• 首页
  • 数据结构与算法
  • 设计模式
  • 网络与IO
  • 数据库
  • 关于
XXL JOB 执行器发生OOM


执行器配置

server.port=8080
server.address=192.168.101.5

logging.config=classpath:logback.xml

# 调度器地址
xxl.job.admin.addresses=http://192.168.101.5:8086/xxl-job-admin
xxl.job.accessToken=

xxl.job.executor.appname=item-service
xxl.job.executor.address=
# 执行器与调度器通信的地址
xxl.job.executor.ip=192.168.101.5
xxl.job.executor.port=9999
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
xxl.job.executor.logretentiondays=30
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;

@XxlJob("updateItem")
public void updateItem() throws Exception {

    logger.info("线程[" + Thread.currentThread().getName() + "]执行updateItem任务");

    logger.info("任务被执行...");
}



在调度中心配置执行器

配置任务



1.启动执行器
2.在调度中心启动任务
执行器端控制台输出信息如下

19:42:10.151 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 线程[Thread-8]执行updateItem任务
19:42:10.152 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 任务被执行...

19:42:40.028 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 线程[Thread-8]执行updateItem任务
19:42:40.028 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 任务被执行...

19:42:50.041 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 线程[Thread-8]执行updateItem任务
19:42:50.042 logback [Thread-8] INFO  c.x.j.e.s.jobhandler.SampleXxlJob - 任务被执行...



接下来, 调整执行器的启动参数

-Xms20M -Xmx20M


同时, 修改任务, 让执行该任务的线程睡眠, 模拟任务执行耗时久的假象

import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;

@XxlJob("updateItem")
public void updateItem() throws Exception {

    logger.info("线程[" + Thread.currentThread().getName() + "]执行updateItem任务");

    logger.info("任务被执行...");

    # 线程睡眠, 模拟任务执行耗时久
    Thread.sleep(1000_3600);

}


观察JVM内存, 老年代在增长, 经过一段时间, 发生OOM


执行器端控制台输出OOM异常信息

Exception in thread "xxl-rpc, EmbedServer bizThreadPool-519401859" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "logback-5" SLF4J: Failed toString() invocation on an object of type [java.lang.OutOfMemoryError]
Reported exception:
java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "logback-6" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "nioEventLoopGroup-3-3" Exception in thread "nioEventLoopGroup-2-1" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "Catalina-utility-4" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "Catalina-utility-5" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "Catalina-utility-7" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "logback-9" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "logback-4" java.lang.OutOfMemoryError: GC overhead limit exceeded
Exception in thread "Catalina-utility-6" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Catalina-utility-8" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Catalina-utility-11" java.lang.OutOfMemoryError: Java heap space
Exception in thread "Catalina-utility-10" java.lang.OutOfMemoryError: Java heap space


在执行器端程序还未发生OOM之前, 手动将堆空间Dump, 观察执行任务的线程(Thread-8)信息

上图只是JVM某一时刻的堆空间, 随着时间的推移, A指向的链表的长度会越来越长, B指向的数值会越来越大.
A指向的链表的每个节点元素都是调度中心发送的调度参数(TriggerParam), 如下图所示



解释:
调度中心会把调度信息发送给执行器端. 执行器端收到调度信息会把它放入一个 LinkedBlockingQueue<TriggerParam> triggerQueue 队列中. 执行器端的XXL-JOB线程(Thread-n)会从triggerQueue队列中取出调度信息并执行. 如果在执行某个调度任务的时候, 耗时很久, 就会导致triggerQueue队列中的任务越来越多, 且不会被GC回收, 存在OOM的风险.



链接: 分布式调度任务




Copyright © 2018-2025 书唐瑞

苏ICP备19037153号

[ 推演 整合 自愈 ]

[ 故障处理 优化 架构 ]