跳到主要内容

proxy-cache

proxy-cache 插件提供了根据缓存键缓存响应的功能。该插件支持基于磁盘和基于内存的缓存选项,可缓存 GETPOSTHEAD 请求。

可以根据请求 HTTP 方法、响应状态码、请求头值等条件有选择地缓存响应。

示例

以下示例演示了如何在不同场景下配置 proxy-cache

在磁盘上缓存数据

与内存缓存相比,磁盘缓存策略具有系统重启时数据持久化和存储容量更大的优点。它适用于优先考虑持久性并且可以容忍稍大的缓存访问延迟的应用程序。

以下示例演示了如何在路由上使用 proxy-cache 插件将数据缓存在磁盘上。

使用磁盘缓存策略时,缓存 TTL 由响应头 ExpiresCache-Control 的值确定。如果不存在这些响应头,或者 APISIX 由于上游不可用而返回 502 Bad Gateway504 Gateway Timeout,则缓存 TTL 默认为配置文件中配置的值。

创建一个使用 proxy-cache 插件的路由以在磁盘上缓存数据:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"cache_strategy": "disk"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

向路由发送请求:

curl -i "http://127.0.0.1:9080/anything"

你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头,表明插件已成功启用:

Apisix-Cache-Status: MISS

由于第一个响应之前没有可用缓存,因此显示 Apisix-Cache-Status: MISS

在缓存 TTL 窗口内再次发送相同的请求。你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头,表明缓存命中:

Apisix-Cache-Status: HIT

等待缓存超过 TTL 后过期,然后再次发送相同的请求。你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头,表明缓存已过期:

Apisix-Cache-Status: EXPIRED

在内存中缓存数据

内存缓存策略具有访问缓存数据延迟低的优点,因为从 RAM 检索数据比从磁盘存储检索数据更快。它也适用于存储不需要长期持久化的临时数据,从而可以高效地缓存经常更改的数据。

以下示例演示了如何在路由上使用 proxy-cache 插件将数据缓存在内存中。

创建一个使用 proxy-cache 的路由并将其配置为使用基于内存的缓存:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"cache_strategy": "memory",
"cache_zone": "memory_cache",
"cache_ttl": 10
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

cache_strategy: 设置为 memory 以进行内存设置。

cache_zone: 设置为内存缓存区域的名称。

cache_ttl: 将内存缓存的生存时间设置为 10 秒。

向路由发送请求:

curl -i "http://127.0.0.1:9080/anything"

你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头,表明插件已成功启用:

Apisix-Cache-Status: MISS

由于第一个响应之前没有可用缓存,因此显示 Apisix-Cache-Status: MISS

在缓存 TTL 窗口内再次发送相同的请求。你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头,表明缓存命中:

Apisix-Cache-Status: HIT

有条件地缓存响应

以下示例演示了如何配置 proxy-cache 插件以有条件地缓存响应。

创建一个使用 proxy-cache 插件的路由并配置 no_cache 属性:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"no_cache": ["$arg_no_cache", "$http_no_cache"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

no_cache: 如果 URL 参数 no_cache 和响应头 no_cache 的值中至少有一个不为空且不等于 0,则不会缓存响应。

使用指示缓存绕过的 URL 参数 no_cache 值向路由发送几个请求:

curl -i "http://127.0.0.1:9080/anything?no_cache=1"

你应该会收到所有请求的 HTTP/1.1 200 OK 响应,并且每次都能观察到以下响应头:

Apisix-Cache-Status: EXPIRED

使用 URL 参数 no_cache 值为零向路由发送其他几个请求:

curl -i "http://127.0.0.1:9080/anything?no_cache=0"

你应该会收到所有请求的 HTTP/1.1 200 OK 响应,并开始看到缓存命中:

Apisix-Cache-Status: HIT

你还可以按如下方式指定 no_cache 响应头中的值:

curl -i "http://127.0.0.1:9080/anything" -H "no_cache: 1"

不应缓存响应:

Apisix-Cache-Status: EXPIRED

有条件地从缓存检索响应

以下示例演示了如何配置 proxy-cache 插件以有条件地从缓存中检索响应。

创建一个使用 proxy-cache 插件的路由并配置 cache_bypass 属性:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"cache_bypass": ["$arg_bypass", "$http_bypass"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

cache_bypass: 如果 URL 参数 bypass 和响应头 bypass 的值中至少有一个不为空且不等于 0,则不会从缓存中检索响应。

使用指示缓存绕过的 URL 参数 bypass 值向路由发送请求:

curl -i "http://127.0.0.1:9080/anything?bypass=1"

你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头:

Apisix-Cache-Status: BYPASS

使用 URL 参数 bypass 值为零向路由发送另一个请求:

curl -i "http://127.0.0.1:9080/anything?bypass=0"

你应该会看到 HTTP/1.1 200 OK 响应,并带有以下响应头:

Apisix-Cache-Status: MISS

你还可以按如下方式指定 bypass 响应头中的值:

curl -i "http://127.0.0.1:9080/anything" -H "bypass: 1"

应绕过缓存:

Apisix-Cache-Status: BYPASS

缓存 502 和 504 错误响应代码

当上游服务返回 500 范围内的服务器错误时,proxy-cache 插件仅在返回状态为 502 Bad Gateway504 Gateway Timeout 时才会缓存响应。

以下示例演示了当上游服务返回 504 Gateway Timeoutproxy-cache 插件的行为。

创建一个使用 proxy-cache 插件的路由并配置一个虚拟上游服务:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "proxy-cache-route",
"uri": "/timeout",
"plugins": {
"proxy-cache": { }
},
"upstream": {
"type": "roundrobin",
"nodes": {
"12.34.56.78": 1
}
}
}'

向路由生成几个请求:

seq 4 | xargs -I{} curl -I "http://127.0.0.1:9080/timeout"

你应该会看到类似于以下的响应:

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: MISS

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

HTTP/1.1 504 Gateway Time-out
...
Apisix-Cache-Status: HIT

但是,如果上游服务返回 503 Service Temporarily Unavailable,则不会缓存响应。