Springboot服务突然不可用的几点可能原因

前言

写代码时间长了难免会碰上几次线上服务突然不可用的状况,今天就简单来说说几个原因。

一 出现ECONNREFUSED

如果是接口调用时出现ECONNREFUSED,那么大概率是java进程挂了,在服务器上执行jps -v -l 命令看看进程是否在。
如果进程不在,那么应该是系统内存不足,被linux杀掉,查看系统杀进程的命令如下

sudo egrep -i -r 'killed process' /var/log

这个情况我在测试环境碰上几次,原因是同一个机器上跑了几个应用,其中一个应用有时占用大量内存,然后系统把内存最大的应用给杀了。

二 出现ECONNRESET

如果是接口调用返时出现ECONNRESET,那么应该是监听端口的全连接队列满了,系统无法接受新的TCP连接了。可以执行命令netstat -ano|grep 端口|grep LISTEN 查看全连接队列的数量。

第二列是全连接队列Recv-Q,如果队列满的时候这个值是100,这个值是springboot启动监听端口时设置的,取自server.tomcat.accept-count,默认为100。
按正常流程来看,Recv-Q的每一条记录都会被服务应用立即读取出来,放进connection队列中,再用工作线程处理数据,这里的connection队列默认最大值是10000。
所以会出现ECONNRESET的原因可能是此时系统的并发数已经超过10000+100。

三 接口无响应

如果是接口调用时响应很久都没返回,那么可以用top命令查看cpu使用率,如果java进程的cpu使用率高居不下,那大概率是GC线程是拼命运行中,可以用以下步骤验证。
执行命令top -Hp 进程id查看哪些线程占用cpu

把占用率高的线程tid换成十六进制,如30100转成7594,执行命令jstack 进程id|grep 7594

如果看到是带GC字眼的线程,那么就可以确定是因为不断GC导致接口无法响应。如果用命令jstat -gc 进程id查看fullgc次数还在不断的上升。这个时候可以用jmap -dump:format=b,file=heapDump 进程id打印堆,再用Java VisualVM等工具解析,结合接口调用日志基本就可以定位问题所在了。而在这种情况出现前,还会有类似GC overhead limit exceeded的报错。
通常这种情况会在用户不停在做大量数据导出操作时出现。

四 接口无响应

接口调用时响应很久都没返回,还有一种现象是,出现out of memory错误后,应用占用cpu低,用jstat -gc 进程id查看GC也没有异常,看起来一切都正常,但偏偏无法响应请求。这种情况有可能是Tomcat的acceptor线程被杀掉,acceptor线程负责从操作系统的全连接队列提取socket连接,执行命令看看进程是否存在

jstack 进程id|grep  Acceptor
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值