一次线上tcp连接数告警的解决方案
博客专区 > jerrik 的博客 > 博客详情
一次线上tcp连接数告警的解决方案
jerrik 发表于1个月前
一次线上tcp连接数告警的解决方案
  • 发表于 1个月前
  • 阅读 1
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

         最近老大反馈某机器tcp连接数频繁告警,要我去定位下问题。接到任务后,首先分析一下问题:

 1.这个项目上线已有1-2年,以前未曾反馈tcp连接数超标的情况,难道是最近上线的xx需求导致的?

 2.tcp连接数一般都和网络问题有关,且该机器的业务有和银行打交道,且涉及到文件的上传与下载。

 3.查看下CPU和内存使用率是否偏高?

        首先用netstat查看了一下tcp连接,确实存在大量的ESTABLISHED连接,且一直有上升的趋势,这应该就是导致tcp连接数告警的主要原因.然后用jstack查看了线程堆栈,发现有大量的Connection Thread与xxx IP正在建立连接,该ip主要用来和银行进行sftp文件传输。

        打开IDE,全局搜索下使用了jsch的地方,果不其然,确实存在一个通用的文件上传与下载的服务类。

    这是一个全局的初始化方法,首先根据主机名、用户名和账号来创建一个会话,然后调用它的连接方法,一切都很自然,看不出毛病。

     

    下面来看一下文件上传的方法:

    首先获取sftp的通道,然后就直接使用jsch的内部方法实现文件的上传,最后调用disconnect()方法来释放连接。第一反应,有打开连接的方法,上传成功也将连接进行了关闭,怎么

会出现连接不释放的情况呢?

    

      接着看getChannelSftp()和disconnect()方法:

        

       

       根据创建的session来获取sftp渠道,然后调用sftp的connect()方法正式建立文件的输入输出通道。当文件上传、下载完毕,将sftp的渠道关闭,很正常的逻辑。

        但是在什么情况下会出现连接不释放的情况?看一下catch中的代码,当抛出了异常,系统会再次调用初始化init方法。跟进session.connect()方法,发现里面确实启动了一个名字为

Connection Thread的线程,且当调用disconnect()方法的时候 我们并没有手动的关闭掉该线程,而只是关闭了sftp通道而已,所以该线程一直都得不到释放。在init方法后,又重复调用了一次session连接方法,导致启动了两个线程。当时就认为应该是这个问题导致的。

       但是究竟是什么原因会导致抛出异常而发起重连呢?这里只能做一下猜测,或许是tcp连接主动断开导致重连然后频繁创建新的线程,或许是和银行发起文件传输的时候由于网络不稳定导致tcp自动重连,但是之前的线程已经建立。

        最终的解决办法就是去掉init后面的session.connect()方法和在调用disconnect()方法的时候 再调用session.disconnect();jsch的具体实现是手动中断掉之前创建的connection thread,然后将线程置空。

       博主第一次写文章,非喜勿骂,谢谢~

 

 

 

 

 

 

 

 

 

共有 人打赏支持
粉丝 4
博文 11
码字总数 6574
×
jerrik
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: