我正在尝试使用 NGINX 作为 GraphQL 服务器前面的反向代理并利用 NGINX 缓存。在我的配置中,我打算缓存 POST API 请求的响应,将请求正文和 API URL 视为缓存键的一部分。然而,这种方法并没有达到预期效果。即使我修改了 API 请求的有效负载,我仍会继续收到第一次缓存的相同响应。我不确定是什么导致了配置中的问题。
worker_processes 1;
error_log C:/Workspace/error.log;
events {
worker_connections 1024;
}
http {
# Define the cache path and settings
proxy_cache_path "C:/Users/username/Documents/cache" levels=1:2 keys_zone=my_cache:100m max_size=200m inactive=5m;
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/m;
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 8081;
server_name localhost;
location /api {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host localhost;
proxy_pass http://localhost:8080;
# Enable request body buffering and set buffer size
proxy_buffers 8 32M;
proxy_buffer_size 30M;
client_body_buffer_size 10M; # Adjust this size based on your needs
# proxy_buffering on; # Enable buffering for proxy
# proxy_ignore_headers "Set-Cookie";
# proxy_hide_header "Set-Cookie";
proxy_hide_header Cache-Control;
proxy_cache_methods GET POST;
# Define the cache key based on the request scheme, method, and URI
set $cache_key "$scheme$request_method$request_uri|$request_body";
# Set a flag for whether caching should occur based on x-api-cache header
set $cache_condition 0;
if ($http_x_api_cache != "true") {
set $cache_condition 1;
}
# Enable cache only if the condition is true
proxy_cache my_cache;
proxy_cache_key $cache_key;
proxy_cache_bypass $cache_condition;
proxy_no_cache $cache_condition;
proxy_cache_valid 200 5m;
# Add the X-Cache-Status header for cache status
add_header X-Cache-Status $upstream_cache_status;
}
}
}
我不确定这是否能直接回答你的问题,但值得一试。
首先看一下nginx开发指南中的“阶段”【章节】。使用
$cache_key
指令分配 set
变量:
set $cache_key "$scheme$request_method$request_uri|$request_body";
在请求处理的
NGX_HTTP_REWRITE_PHASE
期间执行。在此阶段,尚未收到请求正文,因此未填充 $request_body
变量。因此,无论请求正文内容如何,您的缓存键将始终具有相同的值。
为了确保仅在实际需要时才计算
$cache_key
变量,您可以使用 map
块来代替:
http {
...
map "" $cache_key {
default "$scheme$request_method$request_uri|$request_body";
}
server {
...
location /api {
...
# set $cache_key "$scheme$request_method$request_uri|$request_body";
# ^ remove this line!
...
}
}
}
类似地,评估
$cache_condition
变量最好使用另一个 map
块来完成。曾经有一篇著名的“如果是邪恶的......在位置上下文中使用时”文章(现在只能通过 GitHub 上存档的 nginx wiki 内容可用)。仔细阅读它,特别是“示例”章节,将解释为什么我建议进行以下配置更改:
http {
...
map "" $cache_key {
default "$scheme$request_method$request_uri|$request_body";
}
map $http_x_api_cache $cache_condition {
true 1;
# The following line is optional; the default value will be an empty string
default 0;
}
server {
...
location /api {
...
# set $cache_key "$scheme$request_method$request_uri|$request_body";
# ^ Remove this line!
# set $cache_condition 0;
# if ($http_x_api_cache != "true") {
# set $cache_condition 1;
# }
# ^ Remove these lines too!
...
}
}
}
我不完全确定这种方法是否能按预期工作,无需进一步测试 - 无论是在沙箱环境中还是通过查看 proxy_cache_key
指令处理程序的源代码。尽管如此,还是值得一试。任何反馈或测试结果将不胜感激!