Nginx反向代理WebSocket超时

Nginx反向代理WebSocket超时,nginx,websocket,nginx-reverse-proxy,Nginx,Websocket,Nginx Reverse Proxy,我在wowza应用程序中使用JavaWebSocket满足我的websocket需求,并使用nginx进行ssl,将请求代理给java 问题是,服务器端的连接似乎在整整1小时后被切断。客户端甚至不知道它已经断开了很长一段时间。我不想只调整nginx上的超时,我想了解为什么连接会被终止,因为套接字一直正常工作,直到它不工作为止 编辑: 忘记发布配置: location /websocket/ { proxy_set_header X-Real-IP $remote

我在wowza应用程序中使用JavaWebSocket满足我的websocket需求,并使用nginx进行ssl,将请求代理给java

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

编辑: 忘记发布配置:

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;
}
其中包括:

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()

很可能是因为您需要对websocket代理的配置进行一些调整,但由于您要求:

反向代理服务器在以下方面面临一些挑战: 支持WebSocket。一是WebSocket是一种逐跳协议, 因此,当代理服务器截获来自客户端的升级请求时 需要向后端服务器发送自己的升级请求,包括 适当的标题。另外,由于WebSocket连接很长 与HTTP使用的典型短命连接不同, 反向代理需要允许这些连接保持打开状态, 而不是因为它们似乎闲置而关闭它们

在处理websocket代理的location指令中,您需要包含标题,这是Nginx给出的示例:

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发送升级请求 从客户端到后端服务器,升级和连接 必须显式设置标题,如本例所示


我还建议您看一下将websocket功能直接添加到Nginx中的。工作正常。

超时可能来自客户端、nginx或后端。当你说它被切割为“服务器端”时,我认为这意味着你已经证明它不是客户端。您的nginx配置看起来不应该超时,因此只剩下后端

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

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响应

time curl -i -N --insecure \
  -H "Host: example.com" \
  https://127.0.0.1:443/proxied-path
HTTP/1.1504网关超时
服务器:nginx/1.14.2
日期:2019年9月19日星期四21:37:47 GMT
内容类型:text/html
内容长度:183
连接:保持活力
504网关超时
504网关超时

nginx/1.14.2 实际1m0.207s 用户0m0.048s 系统0m0.042s
其他想法 有人提到尝试,但除非客户端正在关闭连接,否则不会有任何区别。此外,尽管这可能会保持内部连接打开,但我认为它无法保持端到端流的完整性

您可能想试试,但这需要nginx>=1.15.6

最后,报告中有一条注释提示了一个好的解决方案:

或者,可以将代理服务器配置为定期发送WebSocket ping帧,以重置超时并检查连接是否仍处于活动状态


如果您可以控制后端并希望连接无限期地保持打开状态,则定期发送到客户端(假设使用了web浏览器,则不需要在客户端进行任何更改,因为它是作为规范的一部分实现的)应该可以防止连接因不活动而关闭(使代理读取超时变得不必要)无论它打开多长时间或涉及多少中间框。

对不起,我应该将我当前的配置与问题一起发布。现在更新。您是否尝试过包括
proxy\u ignore\u client\u abort on;
?尝试一下。几个小时后会更新结果。谢谢。仍在发生。在exacly on之后,几个连接关闭e hour:(@miknik
-validity 3650
将证书的有效期设置为10年(这里的单位是天,而不是秒)正如您所说,ping是一个问题。我使用的packge有一个自动发送ping的实现,但我在集成它时没有看到它,而是“手动”发送ping.一旦我换了它,我就没有任何问题了。
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