tomcat假死无法访问问题

1 网络

检查网络是否正常,ping是否能正常通,是否有丢包

2 nginx连接查看

2.1 检查ng的网络

检查到ng的服务是否正常,access.log中是否能正常打印日志

ng到后端的转发是否正常,ping到后端的网络是否通畅,access.log中是否能从后端转发中正确得到响应

2.2检查tomcat的情况

1.tomcat的进程是否还在 ps -ef | grep tomcat

2.tomcat中的日志是否还在持续打印日志,自己本地调curl 用服务看能否得到响应,如果不行说明服务有问题,如果日志正常打印可能存在网络问题

3 查看TCP连接是否正常

使用ss -s命令查看tcp的连接状态 关注time_wati参数

可以修改 /etc/sysctl.conf来修改timeout的值

[root@web01 ~]# vim /etc/sysctl.conf
 
net.ipv4.tcp_tw_reuse = 1
 
net.ipv4.tcp_tw_recycle = 1
 
net.ipv4.tcp_timestamps = 1
 
net.ipv4.tcp_syncookies = 1
 
net.ipv4.tcp_fin_timeout = 30

4 检查tomcat的连接数是否正常

发现tomcat 使用的是默认配置

tomcat默认最大连接数(线程数)200个,默认每一个连接的生命周期2小时(7200秒),tomcat使用http 1.1协议,而http1.1默认是长连接。tomcat接受处理完请求后,socket没有主动关闭,因此如果在2小时内,请求数超过200个,服务器就会出现上述假死现象

查看服务现线程使用情况

ps aux | grep tomcat
ps -T -p pid |wc -l

查看tomcat的配置server.xml,最大线程数是否跟环境匹配

<Connector port="8443" protocol="org.apache.coyote.http11.Http11AprProtocol"
               maxThreads="150" SSLEnabled="true" >
        <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
        <SSLHostConfig>
            <Certificate certificateKeyFile="conf/localhost-rsa-key.pem"
                         certificateFile="conf/localhost-rsa-cert.pem"
                         certificateChainFile="conf/localhost-rsa-chain.pem"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>

5 JVM内存溢出

当jvm无法为新的对象分配内存时,Gc无法回收一直被占用的内存,就会导致内存溢出OOM,使用命令分析 jstack jstat jmap jps

5.1 jstack查看tomcat是否出现死锁

jstack -F 进程ID
在thread dump中,要留意下面几种状态  死锁,
•  Deadlock(重点关注)  等待资源,
•  Waiting on condition(重点关注)  
•  等待获取监视器,Waiting on monitor entry(重点关注)  
•  阻塞,Blocked(重点关注) 
•  执行中,Runnable  
•  暂停,Suspended  
•  对象等待中,Object.wait() 或 TIMED_WAITING  
•  停止,Parked 
 

6. docker容器中只有jre没有相关工具

可以使用https://github.com/jattach/jattach 这个工具进行分析下载

先将jattach的 上传到宿主机 ,然后授权权限 ,复制到docker 容器中

chmod 777 jattach
docker cp jattach bam:/opt/java/openjdk/bin

到对应的目录下面

jattach 1 threaddump /home/bam/conf/threaddump.hprof
jattach 1 dumpheap /home/bam/conf/dumpheap.hprof

使用idea的工具分析 今日profile 上传hprof文件

在这里插入图片描述

或者使用 memory analyzer工具分析

在这里插入图片描述

Supported commands:
load : load agent library
properties : print system properties
agentProperties : print agent properties
datadump : show heap and thread summary
threaddump : dump all stack traces (like jstack)
dumpheap : dump heap (like jmap)
inspectheap : heap histogram (like jmap -histo)
setflag : modify manageable VM flag
printflag : print VM flag
jcmd : execute jcmd command

7 记问题排查

项目上反馈服务经常中断,出现访问不了的情况,一开始怀疑是网络问题,因为这个服务的部署在其他的项目上从没有出现过无法响应的问题,但是服务只要一重启就能恢复访问,项目上重启了很多次都是如此,

排查问题

1.查看单独访问tomcat的服务服务是否正常,发现不正常

2.还是怀疑是网络问题,直接本地服务器调用探活接口测试服务是否可用,接口返回不成功

3.日志还在打印第三方服务探活日志,说明tomcat的服务还是正常的,可能出现了tomcat的假死现象,但是服务不能正常提供

4.没有内存泄露的日志打印,top命令观察cpu和内存都是正常的,硬盘使用也是正常的

5.怀疑是第三方服务内置jar包在我们服务中回去调用他们的服务进行探活连接,没有关闭连接导致的,但是第三方服务在其他的项目上也部署了,没有问题,还是去查看服务器的连接数 ss -s发现只有100的连接剩余,但是只要剩余就能正常提供服务,于是查看tomcat的线程情况

ps -ef | grep java
ps -T -p |wc -l

发现tomcat的线程数有1400多,但是配置的tomcat的线程数才1000,于是就开始分析为什么会导致连接数被占满的情况,还是怀疑第三方服务没有释放连接,各种检查配置发现没有什么问题,这个时候联想到上午实施问后台有个接口大量报空指针的异常是否会影响这个问题,上午回复说只是空指针异常不会导致服务不可用的情况,

下午查看空指针异常的地方回退到对应的版本查看,发现空指针后,response写数据返回 流没有正常的关闭。 也正好服务项目经常一段时间后出现不可用的情况。

在 Java Servlet 中,如果响应对象的

close() 方法没有被调用,则连接不会被释放。这意味着,如果在 Servlet 中没有关闭响应,则连接将一直处于打开状态,直到连接超时。这可能会导致连接池中的连接用尽,从而导致应用程序停止响应。 因此,在编写 Servlet 代码时,应该始终确保在处理完请求后,关闭响应对象以释放连接。例如,使用

try-with-resources 块可以确保在使用完响应对象后,自动关闭响应对象,例如:

try (PrintWriter out = response.getWriter()) {
    // 处理响应输出
}

这个代码块中的

try 语句会自动关闭

PrintWriter 对象,在关闭之前,

PrintWriter 对象会将响应数据写入到响应对象中,然后响应对象将被关闭,以释放连接。 总的来说,确保在编写 Java Servlet 代码时关闭响应对象是一个重要的最佳实践,可以避免连接池中的连接用尽,从而提高应用程序的可靠性和性能

8 知乎案例

知乎地址

https://zhuanlan.zhihu.com/p/165995050

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值