关于 lua 中对 nginx 变量处理后 proxy_pass 出现问题的疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
laev
V2EX    NGINX

关于 lua 中对 nginx 变量处理后 proxy_pass 出现问题的疑问

  •  
  •   laev 2021-11-25 14:56:18 +08:00 2005 次点击
    这是一个创建于 1490 天前的主题,其中的信息可能已经有所发展或是发生改变。
    xdm 好,我是个前端,运维方面的菜鸡,请教大家一下

    我用 openresty 搭建了个简陋版本的灰度切换方案,但是 lua 脚本运行之后好像出了点问题

    -------------------------test.conf start-----------------------------
    upstream production_server {
    server 123.123.123.123:80;
    }
    upstream grayscale_server {
    server 456.456.456.456:80;
    }

    server {
    listen 80;
    server_name localhost;
    lua_code_cache off;
    set $default_stream "production_server";
    set $grayscale_stream "grayscale_server";
    # 运行脚本读取策略
    access_by_lua_file /usr/local/openresty/lua/main.lua;

    location / {
    default_type text/html;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_redirect off;
    proxy_pass $scheme://$default_stream;
    proxy_next_upstream http_500 http_503 error;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root /usr/local/openresty/nginx/html;
    }
    }
    -------------------------test.conf end-----------------------------

    -------------------------main.lua start-----------------------------
    local redisutils = require("redisutils")
    local cOntroller= require("controller")
    local red = redisutils.redisClient()
    local params = ngx.req.get_uri_args()
    local userId = params.userId

    if red then
    local is_grayscale = controller.checkUserId(red, userId)
    if is_grayscale then
    ngx.var.default_stream = ngx.var.grayscale_stream
    end
    redisutils.closeRedis(red)
    end
    -------------------------main.lua end-----------------------------

    我把$default_stream 直接替换为“production_server” 或 “grayscale_server” 都没有问题
    但是 lua 运行后,大概是这一句 ngx.var.default_stream = ngx.var.grayscale_stream
    index.html 中的 js 和 css 等使用相对路径(“/js/xxx.js”)的资源都似乎回源到了代理机器本身,从而最终找不到资源

    如果哪位大佬有办法解决,希望不吝赐教一下,或者说有更好的方法也可以。

    感谢!!!
    第 1 条附言    2021-11-26 10:54:03 +08:00
    我大概知道了,在 conf 文件中
    access_by_lua_file /usr/local/openresty/lua/main.lua
    是非阻塞的,所以往下运行,当脚本没执行完最后 proxy_pass 代理的还是"production_server",而直接写死或通过简单赋值的修改,运行时间是比较快的,能够成功设置值。所以这才出现了那些现象。
    4 条回复    2021-11-29 10:28:21 +08:00
    eason1874
        1
    eason1874  
       2021-11-25 15:44:18 +08:00
    静态文件链接不带 userId 参数吧,按你的代码,链接没有 userId 判断不了是否灰度

    但是判断不了也应该回源 production_server 啊,怎么会是代理机器呢,你确定没搞错?
    laev
        2
    laev  
    OP
       2021-11-26 09:22:39 +08:00
    @eason1874 确实是我搞错了,最终回源到的是 production_server 。我有点疑问的是当$default_stream 为 production_server 也就是默认值的时候,静态文件是可访问的,似乎 nginx 自动处理了$args ,同时 $default_stream 替换为 grayscale_server 也是可以访问的。我尝试在配置文件中写入
    access_by_lua_block {
    ngx.var.default_stream = ngx.var.grayscale_stream
    }
    这样也能成功读取到,目前似乎是在引用 lua 脚本运行赋值时没有获得 userId 从而导致资源被指向 production_server
    eason1874
        3
    eason1874  
       2021-11-26 14:11:09 +08:00
    @laev 你的代码根据网址参数 userId 判断是否灰度,静态文件链接没有这个参数啊

    比如你允许 userId 为 1 的灰度, 当请求 //localhost/?userId=1 时会匹配到灰度,但是网页里面的资源比如 /js/a.js 不会匹配到灰度,因为不是 /js/a.js?userId=1 ,缺少必要参数

    解决办法就是换别的方式传参。比如用 Cookies ,但是 Cookies动态判断的缺点很多,客户端禁用 Cookies 的时候不管用,要在 CDN 缓存静态资源时不管用,等等

    所以不同版本的静态资源路径通常是写死的,部署自动在路径加上文件版本号,比如 /js/a-{filehash}.js ,新版本引用新的文件就不会读取到旧文件

    前端服务在静态文件路径同时反代生产和灰度环境,proxy_next_upstream http_404 ,生产 404 就读灰度,然后把结果缓存并返回
    laev
        4
    laev  
    OP
       2021-11-29 10:28:21 +08:00
    @eason1874 明白了,十分感谢!我一直以来走进死胡同了。。感觉自己有点蠢[笑哭]
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2947 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:27 PVG 20:27 LAX 04:27 JFK 07:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86