作为 NGINX 缓存中缓存键一部分的 POST 请求正文未按预期工作

问题描述 投票:0回答:1

我正在尝试使用 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 nginx-reverse-proxy nginx-config nginx-location nginx-cache
1个回答
0
投票

我不确定这是否能直接回答你的问题,但值得一试。

首先看一下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

 指令处理程序的源代码。尽管如此,还是值得一试。任何反馈或测试结果将不胜感激!

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.