proxy-cache
描述#
proxy-cache 插件提供了根据缓存键缓存响应的功能。该插件支持基于磁盘和基于内存的缓存选项,用于缓存 GET、POST 和 HEAD 请求。
可以根据请求 HTTP 方法、响应状态代码、请求标头值等有条件地缓存响应。
属性#
| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
|---|---|---|---|---|---|
| cache_strategy | string | 否 | disk | ["disk","memory"] | 缓存策略。缓存在磁盘还是内存中。 |
| cache_zone | string | 否 | disk_cache_one | 与缓存策略一起使用的缓存区域。该值应与配置文件中定义的缓存区域之一匹配,并与缓存策略相对应。例如,当使用内存缓存策略时,应该使用内存缓存区域。 | |
| cache_key | array[string] | 否 | ["$host", "$request_uri"] | 用于缓存的键。支持NGINX 变量和值中的常量字符串。变量应该以 $ 符号为前缀。 | |
| cache_bypass | array[string] | 否 | 一个或多个用于解析值的参数,如果任何值不为空且不等于 0,则不会从缓存中检索响应。支持值中的 NGINX 变量 和常量字符串。变量应该以 $ 符号为前缀。 | ||
| cache_method | array[string] | 否 | ["GET", "HEAD"] | ["GET", "POST", "HEAD"] | 应缓存响应的请求方法。 |
| cache_http_status | array[integer] | 否 | [200, 301, 404] | [200, 599] | 应缓存响应的响应 HTTP 状态代码。 |
| hide_cache_headers | boolean | 否 | false | 如果为 true,则隐藏 Expires 和 Cache-Control 响应标头。 | |
| cache_control | boolean | 否 | false | 如果为 true,则遵守 HTTP 规范中的 Cache-Control 行为。仅对内存中策略有效。 | |
| no_cache | array[string] | 否 | 用于解析值的一个或多个参数,如果任何值不为空且不等于 0,则不会缓存响应。支持 NGINX 变量 和值中的常量字符串。变量应以 $ 符号为前缀。 | ||
| cache_ttl | integer | 否 | 300 | >=1 | 在内存中缓存时的缓存生存时间 (TTL),以秒为单位。要调整在磁盘上缓存时的 TTL,请更新配置文件 中的 cache_ttl。TTL 值与从上游服务收到的响应标头 Cache-Control 和 Expires 中的值一起评估。 |
| consumer_isolation | boolean | 否 | true | 如果为 true,按已认证身份对缓存进行分区。当请求解析为 APISIX 消费者(ctx.consumer_name)或携带 remote user(ctx.var.remote_user)时,身份会被作为前缀加入有效的缓存键,使每个消费者拥有独立的缓存命名空间。当 cache_key 已包含身份相关变量($consumer_name、$consumer_group_id、$remote_user 或 $http_authorization)时此选项不生效。如果希望不同消费者共享缓存(例如上游响应与请求方无关的路由),可设置为 false。 | |
| cache_set_cookie | boolean | 否 | false | 如果为 true,缓存包含 Set-Cookie 响应头的响应。默认关闭,因为 Set-Cookie 是面向特定接收方的,不适合放入共享缓存。仅对内存缓存策略有效——磁盘缓存策略由 NGINX 原生 proxy_cache 处理,对带 Set-Cookie 的响应始终不缓存,且不受此选项影响。仅当上游的 Set-Cookie 与具体用户无关(例如 A/B 测试变体 cookie)时才启用。 |
无论 cache_control 标志如何,本插件始终遵循上游响应中的 Cache-Control: private、no-store 与 no-cache 指令——携带其中任一指令的响应不会被缓存。cache_control 标志只控制请求侧语义(客户端的 max-age、min-fresh 等请求指令)以及基于 max-age / s-maxage 的 TTL 推导,不控制是否遵守上游的不可缓存指令。
两种缓存策略都会遵循上游响应中的 Vary 响应头(RFC 9111 §4.1)。缓存条目会按请求中 Vary 列出的各个头部的值进行分区,因此一个带有 Vary: Accept-Encoding 的响应不会被返回给具有不同 Accept-Encoding 的请求。Vary: * 的响应被视为不可复用,不会被缓存。
静态配置#
默认情况下,磁盘缓存时的 cache_ttl 和缓存 zones 等值已在 默认配置 中预先配置。
要自定义这些值,请将相应的配置添加到 config.yaml。例如:
apisix:
proxy_cache:
cache_ttl: 10s # 仅当 `Expires` 和 `Cache-Control` 响应标头均不存在,或者 APISIX 返回
# 由于上游不可用导致 `502 Bad Gateway` 或 `504 Gateway Timeout` 时
# 才会在磁盘上缓存时使用默认缓存 TTL
zones:
- name: disk_cache_one
memory_size: 50m
disk_size: 1G
disk_path: /tmp/disk_cache_one
cache_levels: 1:2
# - name: disk_cache_two
# memory_size: 50m
# disk_size: 1G
# disk_path: "/tmp/disk_cache_two"
# cache_levels: "1:2"
- name: memory_cache
memory_size: 50m
重新加载 APISIX 以使更改生效。
示例#
以下示例演示了如何为不同场景配置 proxy-cache。
note
您可以这样从 config.yaml 中获取 admin_key 并存入环境变量:
admin_key=$(yq '.deployment.admin.admin_key[0].key' conf/config.yaml | sed 's/"//g')
在磁盘上缓存数据#
磁盘缓存策略具有系统重启时数据持久性以及与内存缓存相比具有更大存储容量的优势。它适用于优先考虑耐用性且可以容忍稍大的缓存访问延迟的应用程序。
以下示例演示了如何在路由上使用 proxy-cache 插件将数据缓存在磁盘上。
使用磁盘缓存策略时,缓存 TTL 由响应标头 Expires 或 Cache-Control 中的值确定。如果这些标头均不存在,或者 APISIX 由于上游不可用而返回 502 Bad Gateway 或 504 Gateway Timeout,则缓存 TTL 默认为 配置文件 中配置的值。
使用 proxy-cache 插件创建路由以将数据缓存在磁盘上:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"cache_strategy": "disk"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /anything
plugins:
proxy-cache:
cache_strategy: disk
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: proxy-cache-plugin-config
spec:
plugins:
- name: proxy-cache
config:
cache_strategy: disk
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: proxy-cache-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
ingressClassName: apisix
http:
- name: proxy-cache-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: proxy-cache
enable: true
config:
cache_strategy: disk
将配置应用到集群:
kubectl apply -f proxy-cache-ic.yaml
向路由发送请求:
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 创建路由并将其配置为使用基于内存的缓存:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_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
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /anything
plugins:
proxy-cache:
cache_strategy: memory
cache_zone: memory_cache
cache_ttl: 10
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: proxy-cache-plugin-config
spec:
plugins:
- name: proxy-cache
config:
cache_strategy: memory
cache_zone: memory_cache
cache_ttl: 10
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: proxy-cache-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
ingressClassName: apisix
http:
- name: proxy-cache-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: proxy-cache
enable: true
config:
cache_strategy: memory
cache_zone: memory_cache
cache_ttl: 10
将配置应用到集群:
kubectl apply -f proxy-cache-ic.yaml
❶ 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 属性,这样如果 URL 参数 no_cache 和标头 no_cache 的值中至少有一个不为空且不等于 0,则不会缓存响应:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_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
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /anything
plugins:
proxy-cache:
no_cache:
- $arg_no_cache
- $http_no_cache
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: proxy-cache-plugin-config
spec:
plugins:
- name: proxy-cache
config:
no_cache:
- $arg_no_cache
- $http_no_cache
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: proxy-cache-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
ingressClassName: apisix
http:
- name: proxy-cache-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: proxy-cache
enable: true
config:
no_cache:
- $arg_no_cache
- $http_no_cache
将配置应用到集群:
kubectl apply -f proxy-cache-ic.yaml
❶ 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 属性,这样如果 URL 参数 bypass 和标头 bypass 的值中至少有一个不为空且不等于 0,则不会从缓存中检索响应:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "proxy-cache-route",
"uri": "/anything",
"plugins": {
"proxy-cache": {
"cache_bypass": ["$arg_bypass", "$http_bypass"]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /anything
plugins:
proxy-cache:
cache_bypass:
- $arg_bypass
- $http_bypass
upstream:
type: roundrobin
nodes:
- host: httpbin.org
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbin-external-domain
spec:
type: ExternalName
externalName: httpbin.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: proxy-cache-plugin-config
spec:
plugins:
- name: proxy-cache
config:
cache_bypass:
- $arg_bypass
- $http_bypass
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: proxy-cache-plugin-config
backendRefs:
- name: httpbin-external-domain
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbin-external-domain
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: httpbin.org
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
ingressClassName: apisix
http:
- name: proxy-cache-route
match:
paths:
- /anything
upstreams:
- name: httpbin-external-domain
plugins:
- name: proxy-cache
enable: true
config:
cache_bypass:
- $arg_bypass
- $http_bypass
将配置应用到集群:
kubectl apply -f proxy-cache-ic.yaml
❶ 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 Gateway 或 504 Gateway Timeout。
以下示例演示了当上游服务返回 504 Gateway Timeout 时 proxy-cache 插件的行为。
使用 proxy-cache 插件创建路由并配置虚拟上游服务:
- Admin API
- ADC
- Ingress Controller
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${admin_key}" \
-d '{
"id": "proxy-cache-route",
"uri": "/timeout",
"plugins": {
"proxy-cache": { }
},
"upstream": {
"type": "roundrobin",
"nodes": {
"12.34.56.78": 1
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /timeout
plugins:
proxy-cache: {}
upstream:
type: roundrobin
nodes:
- host: 12.34.56.78
port: 80
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: dummy-upstream
spec:
type: ExternalName
externalName: dummy.example.com
---
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: aic
name: proxy-cache-plugin-config
spec:
plugins:
- name: proxy-cache
config:
_meta:
disable: false
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /timeout
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: proxy-cache-plugin-config
backendRefs:
- name: dummy-upstream
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: dummy-upstream
spec:
ingressClassName: apisix
externalNodes:
- type: Domain
name: dummy.example.com
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: aic
name: proxy-cache-route
spec:
ingressClassName: apisix
http:
- name: proxy-cache-route
match:
paths:
- /timeout
upstreams:
- name: dummy-upstream
plugins:
- name: proxy-cache
enable: true
将配置应用到集群:
kubectl apply -f proxy-cache-ic.yaml
生成一些对路由的请求:
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,则响应将不会被缓存。