在 nginx 中,可以通过 $arg_ 变量组合来构建包含请求参数的缓存键。具体做法是在 proxy_cache_key 指令中使用字符串拼接,例如将 $uri 与 $arg_id 结合,这样不同参数的请求会生成不同的缓存文件,从而实现基于参数的差异化缓存。

如何配置 proxy_cache_key 以区分参数?
直接回答:通过修改 proxy_cache_key 指令,将 $arg_ 变量嵌入到键值字符串中即可区分参数。例如,使用 $uri$is_args$args 可以缓存所有参数,而 $uri$arg_id 仅根据特定 ID 区分。这样做会让 Nginx 为每个唯一的参数组合创建独立的缓存条目。

server {
listen 80;
server_name example.com;
# 定义缓存路径和级别
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;
location /api/data {
# 核心配置:根据 URI 和 id 参数生成缓存键
# 如果 id 为空,则只使用 $uri,避免空值导致键冲突
set $cache_key $uri;
if ($arg_id) {
set $cache_key "${uri}_id_${arg_id}";
}
proxy_cache my_cache;
proxy_cache_key $cache_key;
proxy_cache_valid 200 10m;
proxy_pass http://backend_server;
}
}预期结果:当访问 /api/data?id=1 时,Nginx 生成键 /api/data_id_1 并缓存响应;访问 /api/data?id=2 时,生成键 /api/data_id_2 并单独缓存。若请求不带 id 参数,则使用默认键 /api/data 进行缓存。
如何处理多个参数或复杂查询字符串?
直接回答:对于多个参数,可以直接使用内置变量 $args 或 $is_args$args 作为缓存键的一部分。这会将整个查询字符串(如 ?a=1&b=2)纳入缓存键计算,确保不同参数组合对应不同缓存。注意,如果参数顺序可能变化但语义相同,需在前端或网关层标准化参数顺序,否则 Nginx 会视为不同键。

location /search {
# 使用完整的查询字符串作为缓存键的一部分
# $is_args 在有无参数时分别为空或 '?'
# $args 包含完整的查询字符串
proxy_cache_key "$uri$is_args$args";
proxy_cache my_cache;
proxy_cache_valid 200 5m;
proxy_pass http://search_backend;
}预期结果:请求 /search?q=linux&page=1 与 /search?q=linux&page=2 会产生不同的缓存键,分别缓存搜索结果。如果请求 /search 无参数,则键为 /search,单独缓存。此配置简单有效,但需注意长查询字符串可能增加缓存键长度,影响内存效率。
当参数值为空或特殊字符时缓存键会怎样?
直接回答:当参数值为空时,直接使用 $arg_param 会导致键中包含空字符串,可能引发意外匹配或无效键。建议通过 if 语句判断参数是否存在再拼接,或使用 $args 整体处理。特殊字符(如空格、中文)在 URL 中会被编码,Nginx 会按编码后的字符串生成键,因此 ?name=hello%20world 和 ?name=hello world(未编码)会被视为不同键,需确保客户端发送标准编码。


















