常用网关都是如何配置缓存请求的

Posted by 梁远鹏 on 2023-02-20 | 阅读 |,阅读约 4 分钟

TOC

前言

Envoy

由于 envoy cache 遵循 http cache 规范,因此规定缓存的 API 需要返回cache-control的 header,并且 value 需要标识缓存的时间,例如缓存 10min max-age=600.

envoy.yaml

static_resources:
  listeners:
  - address:
      socket_address:
        address: 0.0.0.0
        port_value: 10001
    filter_chains:
    - filters:
        - name: envoy.filters.network.http_connection_manager
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
            scheme_header_transformation:
              scheme_to_overwrite: https
            stat_prefix: ingress_http
            route_config:
              name: local_route
              virtual_hosts:
                - name: local_service
                  domains: ["*"]
                  routes:
                    - match:
                        prefix: "/"
                      response_headers_to_add:
                        - header:
                            key: cache-control
                            value: "max-age=600"
                          append: true
                      direct_response:
                        status: 200
                        body:
                          inline_string: "{\"hello\":\"world\"}"
            http_filters:
              - name: envoy.filters.http.router
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  - address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
      - filters:
          - name: envoy.filters.network.http_connection_manager
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
              use_remote_address: true
              access_log:
                - name: envoy.file_access_log
                  typed_config:
                    "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
                    path: /dev/stdout
              codec_type: auto
              stat_prefix: ingress_http
              http_filters:
                - name: "envoy.filters.http.cache"
                  typed_config:
                    "@type": "type.googleapis.com/envoy.extensions.filters.http.cache.v3.CacheConfig"
                    typed_config:
                      "@type": "type.googleapis.com/envoy.extensions.http.cache.file_system_http_cache.v3.FileSystemHttpCacheConfig"
                      cache_path: /tmp/envoycache
                      manager_config:
                        thread_pool:
                          thread_count: 1
                - name: envoy.filters.http.router
                  typed_config:
                    "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
              route_config:
                name: local_route
                virtual_hosts:
                  - name: service
                    domains:
                      - "*"
                    routes:
                      - match:
                          prefix: "/"
                        route:
                          cluster: localproxy
  clusters:
    - name: localproxy
      connect_timeout: 60s
      type: LOGICAL_DNS
      lb_policy: round_robin
      load_assignment:
        cluster_name: localproxy
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: 127.0.0.1
                      port_value: 10001
admin:
  access_log_path: "/dev/null"
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 8082

首先两次请求, 在第二次的请求中 response header 里面可以看到 age,那么就是 cache 了,

lan@lan:~/repo/git/liangyuanpeng.github.io$ curl -X GET localhost:10000/hello2 -I
HTTP/1.1 200 OK
cache-control: max-age=600
content-length: 17
content-type: text/plain
date: Thu, 06 Apr 2023 03:30:50 GMT
server: envoy
x-envoy-upstream-service-time: 0

lan@lan:~/repo/git/liangyuanpeng.github.io$ curl -X GET localhost:10000/hello2 -I
HTTP/1.1 200 OK
cache-control: max-age=600
content-length: 17
content-type: text/plain
date: Thu, 06 Apr 2023 03:30:50 GMT
server: envoy
x-envoy-upstream-service-time: 0
age: 2

查看缓存目录,已经有内容了.

lan@lan:~/repo/git/liangyuanpeng.github.io$ ls /tmp/envoycache/
cache-2548926444025561090

查看一下缓存的内容,可以看到里面有 header 以及 body 的内容,也就是请求需要返回的东西.

lan@lan:~/repo/git/liangyuanpeng.github.io$ cat /tmp/envoycache/cache-2548926444025561090 
CACH0000�
4
cluster_name_goes_herelocalhost:10000�/hello2@
                                             ������j�
:status200�
cache-control
             max-age=600�
content-length17��

content-type
text/plain�%
dateThu, 06 Apr 2023 03:30:50 GMT�
serverenvoy�"
x-envoy-upstream-service-time0{"hello":"world"}

再试试换一个 IP 地址来访问,但是实际上是同一个资源,这时候会怎么样.

看看缓存目录,多了一个缓存.

lan@lan:~/repo/git/liangyuanpeng.github.io$ curl -X GET 192.168.3.87:10000/hello2 -I
HTTP/1.1 200 OK
cache-control: max-age=600
content-length: 17
content-type: text/plain
date: Thu, 06 Apr 2023 03:31:32 GMT
server: envoy
x-envoy-upstream-service-time: 0

lan@lan:~/repo/git/liangyuanpeng.github.io$ ls /tmp/envoycache/
cache-13382174171709149627  cache-2548926444025561090

查看一下第二个缓存的内容,可以看到 有个 header 是带有完整的请求地址的,因此可以得知缓存是根据 域名+path 来作为缓存的唯一 key 的.

Envoy 这个 API 特性目前还在开发中,因此请谨慎使用,可以将下述文档地址中 v1.25.3 修改为你当前 Envoy 的版本,查看这个 API 是否还处于开发当中.

https://www.envoyproxy.io/docs/envoy/v1.25.3/api-v3/extensions/http/cache/file_system_http_cache/v3/file_system_http_cache.proto#envoy-v3-api-msg-extensions-http-cache-file-system-http-cache-v3-filesystemhttpcacheconfig

下面是这个 API 的变更情况,可以看到1.25.3中只有两个字段并且不支持缓存清理的逻辑,而在1.26.0-dev的开发版本中已经支持了max_cache_size_bytesmax_cache_entry_count两个清理缓存相关的配置了.

1.25.3

{
  "manager_config": {...},
  "cache_path": ...
}

1.26.0-dev

{
  "manager_config": {...},
  "cache_path": ...,
  "max_cache_size_bytes": {...},
  "max_cache_entry_count": {...}
}

对于缓存清理的配置留给你试试效果,也许当你看到本文时 Envoy 的缓存功能已经基本完善,到那时也欢迎与我交流相关内容:)

Pipy

docker pull flomesh/pipy:0.90.0-54

pipy的体验

上手门槛比较高,官方文档相对也是比较少的,有一种束手无策的感觉.

例如,官方例子中是的 js 脚本是这样的:

pipy()

  .listen(8000)
  .demuxHTTP().to(
    $=>$.muxHTTP().to(
      $=>$.connect('localhost:8080')
    )
  )

这是将请求转发到 localhost:8080,而我将地址做了一个修改,将请求修改为转发到https://registry.lank8s.cn

pipy()
  .listen(8000)
  .demuxHTTP().to(
    $=>$.muxHTTP().to(
      $=>$.connect('https://registry.lank8s.cn')
    )
  )

PS: registry.worker.liangyuanpeng.com:443https://registry.lank8s.cn都试过,一样的结果.

然后请求http://192.168.56.11:8000/v2/kube-apiserver/manifests/v1.26.0尝试反向代理的效果,很遗憾,失败了并且没有任何解决问题的思路.

错误信息:

2023-02-20 14:07:29.965 [ERR] [connect] invalid target: https://registry.worker.liangyuanpeng.com/v2/
2023-02-20 14:07:29.965 [ERR] [connect] invalid target: https://registry.worker.liangyuanpeng.com/v2/
2023-02-20 14:07:29.965 [ERR] [connect] invalid target: https://registry.worker.liangyuanpeng.com/v2/
2023-02-20 14:08:29.968 [ERR] [connect] invalid target: https://registry.worker.liangyuanpeng.com/v2/
2023-02-20 14:08:29.968 [ERR] [connect] invalid target: https://registry.worker.liangyuanpeng.com/v2/

我请求的路径是/v2/kube-apiserver/manifests/v1.26.0,而错误提示的路径却是/v2/,很奇怪.

这只是我的一个请求转发 hello world,但我拿它没有任何办法 :(

浅尝后我对 flomesh pipy 的看法是:劝退程度很大…

劝退的不是 js 脚本本身的复杂度,而是文档,入门指引性 example 太少.

而 Pipy 称自身为可编程网关,我更愿意把它叫做"完全编程网关",而把 Envoy 叫做可编程网关.

因为如果你不会写 pipy js 的话,你是没办法使用它的,对于 Envoy 来说,你只有在扩展特定功能点时才需要以编程的方式制作 filter,否则可以直接使用 Envoy 配置文件即可.

Nginx

apisix

最后

本文没有尝试缓存功能在 Kong 的应用,也许后面某天会有兴趣为本文添加 Kong 在这方面的内容,在此之前欢迎任何同学投稿这方面的内容!

微信公众号

扫描下面的二维码关注我们的微信公众号,第一时间查看最新内容。同时也可以关注我的Github,看看我都在了解什么技术,在页面底部可以找到我的Github。

wechat-qrcode

温馨提示

本文还在持续创作中,如果你对本文主题感兴趣可以加我微信好友进行催更,博客下方可以找到我的微信联系方式 :)