You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenResty中带登录会话的反向代理缓存HIT实现可行性问询

实现缓存HIT同时支持正常登录的OpenResty配置方案

完全可以实现缓存状态为HIT的同时允许正常登录,核心是通过差异化缓存策略区分静态/公共资源和登录相关的个性化资源,同时保证登录所需的Set-Cookie头正常传递。以下是具体解决思路和配置调整:

问题根源分析

你当前的配置存在两个核心问题:

  1. proxy_ignore_headers Set-Cookie和proxy_hide_header "Set-Cookie"会拦截上游返回的登录Cookie,导致客户端无法保存登录状态;
  2. 缓存逻辑未区分公共资源和个性化资源,要么全量绕过缓存(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 01:40:30