OpenResty中带登录会话的反向代理缓存HIT实现可行性问询
实现缓存HIT同时支持正常登录的OpenResty配置方案
完全可以实现缓存状态为HIT的同时允许正常登录,核心是通过差异化缓存策略区分静态/公共资源和登录相关的个性化资源,同时保证登录所需的Set-Cookie头正常传递。以下是具体解决思路和配置调整:
问题根源分析
你当前的配置存在两个核心问题:
proxy_ignore_headers Set-Cookie和proxy_hide_header "Set-Cookie"会拦截上游返回的登录Cookie,导致客户端无法保存登录状态;- 缓存逻辑未区分公共资源和个性化资源,要么全量绕过缓存(BYPASS),要么全量缓存导致登录用户看到统一的缓存内容。
具体配置调整
1. 修复Cookie传递问题
首先移除全局的Cookie拦截指令,仅在静态资源请求中隐藏Set-Cookie(静态资源不需要个性化状态):
# 移除全局的这两行指令 # proxy_hide_header "Set-Cookie"; # proxy_ignore_headers Cache-Control Expires Set-Cookie;
2. 优化缓存绕过逻辑
通过Lua脚本精准控制哪些请求需要缓存、哪些需要绕过:
- 未登录用户:缓存所有公共页面
- 已登录用户:缓存静态资源,绕过登录接口、用户中心等个性化页面
- 固定跳过登录、登出等敏感接口的缓存
set_by_lua $no_cache ' -- 定义无需缓存的敏感路径 local no_cache_paths = {"/login", "/user", "/api/auth", "/logout"} local req_uri = ngx.var.request_uri for _, path in ipairs(no_cache_paths) do if string.find(req_uri, path) then return "1" end end -- 已登录用户判断 local login_cookie = ngx.var.cookie_COOKIE if login_cookie and login_cookie ~= "" then -- 静态资源允许缓存,非静态个性化页面绕过 local static_exts = {".js", ".css", ".png", ".jpg", ".gif", ".svg"} local uri_ext = string.match(req_uri, "%.([^%.]+)$") if uri_ext then for _, ext in ipairs(static_exts) do if "." .. uri_ext == ext then return "" end end end return "1" end -- 未登录用户缓存所有公共页面 return "" ';
3. 优化缓存Key
对于需要区分用户的页面(如已登录用户的个性化内容),用Cookie的MD5哈希值作为缓存Key的一部分,既保证用户缓存独立性,又避免原始Cookie过长导致Key溢出:
set_by_lua $cookie_hash ' local login_cookie = ngx.var.cookie_COOKIE if login_cookie and login_cookie ~= "" then return ngx.md5(login_cookie) end return "" '; proxy_cache_key "$scheme$request_method$host$request_uri$mobile_request$cookie_hash";
4. 静态资源单独配置
为静态资源设置更长的缓存有效期,进一步提升命中率:
location ~* \.(js|css|png|jpg|gif|svg)$ { proxy_cache my-cache; proxy_cache_valid 200 7d; proxy_cache_key "$scheme$request_method$host$request_uri$mobile_request"; proxy_pass http://your_upstream; proxy_buffering on; proxy_cache_revalidate on; proxy_cache_min_uses 1; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; -- 静态资源无需传递Cookie proxy_hide_header "Set-Cookie"; proxy_ignore_headers Set-Cookie; }
完整配置片段
proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=my-cache:8m max_size=1000m inactive=600m; proxy_temp_path /tmp/nginx; add_header X-Cache-Status $upstream_cache_status; server { listen 80; server_name your_domain; # 静态资源缓存配置 location ~* \.(js|css|png|jpg|gif|svg)$ { proxy_cache my-cache; proxy_cache_valid 200 7d; proxy_cache_key "$scheme$request_method$host$request_uri$mobile_request"; proxy_pass http://your_upstream; proxy_buffering on; proxy_cache_revalidate on; proxy_cache_min_uses 1; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_hide_header "Set-Cookie"; proxy_ignore_headers Set-Cookie; } # 主请求配置 location / { set_by_lua $no_cache ' local no_cache_paths = {"/login", "/user", "/api/auth", "/logout"} local req_uri = ngx.var.request_uri for _, path in ipairs(no_cache_paths) do if string.find(req_uri, path) then return "1" end end local login_cookie = ngx.var.cookie_COOKIE if login_cookie and login_cookie ~= "" then local static_exts = {".js", ".css", ".png", ".jpg", ".gif", ".svg"} local uri_ext = string.match(req_uri, "%.([^%.]+)$") if uri_ext then for _, ext in ipairs(static_exts) do if "." .. uri_ext == ext then return "" end end end return "1" end return "" '; set_by_lua $cookie_hash ' local login_cookie = ngx.var.cookie_COOKIE if login_cookie and login_cookie ~= "" then return ngx.md5(login_cookie) end return "" '; proxy_cache_bypass $no_cache; proxy_no_cache $no_cache; proxy_buffering on; proxy_cache my-cache; proxy_cache_valid 200 302 60m; proxy_cache_valid 404 1m; proxy_cache_revalidate on; proxy_cache_min_uses 3; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_cache_key "$scheme$request_method$host$request_uri$mobile_request$cookie_hash"; proxy_pass http://your_upstream; } }
核心效果
- 未登录用户访问公共页面时,缓存状态为
HIT; - 已登录用户访问静态资源时,缓存状态为
HIT,访问个性化页面时自动绕过缓存; - 登录请求正常传递
Set-Cookie头,客户端可以正常保存登录状态。
内容的提问来源于stack exchange,提问作者clarissa emanuel
相关产品推荐
相关产品推荐

