快取篩選器

在此範例中,我們示範如何透過使用快取篩選器在 Envoy 中利用 HTTP 快取。此沙箱的設定基於 前端代理沙箱 的設定。

所有傳入的請求都會透過前端 Envoy 進行路由,該 Envoy 作為位於 envoymesh 網路邊緣的反向代理。

連接埠 8000docker-compose.yaml 公開,以處理對服務的 HTTP 呼叫。兩個後端服務部署在前端 Envoy 後方,每個服務都有一個 sidecar Envoy。

前端 Envoy 設定為執行快取篩選器,該篩選器將可快取的回應儲存在記憶體快取中,並將其提供給後續請求。

在此示範中,由已部署服務提供的回應儲存在 responses.yaml 中。

此檔案會掛載到這兩個服務的容器,因此在服務執行時對已儲存的回應所做的任何變更都應立即生效(無需重建或重新執行)。

為了進行示範,回應的建立日期會在提供服務之前附加到其本文中。每個回應都會計算 Etag 以進行驗證,這僅取決於 yaml 檔案中的回應本文(即,不會考慮附加的日期)。快取的回應可以透過具有 age 標頭來識別。經過驗證的回應可以透過具有比 date 標頭更早的產生日期來識別;因為當驗證回應時,date 標頭會更新,而本文保持不變。經過驗證的回應沒有 age 標頭。從後端服務提供的回應沒有 age 標頭,且其 date 標頭與其產生日期相同。

步驟 1:啟動所有容器

變更為 examples/cache 目錄。

$ pwd
envoy/examples/cache
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps

       Name                      Command            State                   Ports
---------------------------------------------------------------------------------------------------
cache_front-envoy_1   /docker-entrypoint.sh /bin ... Up           10000/tcp, 0.0.0.0:8000->8000/tcp
cache_service1_1      python3 /code/service.py       Up (healthy)
cache_service2_1      python3 /code/service.py       Up (healthy)

步驟 2:測試 Envoy 的 HTTP 快取功能

您現在可以透過 front-envoy 將請求傳送到這兩個服務。請注意,由於這兩個服務具有不同的路由,因此對不同服務的相同請求具有不同的快取項目(即,傳送到服務 2 的請求不會由服務 1 產生的快取回應提供服務)。

若要傳送請求

curl -i localhost:8000/service/<service_no>/<response>

service_no:要將請求傳送到的服務,1 或 2。

response:正在請求的回應。這些回應位於 responses.yaml 中。

提供的範例回應為

  • valid-for-minute

    此回應在快取中保持新鮮一分鐘。之後,回應會由後端服務驗證,然後從快取中提供。如果發現已更新,則會提供(並快取)新的回應。否則,將會提供並重新整理快取的回應。

  • private

    此回應是私有的;它不能由共用快取(例如 Proxy)儲存。它將始終由後端服務提供。

  • no-cache

    此回應每次都必須在提供服務之前進行驗證。

您可以在沙箱執行時變更回應的標頭和本文(或新增新的標頭和本文)以進行實驗。

範例回應

1. valid-for-minute

$ curl -i localhost:8000/service/1/valid-for-minute
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 103
cache-control: max-age=60
custom-header: any value
etag: "172ae25df822c3299cf2248694b4ce23"
date: Fri, 11 Sep 2020 03:20:40 GMT
server: envoy
x-envoy-upstream-service-time: 11

This response will stay fresh for one minute
Response body generated at: Fri, 11 Sep 2020 03:20:40 GMT

自然地,回應 date 標頭與產生時間相同。在 30 秒後傳送相同的請求會提供具有相同產生時間的完全相同的回應,但具有 age 標頭,因為它來自快取

$ curl -i localhost:8000/service/1/valid-for-minute
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 103
cache-control: max-age=60
custom-header: any value
etag: "172ae25df822c3299cf2248694b4ce23"
date: Fri, 11 Sep 2020 03:20:40 GMT
server: envoy
x-envoy-upstream-service-time: 11
age: 30

This response will stay fresh for one minute
Response body generated at: Fri, 11 Sep 2020 03:20:40 GMT

在 1 分 1 秒後

$ curl -i localhost:8000/service/1/valid-for-minute
HTTP/1.1 200 OK
cache-control: max-age=60
custom-header: any value
etag: "172ae25df822c3299cf2248694b4ce23"
date: Fri, 11 Sep 2020 03:21:41 GMT
server: envoy
x-envoy-upstream-service-time: 8
content-length: 103
content-type: text/html; charset=utf-8

This response will stay fresh for one minute
Response body generated at: Fri, 11 Sep 2020 03:20:40 GMT

在與後端服務驗證後,提供了相同的回應。您可以驗證這一點,因為回應產生時間是相同的,但回應 date 標頭已使用驗證回應日期進行更新。此外,沒有 age 標頭。

每次驗證回應時,它都會保持新鮮一分鐘。如果在快取的回應仍然新鮮時回應本文發生變更,則仍然會提供快取的回應。只有在快取的回應不再新鮮時,才會更新快取的回應。

2. private

$ curl -i localhost:8000/service/1/private
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 117
cache-control: private
etag: "6bd80b59b2722606abf2b8d83ed2126d"
date: Fri, 11 Sep 2020 03:22:28 GMT
server: envoy
x-envoy-upstream-service-time: 7

This is a private response, it will not be cached by Envoy
Response body generated at: Fri, 11 Sep 2020 03:22:28 GMT

無論您發出多少次此請求,您都將始終收到新的回應;新的產生日期、新的 date 標頭,且沒有 age 標頭。

3. no-cache

$ curl -i localhost:8000/service/1/no-cache
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 130
cache-control: max-age=0, no-cache
etag: "ce39a53bd6bb8abdb2488a5a375397e4"
date: Fri, 11 Sep 2020 03:23:07 GMT
server: envoy
x-envoy-upstream-service-time: 7

This response can be cached, but it has to be validated on each request
Response body generated at: Fri, 11 Sep 2020 03:23:07 GMT

幾秒鐘後

$ curl -i localhost:8000/service/1/no-cache
HTTP/1.1 200 OK
cache-control: max-age=0, no-cache
etag: "ce39a53bd6bb8abdb2488a5a375397e4"
date: Fri, 11 Sep 2020 03:23:12 GMT
server: envoy
x-envoy-upstream-service-time: 7
content-length: 130
content-type: text/html; charset=utf-8

This response can be cached, but it has to be validated on each request
Response body generated at: Fri, 11 Sep 2020 03:23:07 GMT

您將收到具有相同產生時間的快取回應。但是,由於此回應始終會先進行驗證,因此 date 標頭將始終更新。此外,沒有 age 標頭。

如果您在 yaml 檔案中變更回應本文

$ curl -i localhost:8000/service/1/no-cache
HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 133
cache-control: max-age=0, no-cache
etag: "f4768af0ac9f6f54f88169a1f3ecc9f3"
date: Fri, 11 Sep 2020 03:24:10 GMT
server: envoy
x-envoy-upstream-service-time: 7

This response can be cached, but it has to be validated on each request!!!
Response body generated at: Fri, 11 Sep 2020 03:24:10 GMT

您將收到一個由後端服務提供的新回應。新回應將快取以用於後續請求。

您也可以將新的回應新增至具有不同 cache-control 標頭的 yaml 檔案,並開始實驗!

另請參閱

Envoy 快取篩選器組態

深入瞭解如何設定 Envoy 快取篩選器。

MDN Web Docs.

深入瞭解網頁上的快取和 cache-control