java 线程栈分析_记一次Java线程堆栈分析

最近系统偶尔出现无法登陆,不能响应请求的情况。

上服务器使用Jps,Jstack将线程堆栈信息输出到文件里面,然后从服务器上把文件取下来通过fastthread.io把文件上传分析。

不得不说用这个网址分析方便了很多,不然几百个线程看得头皮发麻。

9586a1e3fa57588877c68ad0a134b1e3.png

可以看到300多个线程在WAITING状态。

随便点一个进去看看

ed01691942b8566f3f39d17ea2af07d3.png

基本上300多个等待的线程都很类似,都是在等数据库连接。

这些个线程的源头一半是系统定时任务,一半是接口调用的关于角色的Spring Security权限验证。

系统中Tomcat最大线程配置的500,但是数据库连接池的最大连接数配置的80.

可是系统对外开放的接口并没有角色的限制。没办法只看看系统中Spring Security的配置,发现现在的配置是判断有没有角色限制是通过数据库验证的(通过修改FilterSecurityInterceptor的securityMetadataSource)。这个配置就是不管什么请求,都会去数据取对应请求地址的需要的角色。其他请求倒是没啥事,毕竟没几个人用,但是对外的那个接口就不一样了。所以把这里这个没用的验证去掉。

另外定时任务每分钟跑一次,还是使用@Async异步的,使用的默认的线程池,无限开线程,线程存活时间还长,这谁顶得住呀。所以定时任务这里应该改成@Async(自定义的线程池)。

然而事情并不是这么简单,上面的做法只是在数据库连接池拿不到连接的时候,减少等待连接的线程,关键问题还是要找到占用连接的线程。

首先,我开启了druid的监控。

spring.datasource.druid.web-stat-filter.enabled=true

spring.datasource.druid.stat-view-servlet.enabled=true

复制代码然后意外的发现目前removeAbandoned设置的false,将其改为true

spring.datasource.druid.removeAbandoned=true

复制代码

改完之后就发现了有些任务出现了connection holder is null的错误。

这说明那些任务很长时间内都需要操作数据库,在连接池回收之后提交事务倒是出现异常。

最后从代码里发现,定时任务的所有操作都在一个事务里,一个任务几十分钟,长于removeAbandonedTimeout的时间,所以出问题了。所以,定时的大粒度事务应该去掉。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值