缓存过滤器

在此示例中,我们通过使用缓存过滤器演示了如何在 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 中找到。

提供的示例响应为

  • 有效一分钟

    此响应在缓存中保持新鲜一分钟。之后,该响应会在提供服务之前由后端服务验证。如果发现已更新,则提供新的响应(并将其缓存)。否则,将提供并刷新缓存的响应。

  • 私有

    此响应是私有的;它不能由共享缓存(如代理)存储。它将始终由后端服务提供。

  • 无缓存

    每次提供此响应之前都必须对其进行验证。

您可以在沙盒运行时更改响应的标头和正文(或添加新的标头和正文)以进行实验。

示例响应

1. 有效一分钟

$ 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. 私有

$ 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. 无缓存

$ 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 文档.

了解有关网络缓存和 cache-control 的更多信息。