首页 > 其他分享 >记一次长连接断开排查过程

记一次长连接断开排查过程

时间:2023-04-28 11:44:57浏览次数:42  
标签:断开连接 浏览器 断开 Nginx 排查 心跳 连接

文章地址

问题

WebSocket 的网络链路是 浏览器 <-> Nginx <-> 后端服务,心跳时间是 60 s,出现了有心跳发送但长连接中断的问题。

过程

  1. 查看后端服务日志,发现是被动断开,不是空闲检测主动断开的,再抓服务器的网络包,确认后端服务是被断开的,排除后端服务的问题。

  2. 使用其他语言建立 WebSocket 长连接,维持 10 秒一次心跳,经过 45 小时测试没有断开连接,那么大概率是浏览器 或 JavaScript 哪里不对。

  3. 抓浏览器的包,这次比较诡异,发现浏览器的长连接也是被动断开的,那问题就只能是 Nginx 的了。

  4. 抓 Nginx 的包,发现每次都是 Nginx 先把后端服务的连接断开,之后再断开浏览器的 WebSocket,查看与后端服务的通信,没有问题,接着查看浏览器发送的心跳包,发现这种场景的最后一个心跳包都是 60 s 前发送的,而正常的心跳是 10 s 一次,那么问题就确定了,是浏览器的心跳包不是 10 s 一次,而是 1 分钟一次导致的,但 1 分钟没有心跳导致断开连接是应该由后端服务的空闲检测触发的,不应该由 Nginx 触发,将该问题扔给 ChatGPT 后得到了一个 Nginx 的参数 proxy_read_timeout,这个参数默认 60 s,即 60 s 内没有通信就关闭连接,这样就解释了为什么 Nginx 会主动断开与后端服务的连接,将 proxy_read_timeout 设置为更长时间,经过测试,主动断开连接的发起者就变成了后端服务的空闲检测机制。

下面的图片描述了这个过程:

长连接断开

如果图中 1 分钟后的心跳是心跳 1,那么就不会断开连接,如果慢了一会,比如 100 ms,即心跳 2,则会导致连接断开。

  1. 上面 Nginx 的配置只解决了断开连接一定由后端服务的空闲检测发起,但问题的关键在于浏览器的心跳包发送时间间隔不对,刚开始是 10 s 一次,过了一段时间就变成了 1 分钟一次。首先如果在当前页面的话不会发生这种问题,但如果在其他页面就会触发这个问题,接着查看开发者工具中的网络,发现过一段时间定时器变成了 1 分钟一次(也可能是 1 分钟内的不固定的时间点,但断开连接的最后一个心跳一定是 1 分钟),在查阅资料后确定浏览器会优化非当前页面的定时器,将所有定时器合并为 1 分钟触发一次已降低系统资源占用。

  2. 如何解决浏览器的定时器被优化的问题?使用 WebWorker。使用 WebWorker 后定时任务心跳发送的时间间隔不再出现 1 分钟执行一次的问题,也就没有出现过 WebSocket 被断开的问题。看了下友商的前端实现,发现也是 WebWorker。

总结

开始排查时思维有点凌乱,没有确定思路,实际应该先确定心跳(客户端)是否有问题,如果心跳没问题再排查服务端。

资料

https://developer.chrome.com/blog/timer-throttling-in-chrome-88/

标签:断开连接,浏览器,断开,Nginx,排查,心跳,连接
From: https://www.cnblogs.com/hligy/p/17361617.html

相关文章

  • 【远程连接工具】xshell上用vi/vim小键盘无法使用的修改办法
    转至:https://blog.csdn.net/qq_44676946/article/details/117257410问题:后台开发人员经常使用Xshell来访问远程服务器,在用vim(或vi)编辑文件的时,使用小键盘数字键的时候,可能会输入一堆字母和换行,并不是数字。修改:1.修改会话属性2.选择类别“终端”-VT模式3.选择“初始数字键盘......
  • struts 1.2 struts连接池河dbcp连接池所要用的3个jar包
    连接池struts-config.xml里配置<struts-config>下<data-sources> <data-sourcekey="mysqlDB"type="org.apache.commons.dbcp.BasicDataSource"> <set-propertyproperty="driverClassName" val......
  • Sql Server 2005 在建立与服务器的连接时出错。provider,error: 40
    在建立与服务器的连接时出错。在连接到SQLServer2005时,在默认的设置下SQLServer不允许进行远程连接可能会导致此失败。(provider:命名管道提供程序,error:40-无法打开到SQLServer的连接)(.NetSqlClientDataProvider) 网上找的解决办法对我的不适用下面上网......
  • linux排查
    应急响应一:网络连接排查(重点关注高危端口的链接)netstat-pantu二:获取异常进程pid占用CPU空间top-c-o%CPUps-eopid,ppid,%cpu,%mem,cmd--sort=-%cpu|head-5占用内存空间top-c-o%MEMps-eopid,ppid,%mem,%cpu,cmd--sort=-%mem|head......
  • python 连接数据库
    使用pymysql连接数据库importpymysqlconn=pymysql.connect(host="10.00.0.00",port=31379,user="root",password="123456",database="acc_test")#模拟从数据库获取单个字段值withconn.cursor()ascursor:#获取【......
  • spring boot jpa MYSQL教程mysql连接的空闲时间超过8小时后 MySQL自动断开该连接
     SunApr1608:15:36CST2023Therewasanunexpectederror(type=InternalServerError,status=500).PreparedStatementCallback;SQL[selectuserIdfromfamilyxiao_UserConnectionwhereproviderId=?andproviderUserId=?];Nooperationsallowedaftercon......
  • 线上问题排查回答(转载)
    面试官:「你是怎么定位线上问题的?」这个面试题我在两年社招的时候遇到过,前几天面试也遇到了。我觉得我每一次都答得中规中矩,今天来梳理复盘下,下次又被问到的时候希望可以答得更好。下一次我应该会按照这个思路去答:1、如果线上出现了问题,我们更多的是希望由监控告警发现我们出了......
  • 蓝牙的扫描、连接、读写
    步骤:在info.plist中加入蓝牙的权限NSBluetoothAlwaysUsageDescription:创建蓝牙管理者对象,创建后,首先会执行系统蓝牙是否打开的协议方法centralManagerDidUpdateState,如果系统蓝牙未打开,会有系统的弹框提示打开蓝牙,如下:打开系统蓝牙后,开始扫描设备,扫描到设备后会执行didDis......
  • 使用ethtool排查网卡速率问题
    今天去现场帮一个客户排查备份网络速率问题。用户期望是万兆的速率,但实际上目前只有千兆,因为目前上面运行着数据库,且数据量较大,千兆的备份网络速率不能满足用户备份数据库的时长要求。首先,确认备份网络是由两块网卡(eth3,eth4)做了bonding,起名为bondeth1。使用ethtool查看底层的et......
  • 记一次线上服务器问题排查过程
    问题描述前几天我们更新线上服务器,使用对应的新版客户端连接时,怎么都连不上,如果直接连接其他服,比如我们内部的测试服或者审核服,却一切正常。同时,如果使用老包连接服务器,也是正常的这个问题查的头疼,每一步都超出我的理解范围排查过程首先第一步,我们在服务器接口的必经之路上......