服务不可用的一个问题
今天线上遇到一个问题,我有个服务调es做curd, 有一段时间服务突然不接收请求,进程还活着,就是单纯的请求进不来了,但是过了一会儿又好了。排查了一下故障前后有大量的请求丢弃(服务是rpc调用,服务端有4个队列每个队列32线程),观察到队列中有很多请求等待时间过长。
服务当时是这样的:
瞬间一段时间(18:19)就没有流量了,然而进程还在。
后来莫名其妙自己又活了,但是活了以后瞬间并发量上来了。
因为服务影响面积大,问题出现瞬间我尝试重启服务,但是并没什么用,起来后收到几次请求立马又假死了。
排查的过程中,在日志里面又看到 有少数请求调用时间非常久,估计是因为这个导致所有线程都被占满了,腾不出更多的空来接受新的请求了。
可以确保不是网络问题,因为这一段时间服务器是有出口流量的,找运维同学看过监控了。
另外,这一段时间的内存稍微吃的有点多,但是没有出现大面积全GC,个人觉得不太像是全GC导致的,至少GC日志看不到FullGC 字样,只是cms gc回收老年代频率高了点。
这个rpc服务 里面是调用elasticsearch做增删改查业务的,调用量挺高的,不过出问题的时候是低峰期,我觉得唯一的解释就是这一会儿存在一些 查询或者修改很慢的请求占用了这128个线程不释放。
好了,问题和我自己的假设已经叙述完了, 如果我的假设成立的话,那么优化方向似乎就变成了:如何提升请求响应速度,进而演变为了:如何提升elasticsearch 的增删改查效率(的确,线上环境再一些高峰期的时候,会出现一些删改查比较慢的请求,但es的删改查效率原本也不高),这块的优化方案是我想问大伙儿的。
另外,是不是需要设置增删改查和es交互这块的超时时间,比如es api里面有 get(timeout)这种方法,但是我又不知道这个数设置多少是合适的,这块也是我想问的。
超时这个问题上,是不是在es api客户端也要做文章,有没有可能是我调用es 客户单发起请求,但是每次请求完我并没有close,这样导致链接长时间不释放,阻塞了es集群,导致很多es操作时间其实并不长,但是都浪费在了等待es服务端接受请求上。不过貌似TransportClient是做了连接池的吧,这样还需要我手动close链接吗?这也是我想问的。
最后,大家帮忙分析下,这种假死行为还有没有可能是别的原因,由于事发紧急,没来得及捕获更多信息,我能保证的是内存和cpu还是足够的,机器监控记录能看到。网络OK的,进程没有死。
有遇到类似问题的同学,欢迎一起探讨。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我们貌似也遇到过类似的问题,我们当时因为事务引起的,后来调小了事务的粒度,解决了这样的问题。
我们排查过程这样做的,在服务中的关键位置(如查数据库,业务业务,接口内层,接口外层)做耗时记录,再压测可以看到在哪个环境耗时最多,即造成阻塞的点;然后分析到是事务控制不当,频繁开启事务,导致最终的后果。
另外,磁盘的IO情况如何呢?
以上,愿对你有帮助!