缓存过滤器
在此示例中,我们通过使用缓存过滤器演示了如何在 Envoy 中利用 HTTP 缓存。此沙盒的设置基于 前端代理沙盒 的设置。
所有传入请求都通过前端 Envoy 路由,前端 Envoy 充当位于 envoymesh
网络边缘的反向代理。
端口 8000
由 docker-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
的更多信息。