proxy-cache
proxy-cache 插件提供了根据缓存键缓存响应的功能。该插件支持基于磁盘和基于内存的缓存选项,可缓存 GET、POST 和 HEAD 请求。
可以根据请求 HTTP 方法、响应状态码、请求头值等条件有选择地缓存响应。
示例
以下示例演示了如何在不同场景下配置 proxy-cache。
在磁盘上缓存数据
与内存缓存相比,磁盘缓存策略具有系统重启时数据持久化和存储容量更大的优点。它适用于优先考虑持久性并且可以容忍稍大的缓存访问延迟的应用程序。
以下示例演示了如何在路由上使用 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_API_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 检索数据比从磁盘存储检索数据更快。它也适用于存储不需要长期持久化的临时数据,从而可以高效地缓存经常更改的数据。
从 API7 企业版 3.10.0 起,内存缓存策略也会遵循上游 Vary 响应头。系统会根据 Vary 中列出的请求头计算不同变体,并分别缓存响应;带有 Vary: * 的响应不会被缓存。
以下示例演示了如何在路由上使用 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_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
}
}
}'
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
手动清除缓存
虽然缓存响应通常会根据 TTL 过期,但你可能需要在缓存过期前清除缓存数据。
以下示例演示了如何使用 PURGE 方法清除磁盘上的缓存数据。PURGE 也支持内存缓存;如需测试,请使用上一个示例中的内存缓存配置。
将 PURGE 请求发送到与缓存请求相同的路由 URI。插件为 PURGE 请求派生缓存键的方式与填充缓存的请求相同。请使用相同的主机、URI、查询参数以及 cache_key 引用的任何其他值。如果缓存键按消费者隔离,请以同一消费者身份发送请求。
创建一个将响应缓存到磁盘的路由:
- Admin API
- ADC
- Ingress Controller
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",
"pass_host": "node",
"scheme": "https",
"nodes": {
"httpbingo.org:443": 1
}
}
}'
services:
- name: proxy-cache-service
routes:
- name: proxy-cache-route
uris:
- /anything
plugins:
proxy-cache:
cache_strategy: disk
upstream:
type: roundrobin
pass_host: node
scheme: https
nodes:
- host: httpbingo.org
port: 443
weight: 1
将配置同步到网关:
adc sync -f adc.yaml
- Gateway API
- APISIX CRD
apiVersion: v1
kind: Service
metadata:
namespace: aic
name: httpbingo-external-domain
spec:
type: ExternalName
externalName: httpbingo.org
---
apiVersion: apisix.apache.org/v1alpha1
kind: BackendTrafficPolicy
metadata:
namespace: aic
name: httpbingo-https
spec:
targetRefs:
- name: httpbingo-external-domain
kind: Service
group: ""
passHost: node
scheme: https
---
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: httpbingo-external-domain
port: 443
apiVersion: apisix.apache.org/v2
kind: ApisixUpstream
metadata:
namespace: aic
name: httpbingo-external-domain
spec:
ingressClassName: apisix
scheme: https
passHost: node
externalNodes:
- type: Domain
name: httpbingo.org
port: 443
---
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: httpbingo-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"
再次发送相同的请求,并验证响应中包含 Apisix-Cache-Status: HIT。
向同一 URI 发送 PURGE 请求:
curl -i "http://127.0.0.1:9080/anything" -X PURGE
你应该会看到 HTTP/1.1 200 OK 响应,表明缓存响应已清除。如果没有与缓存键匹配的缓存响应,插件将返回 HTTP/1.1 404 Not Found。
再次向路由发送 GET 请求:
curl -i "http://127.0.0.1:9080/anything"
你应该会看到以下响应头,表明先前的缓存响应已不可用:
Apisix-Cache-Status: MISS
有条件地缓存响应
以下示例演示了如何配置 proxy-cache 插件以有条件地缓存响应。
创建一个使用 proxy-cache 插件的路由并配置 no_cache 属性:
- Admin API
- ADC
- Ingress Controller
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
}
}
}'
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 属性:
- Admin API
- ADC
- Ingress Controller
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
}
}
}'
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_API_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,则不会缓存响应。