解决了一个java服务线程退出的问题
问题背景
早上才上班,测试就提了一个问题:"昨天所有批量任务都没有跑"。我看了一下任务监控页面,任务是有生成的,但却一直在等待调度状态。初步怀疑是我们的调度服务问题,于是上去查看调度服务日志。
从日志上观察,发现没有调度日志。正常情况下即使没有任务,也会有日志输出,说明没有任务需要调度。于是怀疑调度线程没启动。
说明一下背景:我们的调度服务主要由调度线程和任务线程组成,调度线程定时扫描任务表,发现有任务需要调度就启动任务线程处理。
初步定位问题
查看代码,发现调度线程在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超出限制,就会抛出
解决了一个java服务线程退出的问题的更多相关文章
- 停止一个java的线程执行
找了一个停止线程运行的方法,代码如下: public class stopThread extends Thread { private volatile boolean stop = false; ...
- 记一次生产事故的排查与优化——Java服务假死
一.现象 在服务器上通过curl命令调用一个Java服务的查询接口,半天没有任何响应.关于该服务的基本功能如下: 1.该服务是一个后台刷新指示器的服务,即该服务会将用户需要的指示器数据提前计算好,放入 ...
- Java服务,内存OOM问题如何快速定位? (转)
转自:公众号 架构师之路 问题:有一个Java服务出现了OOM(Out Of Memory)问题,定位了好久不得其法,请问有什么好的思路么? OOM的问题,印象中之前写过,这里再总结一些相对通用的方 ...
- Docker学习6:使用docker构建Jekyll服务和java服务
写在前面 ## 文章Dockerfile中涉及apt-get 等操作需更换镜像 在Dockerfile中添加下列 Dockerfile源码,见下面作者githubhttps://github.com/ ...
- java中如何使正在运行中的线程退出
终止线程的三种方法 有三种方法可以使终止线程. 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2. 使用stop方法强行终止线程(这个方法不 ...
- 用Java开发一个本地服务管理软件
一.最终界面先贴上最终效果图,图1为初始化界面,图二为点击启动/停止之后的中间过渡状态,图三为启动成功后弹出的提示框 把动态gif图片嵌入到jpg背景图中?用Adobe ImageReady即可办到 ...
- Java多线程-----线程安全及解决机制
1.什么是线程安全问题? 从某个线程开始访问到访问结束的整个过程,如果有一个访问对象被其他线程修改,那么对于当前线程而言就发生了线程安全问题: 如果在整个访问过程中,无一对象被其他线程修改,就是线程安 ...
- JAVA的StringBuffer类(转载整理)____非常重要的一个类,线程安全,不用每次创建一个对象,以及和String的区别
核心部分转载自:http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html StringBuffer类和String一样,也用来代 ...
- java 使用线程做一个简单的ATM存取款实例.(转)
线程 Thread 类,和 Runable 接口 比较两者的特点和应用领域. 可以,直接继承线程Thread类.该方法编写简单,可以直接操作线程,适用于单重继承情况,因而不能在继承其他类 实现Runn ...
随机推荐
- 记一次 .NET WPF布草管理系统 挂死分析
一:背景 1. 讲故事 这几天看的 dump 有点多,有点伤神伤脑,晚上做梦都是dump,今天早上头晕晕的到公司就听到背后同事抱怨他负责的WPF程序挂死了,然后测试的小姑娘也跟着抱怨...嗨,也不知道 ...
- 1076 Forwards on Weibo
Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may ...
- hdu1529 差分约束(好题)
题意: 超市在每个时间都有需要的人数(24小时)比如 1 0 0 0 0 ....也就是说在第0个小时的时候要用一个人,其他的时间都不用人,在给你一些人工作的起始时间,如果雇佣了这个人,那 ...
- hdu4291 暴力循环节+矩阵快速幂
题意: 给你一个关系式,x[n] = 3*x[n-1] + x[n-2],求x(x(x[n]))%1000000007. 思路: 做这个题目要明确一点,就是对于取余操作大多数时 ...
- Docker安装和helloworld
0.基本简介(想直接实操,直接跳过去看1就好) Docker 在容器的基础上,进行了进一步的封装,从文件系统.网络互联到进程隔离等等,极大的简化了容器的创建和维护.使得 Docker 技术比虚拟机技术 ...
- Swift系列五 - 可选项
可选项,一般也叫可选类型,它允许将值设为nil. 一.定义可选项 平时开发中,如果我们需要把一个变量置空时只需要把变量赋值一个nil即可: 上面尝试后不行,那怎么把一个变量置空呢? 答案:把变量设置可 ...
- JVM默认内存大小
堆(Heap)和非堆(Non-heap)内存 按照官方的说法:"Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在Java虚拟机启动时创建的." ...
- linux中定时运行php(每分钟执行一次为例)
注:使用Crontab定时执行php脚本文件 1. 安装crontab yum install crontabs 说明:/sbin/service crond start //启动服务/sbin/se ...
- 15 个让新手爱不释手的 Python 高级库
为什么我喜欢 Python ? 对于初学者来说,这是一种简单易学的编程语言:另一个原因:大量开箱即用的第三方库,正是 23 万个由用户提供的软件包使得 Python 真正强大和流行 在本文中,我挑选了 ...
- Spring Cloud Alibaba(8)---Feign服务调用
Feign服务调用 有关Spring Cloud Alibaba之前写过五篇文章,这篇也是在上面项目的基础上进行开发. Spring Cloud Alibaba(1)---入门篇 Spring Clo ...