问题描述:

业务是从kafka读取时序数据进行解析和封装后再放入kafka进入下一个 流程,在系统运行一段时间后,吞吐量下降导致kafka数据堆积,后续实时数据展示异常。

问题分析:

基于arthas进行监控,使用dashboard对基础状态进行分析

eden随着系统运行会把堆内存拉高到16G,应该是GC时间过长,导致吞吐量下降。

对GC时间问题进行处理:

-XX:+UnlockExperimentalVMOptions

-XX:+UseG1GC

-XX:G1HeapRegionSize=16m

-XX:ParallelGCThreads=12

-XX:G1MaxNewSizePercent=70

使用G1GC,提高并发线程,提高eden的空间占比70%

对堆内存进行限制:

-Xmx3g

-Xms3g

设置初始值和最大值,防止堆内存扩张到默认的16G,使用过大的空间。

这部分内存占用需要根据实际情况进行多次调整到合适的情况。

程序内异常情况:

基于arthas的dashboard监控,发现业务线程运行异常,产生TIMED_WAITING情况。

通过 thread <线程ID> 进行捕捉发现在代码中有 kafka.producer.close()的使用

每次发送都会新建一个生产者然后关闭这个生产者

默认情况下kafka的send是异步的,在调用close()后会阻塞线程等待消息发送完成,从而影响到整个程序的吞吐量。

通过改善这段代码,创建生产者单例进行复用,对这部分内容进行优化后,业务线程持续处于RUNNABLE状态,暂未发现问题。