APISIX proxycache 缓存插件

2023年 9月 21日 61.5k 0

环境说明

本次环境已经开启APISIX 80端口,文章使用80和9080效果相同!

proxy-cache插件介绍

proxy-cache插件提供缓存后端响应数据的能力,它可以和其他插件一起使用。该插件支持基于磁盘和内存的缓存。目前可以根据响应码和请求模式来指定需要缓存的数据,也可以通过no_cachecache_bypass属性配置更复杂的缓存策略。

参数属性

名称 类型 必选项 默认值 有效值 描述
cache_strategy string disk ["disk","memory"] 缓存策略,指定缓存数据存储在磁盘还是内存中。
cache_zone string disk_cache_one 指定使用哪个缓存区域,不同的缓存区域可以配置不同的路径,在 conf/config.yaml 文件中可以预定义使用的缓存区域。如果指定的缓存区域与配置文件中预定义的缓存区域不一致,那么缓存无效。
cache_key array[string] ["$host", "$request_uri"] 缓存 key,可以使用变量。例如:["$host", "$uri", "-cache-id"]
cache_bypass array[string] 当该属性的值不为空或者非 0 时则会跳过缓存检查,即不在缓存中查找数据,可以使用变量,例如:["$arg_bypass"]
cache_method array[string] ["GET", "HEAD"] ["GET", "POST", "HEAD"] 根据请求 method 决定是否需要缓存。
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 时将不会缓存数据,可以使用变量
cache_ttl integer 300 秒 当选项 cache_control 未开启或开启以后服务端没有返回缓存控制头时,提供的默认缓存时间

基于硬盘缓存

添加磁盘缓存需要添加apisix conf配置文件

apisix:
  proxy_cache:
    cache_ttl: 10s  # 如果上游未指定缓存时间,则为默认磁盘缓存时间
    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

添加位置

1695193706940.png

配置生效

#我们可以进入到APISIX容器,查看是否生效
root@abcdocker:~/apisix-docker/example# docker exec -it dcc95564a8f3 bash

apisix@dcc95564a8f3:/usr/local/apisix$ ls /tmp/
disk_cache_one  grpc-engine-debug.log

创建路由并配置插件

使用本次磁盘,缓存200,GET请求

curl http://127.0.0.1:9180/apisix/admin/routes/1 
-H 'X-API-KEY: edaacc2vvvv3bbb5f136f87ad84b625c8f1' -X PUT -d '
{
  "uri": "/image/*",
  "name": "abcdocker http limit test",
  "methods": [
    "GET"
  ],
  "host": "apisix.i4t.com",
  "plugins": {
        "proxy-cache": {
            "cache_key":  ["$uri", "-cache-id"],
            "cache_bypass": ["$arg_bypass"],
            "cache_method": ["GET"],
            "cache_http_status": [200],
            "hide_cache_headers": true,
            "no_cache": ["$arg_test"]
        }
   },
  "upstream": {
    "nodes": [
      {
        "host": "httpbin.org",
        "port": 80,
        "weight": 1
      }
    ],
    "type": "roundrobin",
    "hash_on": "vars",
    "scheme": "http",
    "pass_host": "pass"
  },
  "status": 1
}'

效果测试,我们直接curl我们创建的img接口

MISS - 在缓存中找不到响应,因此从原始服务器获取。然后可以缓存响应。
EXPIRED - 缓存中的条目已过期。响应包含来自源服务器的新内容。
HIT - 响应包含直接来自缓存的有效新鲜内容。

当用户第一次访问

第一次请求该路由,数据未缓存,那么 Apisix-Cache-Status 字段应为 MISS。此时再次请求该路由:

Apisix-Cache-Status: MISS 状态为MISS

root@abcdocker:~# curl -i -X GET "http://127.0.0.1/abcdocker/anything/" -H "Host: apisix.i4t.com"
HTTP/1.1 404 NOT FOUND
Content-Type: text/html; charset=utf-8
Content-Length: 233
Connection: keep-alive
Date: Wed, 20 Sep 2023 07:16:56 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.5.0
Apisix-Cache-Status: MISS       

当用户第二次访问

Apisix-Cache-Status: HIT为HIT 表示已经访问缓存接口
如果返回的响应头中 Apisix-Cache-Status 字段变为 HIT,则表示数据已被缓存,插件生效:

root@abcdocker:~# curl -i -X GET "http://127.0.0.1/image/webp" -H "Host: apisix.i4t.com"
HTTP/1.1 200 OK
Content-Type: image/webp
Content-Length: 10568
Connection: keep-alive
Date: Wed, 20 Sep 2023 07:32:22 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.5.0
Apisix-Cache-Status: HIT

当用户第三次访问

Apisix-Cache-Status: EXPIRED 缓存接口过期

root@abcdocker:~# curl -i -X GET "http://127.0.0.1/image/webp" -H "Host: apisix.i4t.com"
HTTP/1.1 200 OK
Content-Type: image/webp
Content-Length: 10568
Connection: keep-alive
Date: Wed, 20 Sep 2023 07:33:03 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.5.0
Apisix-Cache-Status: EXPIRED

此时我们在看/tmp/disk_cache_one/ 目录下就已经生成缓存目录

apisix@dcc95564a8f3:/usr/local/apisix$ ls /tmp/disk_cache_one/
1  a  c
apisix@dcc95564a8f3:/usr/local/apisix$

说明

  • 对于基于磁盘的缓存,不能动态配置缓存的过期时间,只能通过后端服务响应头 Expires Cache-Control 来设置过期时间,当后端响应头中没有ExpiresCache-Control时,默认缓存时间为 10 秒钟
  • 当上游服务不可用时,APISIX 将返回502504HTTP 状态码,默认缓存时间为 10 秒钟;
  • 变量以$开头,不存在时等价于空字符串。也可以使用变量和字符串的结合,但是需要以数组的形式分开写,最终变量被解析后会和字符串拼接在一起。

基于内存缓存

通过硬盘缓存难免会有性能问题,但是添加内存中,可以更快的返回数据

缓存:

  • 内存 > SSD > 机械磁盘
  • 本机 > 网络
  • 进程内 > 进程间

原则

  • 越靠近用户的请求越好
  • 尽量使用本进程和本机的缓存解决

开启并配置内存缓存

curl http://127.0.0.1:9180/apisix/admin/routes/1 
-H 'X-API-KEY: edaacc2vvvv3bbb5f136f87ad84b625c8f1' -X PUT -d '
{
  "uri": "/image/*",
  "name": "abcdocker http limit test",
  "methods": [
    "GET"
  ],
  "host": "apisix.i4t.com",
  "plugins": {
        "proxy-cache": {
            "cache_strategy": "memory",
            "cache_zone": "memory_cache",
            "cache_ttl": 10
        }
   },
  "upstream": {
    "nodes": [
      {
        "host": "httpbin.org",
        "port": 80,
        "weight": 1
      }
    ],
    "type": "roundrobin",
    "hash_on": "vars",
    "scheme": "http",
    "pass_host": "pass"
  },
  "status": 1
}'

第一次访问

第一次请求该路由,数据未缓存,那么 Apisix-Cache-Status 字段应为 MISS。此时再次请求该路由:

root@abcdocker:~#  curl -I -X GET "http://127.0.0.1:9080/image/png" -H "Host: apisix.i4t.com"
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 8090
Connection: keep-alive
Apisix-Cache-Status: MISS
Date: Wed, 20 Sep 2023 08:25:00 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.5.0

第二次访问

如果返回的响应头中 Apisix-Cache-Status 字段变为 HIT,则表示数据已被缓存,插件生效:

root@abcdocker:~#  curl -I -X GET "http://127.0.0.1:9080/image/png" -H "Host: apisix.i4t.com"
HTTP/1.1 200 OK
Content-Type: image/png
Transfer-Encoding: chunked
Connection: keep-alive
Date: Wed, 20 Sep 2023 08:25:00 GMT
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Server: APISIX/3.5.0
Age: 9
Apisix-Cache-Status: HIT

为了清除缓存数据,你只需要指定请求的 method 为 PURGE:

curl -i http://127.0.0.1:9080/image -X PURGE

HTTP 响应码为 200 即表示删除成功,如果缓存的数据未找到将返回 404:

HTTP/1.1 200 OK

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论