记一次服务停止排查

早上到公司,查看周末日志有没有异常。日志都是按天切割的。发现昨天的日志,大部分都没有。查发布记录,周末没有人发布过。jps,进程也在。而且小部分日志是正常的。问了运维的人员,也没有人手动删除过。试着打开当前的日志,发现最后一条的日期是昨天下午16点。脑子嗡的一下:完了,服务昨天下午就挂了,到现在都没人发现。

这个服务对应的模块,用户数比较少,且使用频率较低,用户就没有反馈。查看线程和端口都还在,所以健康检查服务并没有报警。

首先怀疑是网络流量不通,问过运维并没有改过nginx配置。尝试模拟前端通过公网调用接口,抓包,返回502.在服务器上直接调用自己的接口,长时间没有返回,直接阻塞。

尝试重启,服务恢复。但是全部重启了,没有留一个现场调查。猜测服务是假死,开始冥思苦想可能的原因。

午饭后,服务再次挂掉。负载均衡上摘掉一台机器做研究。查看内存使用 和 cpu 使用率都非常低。jps拿到pid,jstack <pid> 去所有线程状态。共近300个线程,60个BLOCKED状态。绝大多数都是如下内容:

 
 
 
Thread 31770: (state = BLOCKED)
 - sun.misc.Unsafe.park(boolean, long) @bci=0 (Interpreted frame)
 - java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=175 (Interpreted frame)
 - java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() @bci=42, line=2039 (Interpreted frame)
 - java.util.concurrent.ArrayBlockingQueue.take() @bci=20, line=403 (Interpreted frame)
 - ch.qos.logback.core.AsyncAppenderBase$Worker.run() @bci=21, line=250 (Interpreted frame)

应该是线程池等待任务。其他线程大多都是IN_NATIVE状态。如下:

 
 
 
Thread 6272: (state = IN_NATIVE)
 - java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)
 - java.net.SocketInputStream.socketRead(java.io.FileDescriptor, byte[], int, int, int) @bci=8, line=116 (Compiled frame)
 - java.net.SocketInputStream.read(byte[], int, int, int) @bci=79, line=170 (Compiled frame)
 - java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=141 (Compiled frame)
 - java.io.BufferedInputStream.fill() @bci=214, line=246 (Compiled frame)
 - java.io.BufferedInputStream.read1(byte[], int, int) @bci=44, line=286 (Compiled frame)
 - java.io.BufferedInputStream.read(byte[], int, int) @bci=49, line=345 (Compiled frame)
 - sun.net.www.http.HttpClient.parseHTTPHeader(sun.net.www.MessageHeader, sun.net.ProgressSource, sun.net.www.protocol.http.HttpURLConnection) @bci=51, line=704 (Interpreted frame)
 - sun.net.www.http.HttpClient.parseHTTP(sun.net.www.MessageHeader, sun.net.ProgressSource, sun.net.www.protocol.http.HttpURLConnection) @bci=56, line=647 (Interpreted frame)
 - sun.net.www.protocol.http.HttpURLConnection.getInputStream0() @bci=327, line=1535 (Interpreted frame)
 - sun.net.www.protocol.http.HttpURLConnection.getInputStream() @bci=52, line=1440 (Interpreted frame)

看到是发出的http请求,一直卡到socketRead上。方法栈继续向下找,找到了业务方法,是一个webservice对第三方依赖服务的请求。经过与同事交谈得知,第三方服务对请求ip有白名单控制,而我们的出口IP刚好在昨天修改过,导致请求失败。而请求的部分是对方封装的jar包,内部没用进行超时处理。用户请求卡到这,最终耗尽线程池中的线程。无法响应新请求。

对策:

1.增强基础设施管理制度,流程化,保证各部门对相关修改知晓,且有足够时间对出反应。

2.第三方依赖耦合度降低,排除因为依赖的服务问题,导致整体服务停止。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值