nginx反向代理到websocket出现卡顿的问题

问题:

公司的某项业务是通过nginx反向代理到ws协议的服务,用ws协议的目的是保持长连接,持续性提供服务。但是服务经常出现卡顿现象,猜测可能是没有保持长连接,出现超时连接断开的问题。

解决方案:

ws协议是支持心跳机制的。

  • 心跳机制即:
    在使用websocket的过程中,有时候会遇到网络断开的情况,但是在网络断开的时候服务器端并没有触发onclose的事件。这样会有:服务器会继续向客户端发送多余的链接,并且这些数据还会丢失。所以就需要一种机制来检测客户端和服务端是否处于正常的链接状态。因此就有了websocket的心跳了。还有心跳,说明还活着,没有心跳说明已经挂掉了。
  • 原理
    心跳机制是每隔一段时间会向服务器发送一个数据包,告诉服务器自己还活着,同时客户端会确认服务器端是否还活着,如果还活着的话,就会回传一个数据包给客户端来确定服务器端也还活着,否则的话,有可能是网络断开连接了。需要重连

检查了代码发现心跳超时间设置了5秒,也就是说每5秒就会发送数据包检测客户端和服务端运行状态。在客户端和服务端没有出现网络问题的情况下会一直保持长连接,不会出现卡顿的现象。排除网络问题,问题可能出现在nginx反向代理上。检查了配置发现有几个参数有一些问题。
proxy_connect_timeout 5s;
proxy_read_timeout 5s;

在官方文档上查找了参数的含义如下:

Syntax: proxy_connect_timeout time;
Default:
proxy_connect_timeout 60s;
Context: http, server, location
Defines a timeout for establishing a connection with a proxied server. It should be noted that this timeout cannot usually exceed 75 seconds.

定义了与代理服务器建立连接时的超时时间。这个设置5秒也是足够了,可以排除。

Syntax: proxy_read_timeout time;
Default:
proxy_read_timeout 60s;
Context: http, server, location
Defines a timeout for reading a response from the proxied server. The timeout is set only between two successive read operations, not for the transmission of the whole response. If the proxied server does not transmit anything within this time, the connection is closed.

定义从代理服务器读取响应的超时时间,也就是5秒内没有响应即断开连接。

问题就出现在这里,这个参数设置的5秒正好和心跳超时时间一样。这有可能会导致心跳机制还没发送数据包进行心跳测试,代理服务器发现超时就断开连接了。只要把代理服务器nginx的read_timeout参数设置成远大于心跳的超时时间就可以解决问题。我设置了默认的60秒解决了卡顿问题。

你可能感兴趣的:(nginx反向代理到websocket出现卡顿的问题)