问题背景

​ 早上才上班,测试就提了一个问题:"昨天所有批量任务都没有跑"。我看了一下任务监控页面,任务是有生成的,但却一直在等待调度状态。初步怀疑是我们的调度服务问题,于是上去查看调度服务日志。

​ 从日志上观察,发现没有调度日志。正常情况下即使没有任务,也会有日志输出,说明没有任务需要调度。于是怀疑调度线程没启动。

​ 说明一下背景:我们的调度服务主要由调度线程和任务线程组成,调度线程定时扫描任务表,发现有任务需要调度就启动任务线程处理。

初步定位问题

​ 查看代码,发现调度线程在spring bean初始化时启动的。 没有任何分支,理论上应该不可能没启动。

​ 回去查看日志,发现调度服务启动时,调度线程是有正常启动的。而且之后调度很正常,一直到昨天下午五点多之后突然就没有调度线程的日志了。

​ 这里突然想起来,昨天下午五点多的时候,测试做了压测,结果导致服务器都登录不上。(登录时提示:“fork: retry:资源不可用”)

​ 后来使用root登录后杀掉一些进程,才恢复正常。(linux会给root用户保留一些资源,方便管理员处理系统故障)

​ 当时检查,发现原来是最大进程数设置成1024,但我们服务器上部署了几个java服务,每个服务又开了很多线程。压测时线程数上升,导致系统资源耗尽。

​ 于是初步怀疑是当时资源耗尽引起调度线程的问题,但具体是怎么引起的,还需要再进一步确认。

确认问题

​ 先尝试使用jstack查看调度服务线程,想看一下是不是调度线程因为什么锁卡住了。输出结果发现一个奇怪的情况:调度线程不见了。

于是猜测:难道是昨天下午压测时资源不足,引起了调度线程出异常?(因为调度线程需要开启任务线程,任务线程因为当时系统资源不足,肯定开启失败)

​ 上网搜索了一下,发现其他人也碰上过类似情况。解决方法是增加Catch Throwable,这样可以防止线程退出。

​ 考虑到Catch Throwable可能导致虚拟机一些异常无法恢复,影响后续功能。我直接打印了日志退出。

问题复现与复测以及防止

​ 由于比较忙,没做复现。修改了代码让测试重新压测一下,发现问题没再发生。到此告一段落。

这次学习到了几个知识点:

1 java服务里面线程崩溃不会引起进程退出,这跟我以前写c++的经验是不一样的。

2 java的Error不是Exception的子类,只是捕获Exception不能防止线程因为出现OOM而退出

3 OOM包括了好多种情况,无法创建线程是其中一种。全部情况如下:

java.lang.OutOfMemoryError:Javaheap space

堆内存(Heap Space)没有足够空间存放新创建的对象

Java 进程花费 98% 以上的时间执行 GC,但只恢复了不到 2% 的内存,且该动作连续重复了 5 次

永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大

Metaspace 已被用满

JVM 向底层操作系统请求创建一个新的 native 线程时,如果没有足够的资源分配

所有可用的虚拟内存已被耗尽

操作系统OOM Killer关闭进程

程序请求创建的数组超过最大长度限制

Direct ByteBuffer超出限制,就会抛出

最新文章

  1. python中单引号,双引号,多引号区别
  2. au3 命令
  3. C#中两个日期类型相减得到天数
  4. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP
  5. 【剑指offer】判断二叉树是否为平衡二叉树
  6. SQL*Net more data from client
  7. SecureCRT连接vm中的ubuntu
  8. js获得url的参数
  9. poj1611 简单并查集
  10. 关于js优化和css优化
  11. linux C/C++开发环境搭建指南
  12. 中间件详解,Django复习
  13. [转] ADO.NET调用存储过程带输出参数或返回值
  14. js 正则表达式之环视结构
  15. Ubuntu18.04命令行连接WiFi
  16. Mybatis七(MBG 逆向工程)
  17. RabbitMQ在windows下的安装
  18. 从零开始学Linux系统(五)用户管理和权限管理
  19. animition动画的加入
  20. 你可能还会遇到无法启动mysql的错误

热门文章

  1. Day10_48_Map集合中的常用方法
  2. 805. Split Array With Same Average
  3. css选择器中:first-child 与 :first-of-type的区别
  4. 缓冲区溢出分析第08课:MS06-040漏洞研究——动态调试
  5. 手脱UPX3.91壳(练习)
  6. c# p/invoke 无法加载指定的dll 找不到指定的模块 解决方法
  7. 使用QT creator实现一个五子棋AI包括GUI实现(8K字超详细)
  8. Dubbo原理剖析 之 @DubboReference.version设置为*
  9. Mac使用brew搭建LNMP
  10. IOS Widget(5):小组件刷新机制