栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Linux下的JAVA程序CPU100%处理过程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux下的JAVA程序CPU100%处理过程

JAVA程序CPU100%的处理过程 1.问题描述

最近在使用xxl-job做定时计算处理,写了10个定时任务,基本都是1分钟执行一次,之前开发中数据量较少,执行过程中没有问题。随着项目的被迫落地(一些客观原因导致的,开发的程序还并未做好完整的测试),现场的基础数据开始录入,给定时任务做性能测试,将现场的数据导入到测试环境。xxl-job定时程序大概经过一天的时间运行,过程中会出现2个问题:1.部署的xxl-job定时任务项目主机cpu100%,2.用户使用的项目中查询数据经常timeout

2.问题分析

只要将xxl-job定时项目进行重启后,另一个部署的用户使用项目的问题就会得到暂时的处理。先到定时项目主机中查询问题。
1)显示进程运行信息列表,执行命令:

top


2) 显示一个进程的线程运行信息列表,执行命令:

top -Hp pid

3)找到占用cpu最高的线程,将线程ID转换为十六进制,执行命令:

printf "%xn" tid

4)查询线程堆栈信息,执行命令:

jstack pid|grep tid -A100

也可以直接将导出,执行命令:

jstack pid > tmp/pid.tdump

5)查询出的线程重点输出(部分省略):

"pool-8466-thread-4" #17372878 prio=5 os_prio=0 tid=0x0000000000758800 nid=0x6225 runnable [0x00007fe38c81e000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
	at java.net.SocketInputStream.read(SocketInputStream.java:171)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at okio.Okio$2.read(Okio.java:140)
	...
	at com.influxdb.client.internal.AbstractWriteClient$ToWritePointsMaybe$$Lambda$3385/1512828004.apply
	at com.influxdb.client.internal.WriteApiImpl.close(WriteApiImpl.java:216)
	at com.xxl.job.executor.core.util.influxDB.InfluxDataUtil.qry(InfluxDataUtil.java:80)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

cpu高的线程基本都是在查询influxdb,因为程序中查询数据的实时值和历史值都需要查询influxdb

6)定位代码,看看代码中是否存在问题,避免因为代码的原因导致cpu问题,发觉在写InfluxDataUtil工具类的时候,在创建InfluxDBClient时,可进行优化:

	
	public InfluxDBClient influxDbBuild() {
		if (null == client) {
			client = InfluxData.getInfluxData();
			//client = InfluxDBClientFactory.create(url, token.toCharArray());
		}
		return client;
	}

不需要频繁创建,用单例模式保证系统中只此一份:

public class InfluxData {

	private volatile static InfluxDBClient client;
	private InfluxData(){}
	public static InfluxDBClient getInfluxData() {

		if (client == null) {
			synchronized (InfluxData.class) {
				//通过SpringUtils获取到注入的bean对象
				QryValParam qryValParam = (QryValParam) SpringUtils.getBean("qryValConfigExecutor");
				String url = qryValParam.getUrl();
				String token = qryValParam.getToken();
				if (client == null) {
					client = InfluxDBClientFactory.create(url, token.toCharArray());
				}
			}
		}
		return client;
	}



}

改变代码后,重新上传后,还是未能改变多少,因为一次查询influxdb就是一次tcp连接,数据量大无法改变,定时任务中有大量TIME_WAIT的线程,通过以下命令可查出:

netstat -apn | grep 8086 | grep TIME_WAIT | wc -l

7)改变策略:因为定时中查询实时值比查询历史值更多,那么在现场采集数据的时候写入influxdb的同时,也将最新的数据插入到redis中,查询实时值从redis中,减轻influxdb的连接压力

存储在redis中数据大概只占用2M。修改项目中查询实时值的代码后,重新发布,定时工程运行2天后,暂未出现100%的情况,后续再跟进。。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/273470.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号