首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Nginx反向代理WebSocket超时

Nginx反向代理WebSocket超时
EN

Stack Overflow用户
提问于 2018-08-29 21:01:22
回答 2查看 9K关注 0票数 3

我使用java-websocket来满足我的websocket需要,在一个wowza应用程序中,使用nginx for ssl,将请求代理到java。

问题是,在服务器端,连接似乎恰好在1小时后被切断。客户端甚至不知道它已经断开了很长一段时间。我不想仅仅调整nginx上的超时,我想知道为什么连接被终止,因为套接字一直像往常一样工作,直到它不再工作。

编辑:忘记发布配置:

代码语言:javascript
复制
location /websocket/ {
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    include conf.d/proxy_websocket;
    proxy_connect_timeout 1d;
    proxy_send_timeout 1d;
    proxy_read_timeout 1d;
}

其中包括配置:

代码语言:javascript
复制
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass                      http://127.0.0.1:1938/;

  • Nginx/1.12.2
  • CentOS Linux版本7.5.1804 (核心)
  • Java WebSocket 1.3.8 (GitHub)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-09-20 05:51:50

超时可能来自客户端、nginx或后端。当你说它正在被“服务器端”切断时,我的意思是你已经证明了它不是客户端。您的nginx配置看起来不应该为1 day超时,所以只剩下后端。

直接测试后端

我的第一个建议是尝试直接连接到后端,并确认问题仍然存在(出于故障排除的目的,将nginx排除在外)。请注意,如果使用浏览器不实用,则可以使用命令行实用程序(如curl )来完成此操作。下面是一个测试命令示例:

代码语言:javascript
复制
time curl --trace-ascii curl-dump.txt -i -N \
  -H "Host: example.com" \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Sec-WebSocket-Version: 13" \
  -H "Sec-WebSocket-Key: BOGUS+KEY+HERE+IS+FINE==" \
  http://127.0.0.1:8080

在我(正在工作)的情况下,运行上面的示例会无限期地保持打开状态(我手动使用Ctrl-C组合键停止),因为curl和我的服务器都没有实现超时。然而,当我将其更改为通过nginx作为代理时(默认超时为1分钟),如下所示,几乎恰好1分钟后,我看到来自nginx的504响应。

代码语言:javascript
复制
time curl -i -N --insecure \
  -H "Host: example.com" \
  https://127.0.0.1:443/proxied-path
代码语言:javascript
复制
HTTP/1.1 504 Gateway Time-out
Server: nginx/1.14.2
Date: Thu, 19 Sep 2019 21:37:47 GMT
Content-Type: text/html
Content-Length: 183
Connection: keep-alive

<html>
<head><title>504 Gateway Time-out</title></head>
<body bgcolor="white">
<center><h1>504 Gateway Time-out</h1></center>
<hr><center>nginx/1.14.2</center>
</body>
</html>

real    1m0.207s
user    0m0.048s
sys 0m0.042s

其他想法

有人提到尝试proxy_ignore_client_abort,但这不会有任何影响,除非客户端关闭连接。此外,尽管这可能会使内部连接保持开放,但我不认为它能够保持端到端流的完整性。

您可能想尝试proxy_socket_keepalive,尽管这需要nginx >= 1.15.6。

最后,在WebSocket proxying doc中有一个注释,它暗示了一个好的解决方案:

或者,可以将代理服务器配置为定期发送WebSocket ping帧,以重置超时并检查连接是否仍然有效。

票数 5
EN

Stack Overflow用户

发布于 2018-08-30 00:54:16

这很可能是因为websocket代理的配置需要稍微调整一下,但既然您问了:

在支持WebSocket时,反向代理服务器面临一些挑战。一种是WebSocket是逐跳协议,因此当代理服务器截获来自客户端的升级请求时,它需要向后端服务器发送自己的升级请求,包括适当的标头。此外,由于WebSocket连接是长连接,而不是典型的短连接,反向代理需要允许这些连接保持打开,而不是因为它们看起来空闲而关闭它们。

在处理websocket代理的location指令中,您需要包括头部,这是Nginx给出的示例:

代码语言:javascript
复制
location /wsapp/ {
    proxy_pass http://wsbackend;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}

这现在应该可以工作了,因为:

NGINX通过在客户端和后端服务器之间建立通道来支持WebSocket。为了让NGINX从客户端向后端服务器发送升级请求,必须显式设置Upgrade和Connection头部,如下例所示

我也推荐你看看Nginx Nchan module,它将websocket功能直接添加到Nginx中。效果很好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52078122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档