为什么 NGINX 使用自定义变量代理 ws 会异常?

10 天前
 luxu

之前一直用同样的方式连接后端服务, 是正常使用的。 如

location ^~/prod-api/ {
	    proxy_pass http://$api_host:$api_port;
	    ......
	}

异常情况:

连接 http://$api_host:8877/ws/ 就会异常

server {
        listen    443 ssl;
        set $api_host api;
        ..........

location  /ws/ {
            proxy_pass http://$api_host:8877/ws/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_connect_timeout 90s;
            proxy_send_timeout 120s;
            proxy_read_timeout 120s;
            send_timeout 120s;
        }
}

正常情况:

设置 http://api:8877/ws/ 正常

server {
        listen    443 ssl;
        set $api_host api;
        ..........

location  /ws/ {
            proxy_pass http://api:8877/ws/;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
            proxy_connect_timeout 90s;
            proxy_send_timeout 120s;
            proxy_read_timeout 120s;
            send_timeout 120s;
        }
}

在 nginx 容器内两种设置的抓包截图: https://imgur.com/a/XzyNFQ6

搞不清楚是什么原因导致这种情况,为什么不能这样配。想请教下大家

745 次点击
所在节点    NGINX
5 条回复
msg7086
10 天前
set 指令可能是在 proxy_pass 之后执行的。
纯粹猜测,你可以做做实验或者查一下资料。

Nginx 的配置文件,归根结底是配置而不是程序,不要总是期望写在上面的会比写在下面的早执行。
msg7086
10 天前
另外你可以看看能不能用 upstream 代替 set 来设置变量。upstream 应该是在很靠前的阶段执行的。
rrfeng
10 天前
完整配置贴出来看看
Hanada
3 天前
proxy_pass 的值有变量的话 nginx 的处理逻辑是不一样的。如果有接变量的话,nginx 不会再帮你附加原始请求 uri 进去,所以你异常那个就变成固定使用/ws/回上层了。如果你一定要用变量,可以考虑这样写
proxy_pass http://$api_host:8877$request_uri;
另外不建议无脑给 Connection 头写死设置 Upgrade ,可以参考 nginx 官方第二种写法,用 map 来指定
https://nginx.org/en/docs/http/websocket.html
luxu
2 天前
@Hanada 非常感谢, 解决了我的问题。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1051110

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX