【问题标题】:Enable caching for NGINX third party proxy为 NGINX 第三方代理启用缓存
【发布时间】:2021-09-02 18:09:03
【问题描述】:

我试图通过缓存响应并避免我们从 API 端点获得的 429 响应来避免过于频繁地访问第三方 API。

为此,我设置了一个运行 Ubuntu 20.04 的 Linode 服务器。

配置文件etc/nginx/conf.d/nginx.conf如下

server {
        server_name myserver-name-proxy.server.com;
        access_log /var/log/access.log main;
        error_log /var/log/error.log info;

        location / {
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_cache my_cache;
                proxy_ignore_headers Cache-Control;
                proxy_cache_methods GET HEAD POST;
                proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
                proxy_cache_background_update on;
                proxy_cache_lock on;
                add_header X-Cache-Status $upstream_cache_status;
                proxy_pass https://www.thirdpartyserver.com;
                proxy_ssl_session_reuse on;
                proxy_ssl_server_name on;
                proxy_set_header X-Forwarded-Proto https;
                proxy_buffering on;
                proxy_cache_key $scheme$proxy_host$request_uri;
}
        default_type application/json;

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/myserver-name-proxy.server.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/myserver-name-proxy.server.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = myserver-name-proxy.server.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        server_name myserver-name-proxy.server.com;

        listen 80;
        listen [::]:80;
    return 404; # managed by Certbot
}

那么配置文件etc/nginx/conf.d/nginx.conf就是

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent $request_time "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for" "$upstream_cache_status" "$http_x_cache_status"';

    proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=24h use_temp_path=off;

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

没有错误,但是当我 tail 访问日志文件或检查标头时,只有 MISS 从 NGINX 返回为 $http_x_cache_status

到目前为止,我已尝试将 proxy_cache_path 更改为新文件夹。重新启动时,该文件夹由 NGINX 服务器创建,但没有写入任何内容,还有许多其他内容,例如关闭后台更新、缓存锁定等。

我可以看到这与所有教程之间的唯一区别是我将它与 SSL 一起使用并点击 https:// 端点并在设置中使用 proxy_ssl_session_reuseproxy_ssl_server_name

【问题讨论】:

    标签: nginx caching reverse-proxy nginx-reverse-proxy


    【解决方案1】:

    这有两个问题。

    首先,来自上游服务器的响应没有返回任何过期标头,因此 NGINX 不会缓存这些项目。我也在设置proxy_ignore_headers Cache-Control;

    为确保 NGINX 为这些请求设置缓存,您需要包含 proxy_cache_valid

    这适用于一个端点,但我的另一个端点仍然失败。

    第二个原因是源/上游服务器使用Set-Cookie 标头响应,这意味着响应没有被缓存。为了解决这个问题,我还需要将Set-Cookie 添加到proxy_ignore_headers

    我的最终规则集是

           location / {
                    proxy_pass https://www.thirdpartyserver.com;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_cache nft_cache;
                    proxy_ignore_headers Cache-Control Set-Cookie;
                    proxy_cache_methods GET HEAD POST;
                    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
                    proxy_cache_background_update on;
                    proxy_cache_lock on;
                    add_header X-Cache-Status $upstream_cache_status;
                    proxy_ssl_session_reuse on;
                    proxy_ssl_server_name on;
                    proxy_ssl_verify off;
                    proxy_set_header X-Forwarded-Proto https;
                    proxy_buffering on;
                    proxy_cache_key $scheme$proxy_host$request_uri;
                    proxy_cache_valid 10080m;
    

    我进行的另一项更新是针对缓存 POST 请求的服务器。因为 URL 永远不会改变,所以您应该更新 proxy_cache_key 以包括 $request_body

    proxy_cache_key $scheme$proxy_host$request_uri$request_body;

    这意味着您可以使用不同的请求主体访问同一个发布端点,并且知道您将捕获正确的响应(这是使用 GraphQL 端点完成的,而不是用于发布表单)。

    --编辑--

    我注意到在某些POST 请求中,缓存再次被跳过。原来这是因为proxy_buffer 的大小不足以容纳请求。我还必须包括

    proxy_buffers 8 32k;
    proxy_buffer_size 64k;
    

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 1970-01-01
      • 2019-06-05
      • 2016-05-05
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多