2017-11-21 46 views
10

Tôi đã suy nghĩ về yêu cầu trên Software Recommendations, nhưng sau đó tôi đã phát hiện ra rằng nó có thể là một yêu cầu quá lạ và nó cần một số làm rõ đầu tiên.Caching proxy ngược cho nội dung động

điểm của tôi là:

  • Mỗi phản ứng có chứa một etag
    • mà là một hash của nội dung
    • và đó là duy nhất trên toàn cầu (với đầy đủ khả năng)
  • Nội dung (chủ yếu) động và có thể thay đổi bất cứ lúc nào (expiresmax-age tiêu đề là u không có ở đây).
  • Nội dung là một phần tùy thuộc vào người dùng, như được cho phép bởi quyền (đôi khi bản thân nó thay đổi).

Về cơ bản, proxy phải chứa bộ nhớ cache ánh xạ etag đến nội dung phản hồi. etag được lấy từ máy chủ và trong trường hợp phổ biến nhất, máy chủ không xử lý nội dung phản hồi chút nào.

Nó nên đi như sau: Proxy luôn gửi một yêu cầu đến máy chủ và sau đó một trong hai

  • trở về máy chủ chỉ etag và proxy làm một tra cứu dựa vào nó và
    • 1,1 trên bộ nhớ cache hit,
      • nó đọc dữ liệu phản hồi từ bộ nhớ cache
      • và gửi một phản ứng cho khách hàng
    • 1.2 trên cache,
      • nó yêu cầu máy chủ một lần nữa và sau đó
      • máy chủ trả về phản ứng với nội dung và etag,
      • các cửa hàng ủy quyền đó trong bộ nhớ cache của nó
      • và gửi một phản ứng với khách hàng
  • hoặc máy chủ trả về phản ứng với nội dung và etag,
    • proxy lưu trữ các dữ liệu trong bộ nhớ cache của nó
    • và gửi một phản ứng cho khách hàng

Để đơn giản, tôi rời ra việc xử lý if-none-match tiêu đề, mà là khá hiển nhiên. Lý do của tôi là trường hợp phổ biến nhất 1.1 có thể được thực hiện rất hiệu quả trong máy chủ (sử dụng yêu cầu ánh xạ bộ nhớ cache của nó đến etags; nội dung không được lưu trong máy chủ), để hầu hết các yêu cầu có thể được xử lý mà không có máy chủ xử lý nội dung phản hồi. Điều này sẽ tốt hơn lần đầu tiên lấy nội dung từ bộ nhớ cache bên và sau đó phục vụ nó.

Trong trường hợp 1.2, có hai yêu cầu đối với máy chủ, điều đó nghe có vẻ xấu, nhưng không tệ hơn máy chủ yêu cầu bộ nhớ cache bên và bị bỏ lỡ.

Q1: Tôi tự hỏi, cách ánh xạ yêu cầu đầu tiên tới HTTP. Trong trường hợp 1, nó giống như yêu cầu HEAD. Trong trường hợp 2, nó giống như GET. Quyết định giữa hai tùy thuộc vào máy chủ: Nếu nó có thể phục vụ etag mà không cần tính toán các nội dung, thì đó là trường hợp 1, nếu không, đó là trường hợp 2.

Q2: Có một reverse proxy làm một cái gì đó như thế này ? Tôi đã đọc về nginx, HAProxy và Varnish và nó không có vẻ như vậy. Điều này dẫn tôi đến Q3: Đây có phải là một ý tưởng tồi không? Tại sao?

Q4: Nếu không, thì proxy hiện tại nào dễ thích ứng nhất?

Một thí dụ

Một yêu cầu GET như /catalog/123/item/456 từ người dùng U1 được phục vụ với một số nội dung C1etag: 777777. Proxy được lưu trữ C1 dưới khóa 777777.

Bây giờ, cùng một yêu cầu đến từ người dùng U2. Proxy chuyển tiếp nó, máy chủ trả về chỉ etag: 777777 và proxy là may mắn, tìm thấy C1 trong bộ nhớ cache của nó (trường hợp 1.1) và gửi nó đến U2. Trong ví dụ này, cả khách hàng không phải proxy đều biết kết quả mong đợi.

Phần thú vị là làm cách nào máy chủ có thể biết được etag mà không cần tính toán câu trả lời.Ví dụ, nó có thể có một quy tắc cho biết rằng các yêu cầu của biểu mẫu này trả về cùng một kết quả cho tất cả người dùng, giả sử rằng người dùng đã cho được phép nhìn thấy nó. Vì vậy, khi yêu cầu từ U1 đến, nó đã tính C1 và lưu trữ etag dưới khóa /catalog/123/item/456. Khi cùng một yêu cầu đến từ U2, nó chỉ xác minh rằng U2 được phép xem kết quả.

+0

Những gì bạn mô tả là GET có điều kiện trong HTTP. Khách hàng thực hiện GET với một số tiêu đề HTTP cụ thể chỉ cho máy chủ trả lời nội dung chỉ khi một điều kiện cụ thể phù hợp hoặc không khớp, giống như một điều kiện dựa trên ngày hợp lệ hoặc ETag. –

+0

@PatrickMevzek Sau đó, mô tả của tôi là khó hiểu. Tôi nhận thức được điều kiện GET và đó là một cái gì đó khác nhau. Nó giả định rằng, người khởi xướng "đoán" câu trả lời có thể xảy ra của phản hồi (thậm chí có thể gửi [nhiều hơn một] (https://stackoverflow.com/q/40186498/581205) trong 'if-none-match 'header). '+++' Ở đây, proxy truy vấn máy chủ mà không đoán và máy chủ thường (trường hợp 1) chỉ trả lời với 'etag', hy vọng rằng proxy nhận được một lần truy cập cache (trường hợp 1.1). Ngoài ra còn có khả năng truy vấn thứ hai (trường hợp 1.2). – maaartinus

+0

Không có giả định rằng khách hàng đoán bất cứ điều gì vì các giá trị ETAG mờ đục theo thiết kế. Khách hàng gửi một giá trị ETag nó có trong bộ nhớ cache của nó, liên quan đến URL mà nó truy vấn. –

Trả lời

2

Q1: Đây là yêu cầu GET. Các máy chủ có thể trả lời với một "304 không sửa đổi" mà không có cơ thể.

Q2: openresty (nginx với một số mô-đun bổ sung) có thể thực hiện, nhưng bạn sẽ cần thực hiện một số logic cho chính mình (xem mô tả chi tiết bên dưới).

Q3: Điều này nghe giống như ý tưởng hợp lý đã đưa ra thông tin trong câu hỏi của bạn. Chỉ cần một ít thức ăn cho các tư tưởng:

  • Bạn cũng có thể chia trang ở các bộ phận sử dụng cụ thể và chung chung mà có thể được lưu trữ một cách độc lập.

  • Bạn không nên mong đợi bộ nhớ cache giữ cho các câu trả lời được tính toán vĩnh viễn. Vì vậy, nếu máy chủ trả lại 304 not modified với etag: 777777 (theo ví dụ của bạn), nhưng bộ nhớ cache không biết về nó, bạn nên có tùy chọn để buộc xây dựng lại câu trả lời, ví dụ: với một yêu cầu khác với tiêu đề tùy chỉnh X-Force-Recalculate: true.

  • Không chính xác là một phần trong câu hỏi của bạn, nhưng: Đảm bảo đặt tiêu đề Vary thích hợp để ngăn sự cố lưu vào bộ nhớ cache.

  • Nếu đây chỉ là về quyền, bạn có thể cũng có thể làm việc với các quyền trong cookie đã ký. Bộ nhớ cache có thể lấy được sự cho phép từ cookie mà không hỏi máy chủ và cookie là bằng chứng giả mạo do chữ ký.

Q4: Tôi sẽ sử dụng openresty cho điều này, đặc biệt là lua-resty-redis module. Đặt nội dung được lưu vào bộ nhớ cache thành khóa-giá trị redis với khóa etag làm khóa. Bạn sẽ cần phải mã hóa logic tra cứu trong Lua, nhưng nó không nên nhiều hơn một vài dòng.

+0

Cảm ơn rất nhiều!Một số chi tiết: Tôi không nghĩ rằng máy chủ được phép trả lời mà không có phần thân vì yêu cầu không có điều kiện vì proxy sẽ không gửi tiêu đề 'if-none-match'. Nói chung, nó không thể như bất kỳ 'etag' nó lưu trữ đủ điều kiện để đưa vào tiêu đề. +++ Liên quan đến 'X-Force-Recalculate: true', đó là trường hợp của tôi 1.2 (Tôi không rõ về nó). +++ Quyền trong cookie đã ký sẽ là ý tưởng tuyệt vời nếu chúng không thể bị thu hồi và nếu không có quá nhiều quyền. Có nội dung mà nó chỉ về quyền và các nơi khác phức tạp hơn. +++ Tôi sẽ nhìn vào tình trạng bất ổn. – maaartinus

+1

Về 304, your're right, 'if-none-match' sẽ là bắt buộc theo [RFC7232 4.1] (https://tools.ietf.org/html/rfc7232#section-4.1), nhưng tôi đoán nó là tùy chọn tốt nhất để mô hình hóa các yêu cầu của bạn theo tinh thần ngữ nghĩa HTTP. – Bernhard

Các vấn đề liên quan