打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
服务端Too many open files解决方案
近期系统上线,发现了一个很奇怪的问题,服务端运行没多久就出现页面打不开的现象,查看日志发现大量Too many open files,每台服务器以100MB/s的日志写入速度增加,没多久,每台服务器的日志都纷纷突破了10GB,显然连接数太大,服务器撑不住了,日志截图如下
< xmlnamespace prefix ="v" ns ="urn:schemas-microsoft-com:vml" />< xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
看到这样的景象,当然是首先逐台停止服务器(目前我们使用的是
Tomcat),删除日志,然后启动,但是这样显然维持不了很久又会出现相同的问题,为了不影响用户使用,当然需要两步一起走! 1、      逐台停止Tomcat,删除日志,增大系统可打开的文件连接数,启动Tomcat,恢复服务,保障用户服务正常!
2、      尽可能快的查出问题原因,从根源上解决问题。
那么,首先第一步,查看系统当前连接数是多少?使用命令ulimit –a查看
显然,当前的
1024不能满足我们的需求,因此我们需要加大,Linux连接数最大为65536,我们就暂时设置为最大,让服务器多撑一会,给我们第二部的兄弟排查问题准备足够的时间,设置有很多方法,我在这里列举2种 1、  ulimit -n 65536,上图中已经提示我们使用-n查看对应的连接数,-n + value设置对应的数据值。如下截图所示
这种设置方式非常方便快捷,但是这种设置只对当前登录用户的目前使用环境有效
,系统重启或者用户退出后就会失效。要想永久改变对应的值,需要采用第二种方案 2、  vim /etc/security/limits.conf 进行设置
修改/etc/security/limits.conf(里面有很详细的注释哦),在最下方添加
* soft nofile 65536
* hard nofile 65536
保存即可,这时候,需要重启Tomcat才生效
这时候,使用
umilit –a 或者 ulimit –n查看的时候仍然是1024 当你退出重新登录以后就显示正常了(注意Tomcat要重启哦) 重新登录之前
执行
exit 和login之后
这样,按照之前的速度,还能多撑一个小时左右。
接下来就要彻查问题到底是出在什么地方了,继续监控Tomcat发现,Tomcat抛出了很多异常can't identify protocol,并且都是进程Java(即Tomcat的进程)抛出的,下面的问题就是can't identify protocoll是什么?是如何产生的?以前为何没有见过这个异常!
(注:使用lsof |grep java |grep 'identify protocol'查看Tomcat抛出的can't identify protocol错误数。)网上查询资料,发现can't identify protocol属于网络协议包丢失或者泄漏导致,以下是一段参考资料
问题定位步骤:
1、 用root帐户 遍历 /proc/进程ID/fd目录,如果该目录下文件数比较大(如果大于10,一般就属于socket泄漏),根据该进程ID,可以确认该进程ID所对应的名称。
2、 重启程序恢复服务,以便后续查找问题。
3、 strace 该程序并记录strace信息。strace –p 进程ID >>/tmp/stracelog.log 2>&1
4、 查看 /proc/进程ID/fd 下的文件数目是否有增加,如果发现有增加,记录上一个socket编号,停止strace
5、 确认问题代码的位置。打开/tmp/stracelog.log,从尾部向上查找close(socket编号)所在行,可以确认在该次close后再次创建的socket没有关闭,根据socket连接的server ip可以确认问题代码的位置。
另一种方法:判断是否有socket泄漏:
lsof | grep "can't identify protocol"
如果存在很多,则代表socket泄漏,同时会显示哪个进程使用的sock未关闭。
也就是说,他使用了某个网络,但是这个网络发起了很多请求,却一直没有断开连接,怎么会造成这种现象的呢?但是值得肯定的是一定是向某个机器发起了请求但是却没有响应并且没有断开!
1、  接口调用,显然不会,接口都设置了半分钟超时,没有相应会自动断开,并且接口调用没有这么频繁,也不会这么快做重试操作!排除(X)
2、  数据库连接池,对于数据库来说,一般都设置了数据库连接池,也就是说最多创建多少个连接,每次从连接池中取数据,不可能有这么大的连接量!并且在机器重启后和刚开始系统服务正常,说明数据库连接正常,即便是数据库的问题,也是某些数据导致了异常,但是被限定于数据库连接池的大小,用监控发现,基本上这种车错误以5个/s的速度增长,而数据库连接不可能有这么大的量!排除(X)
3、  消息中间件,消息中间件采用ActiveMQ的方式进行异步通讯,设置有自动重连机制,并且使用长连接,有可能发生连不上重连的问题,但是消息中间件只要用于短信认证、邮件认证、订单交易的使用,不可能这么均匀的增长,并且查询数据库,当时的数据量也很小,检查消息中间件,工作正常,监控过程中有消息接受和消费,因此排除(X)
4、  缓存中间件,缓存中间件采用memcache做服务端存储,使用同步机制通讯,设置有自动重连机制,也有可能导致重连连不上一直连接的问题,排查缓存服务器,端口服务正常,但是发现了一块很奇怪的问题,缓存中的数据只有很少一部分,按照之前设计的,很多数据通过缓存存取,再查缓存命中率,发现近乎100%不命中,显然是缓存除了问题,但是服务正常,为何数据却没有写入的呢?于是马上入手,检查服务器到缓存的网络链路,发现是通的,那就是程序没有连接到这台机器上了,继续排查程序的配置文件,终于真相大白了,原来配置文件配置错误!连接的是研发环境的一台缓存服务器,而不是对应的服务器,而程序包通过AutoConfig推送,导致所有的分布式机器配置文件都是错误的(分布式为了更好的自动化部署机器,使用淘宝的AutoConfig处理配置文件一致的问题),每次系统先从缓存服务器取数据,如果取不到对应的数据则直接从DB取数据,从DB取完成数据后将数据缓存的对应的缓存服务器,但是此时缓存服务器不通,因此就产生可一个长连接失效的错误can't identify protocol,而memcache客户端又不停的尝试连接memcache(因为memcache是长连接),最终导致了大量的can't identify protocol产生,而大量can't identify protocol的产生导致了系统文件连接数过多,系统连接数过多在直接影响了Socket连接的打开与关闭,最终导致了系统的无法响应!命中(√)
问题找到了,修改就变得很简单了,修改为对的配置,重启Tomcat,果然can't identify protocol消失了,系统相应快了很多!
问题是解决了,但是有个很严重的问题,之前用的memcache客户端连不上主服务器的时候会抛出Socket异常,现在为什么不会了呢?还需要继续查找!
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
关于 “can't identify protocol” 问题的定位
Web网站搭建从零到一
理解memcache客户端和服务器端
如何同时启动多个Tomcat服务器
tomcat的4个端口配置
服务性能监控指标
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服