为 NGINX 第三方代理启用缓存
Enable caching for NGINX third party proxy
我试图通过缓存响应并避免我们从 API 端点获得的 429
响应来避免频繁访问第三方 API。
为此,我设置了一个 Linode 服务器 运行 Ubuntu 20.04.
配置文件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
访问日志文件或检查 headers 时,只有 MISS
从 NGINX 作为 $http_x_cache_status
到目前为止,我已尝试将 proxy_cache_path
更改为新文件夹。重新启动时,此文件夹由 NGINX 服务器创建,但从未写入任何内容以及许多其他内容,如切换后台更新、缓存锁定等。
我能看到的这个和所有教程之间的唯一区别是我将它与 SSL 一起使用并点击 https:// endpoing 并使用 proxy_ssl_session_reuse
和 proxy_ssl_server_name
在设置中。
这有两个问题。
首先,来自上游服务器的响应未返回任何过期 header,因此 NGINX 不会缓存这些项目。我也在设置 proxy_ignore_headers Cache-Control;
.
为确保 NGINX 对这些请求设置缓存,您需要包含 proxy_cache_valid
.
这对一个端点有效,但我的另一个端点仍然失败。
第二个原因是因为 origin/upstream 服务器正在响应 Set-Cookie
header,这意味着响应没有被缓存。要解决此问题,我还需要将 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;
这意味着您可以使用不同的请求主体访问相同的 post 端点,并且知道您将捕获正确的响应(这是使用 GraphQL 端点完成的,而不是 posting 表格)。
--编辑--
我注意到在某些 POST
请求中缓存再次被跳过。事实证明,这是因为 proxy_buffer
大小不足以包含请求。我还必须包括
proxy_buffers 8 32k;
proxy_buffer_size 64k;
我试图通过缓存响应并避免我们从 API 端点获得的 429
响应来避免频繁访问第三方 API。
为此,我设置了一个 Linode 服务器 运行 Ubuntu 20.04.
配置文件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
访问日志文件或检查 headers 时,只有 MISS
从 NGINX 作为 $http_x_cache_status
到目前为止,我已尝试将 proxy_cache_path
更改为新文件夹。重新启动时,此文件夹由 NGINX 服务器创建,但从未写入任何内容以及许多其他内容,如切换后台更新、缓存锁定等。
我能看到的这个和所有教程之间的唯一区别是我将它与 SSL 一起使用并点击 https:// endpoing 并使用 proxy_ssl_session_reuse
和 proxy_ssl_server_name
在设置中。
这有两个问题。
首先,来自上游服务器的响应未返回任何过期 header,因此 NGINX 不会缓存这些项目。我也在设置 proxy_ignore_headers Cache-Control;
.
为确保 NGINX 对这些请求设置缓存,您需要包含 proxy_cache_valid
.
这对一个端点有效,但我的另一个端点仍然失败。
第二个原因是因为 origin/upstream 服务器正在响应 Set-Cookie
header,这意味着响应没有被缓存。要解决此问题,我还需要将 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;
这意味着您可以使用不同的请求主体访问相同的 post 端点,并且知道您将捕获正确的响应(这是使用 GraphQL 端点完成的,而不是 posting 表格)。
--编辑--
我注意到在某些 POST
请求中缓存再次被跳过。事实证明,这是因为 proxy_buffer
大小不足以包含请求。我还必须包括
proxy_buffers 8 32k;
proxy_buffer_size 64k;