您在使用SchedulerX过程中会碰到一些问题。本文将介绍如何处理一些典型的使用问题。
机器繁忙
- 现象
在应用管理页面某个分组的操作列单击查看实例,连接实例面板中该机器的状态为繁忙。
- 可能的原因
- 机器的load5(负载)超过在创建任务分组时设置的阈值。
- 机器的内存使用率超过在创建任务分组时设置的阈值。
- 机器的磁盘使用率超过在创建任务分组时设置的阈值。
- 影响
机器状态为繁忙,将导致无法触发调度任务。
- 处理方法
- 在连接实例面板中,将光标放到繁忙上,查看机器的load5、内存使用率和磁盘使用率。
- 根据load5、内存使用率和磁盘使用率的值,确认繁忙的原因并进行相应的处理。例如清理磁盘、释放内存或负载。
如果处理之后,机器仍然繁忙,可以升级机器的配置。
如果只是用于测试,机器繁忙也想继续触发任务,可以在应用管理页面的操作列单击编辑,然后修改编辑应用分组面板中的高级配置,打开是否触发繁忙机器。
暂无可用机器
- 现象
当应用接入任务调度,通过连接机器验证是否成功时,弹出暂无可用机器的提示。
- 可能的原因
- 应用接入任务调度失败
- JAR包冲突
- SchedulerXWorker配置错误
- 处理方法
-
登录部署应用的ECS实例,查看是否存在日志目录/home/${user.home}/logs/schedulerx/worker.log。说明
- 如果是root账号启动的进程,日志在/root/logs/schedulerx/worker.log。
- 如果是admin账户启动的进程,日志在/home/admin/logs/schedulerx/worker.log。
- 如果不存在,说明ECS实例没有接入SchedulerX客户端,请重新接入,详情请参见Java应用接入SchedulerX、Spring应用接入SchedulerX或Spring Boot应用接入SchedulerX。
- 如果存在,进行下一步。
-
查看
worker.log
日志是否有异常日志。- 如果日志包含groupId is not existed,说明是配置问题。在worker.log里搜索Schedulerx WorkerConfig,可以看到当前的配置,然后和控制台对比、确认。
注意 namespace可以从命名空间页面的命名空间ID获取。
- 如果有异常日志,确认是否是JAR包冲突。详情请参见JAR包冲突。
- 如果没有异常日志,搜索“started”,检查SchedulerXWorker的配置是否正确。
- 如果日志包含groupId is not existed,说明是配置问题。在worker.log里搜索Schedulerx WorkerConfig,可以看到当前的配置,然后和控制台对比、确认。
-
JAR包冲突
- 现象
部署调度任务时,提示JAR包冲突。
- 可能的原因
JAR包冲突可能包含其中具体子包冲突的多种可能的原因。 可以在日志里搜一下maven dependencies,可以看到每个JAR的版本和路径,帮助快速定位和解决JAR包冲突,如下图。
- 处理方法
然后参照下表,升级低版本。
JAR包 版本 guava 20.0 com.typesafe.config 1.3.0 protobuf-java 2.6.1 io.netty 3.10.6.Final javaassist 3.21.0-GA hessian 4.0.51 commons-configuration 1.10 commons-validator 1.4.0 - 示例
下面列出几个典型的JAR冲突现象:
- guava冲突
- com.typesafe.config包冲突
- protobuf冲突
2019-03-20 14:49:41.742 [33471_69216-akka.actor.default-dispatcher-4] WARN com.alibaba.schedulerx.worker.SchedulerxWorker:315 - heartbeat error java.lang.VerifyError: class com.alibaba.schedulerx.protocol.Worker$WorkerHeartBeatRequest overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet; at java.lang.ClassLoader.defineClass1(Native Method) ~[?:1.8.0_181] at java.lang.ClassLoader.defineClass(ClassLoader.java:763) ~[?:1.8.0_181] at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[?:1.8.0_181]
- Netty冲突导致ActorSystem.create超时导致启动不起来
2019-03-20 11:52:48.030 [main] ERROR com.alibaba.schedulerx.worker.SchedulerxWorker:142 - Schedulerx Worker error java.util.concurrent.TimeoutException: Futures timed out after [10000 milliseconds] at scala.concurrent.impl.Promise$DefaultPromise.ready(Promise.scala:223) ~[scala-library-2.11.11.jar:?] at scala.concurrent.impl.Promise$DefaultPromise.result(Promise.scala:227) ~[scala-library-2.11.11.jar:?] at scala.concurrent.Await$$anonfun$result$1.apply(package.scala:190) ~[scala-library-2.11.11.jar:?] at scala.concurrent.BlockContext$DefaultBlockContext$.blockOn(BlockContext.scala:53) ~[scala-library-2.11.11.jar:?] at scala.concurrent.Await$.result(package.scala:190) ~[scala-library-2.11.11.jar:?] at akka.remote.Remoting.start(Remoting.scala:189) ~[akka-remote_2.11-2.4.20.jar:?] at akka.remote.RemoteActorRefProvider.init(RemoteActorRefProvider.scala:212) ~[akka-remote_2.11-2.4.20.jar:?] at akka.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:828) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:825) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystemImpl._start(ActorSystem.scala:825) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystemImpl.start(ActorSystem.scala:841) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystem$.apply(ActorSystem.scala:245) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystem$.apply(ActorSystem.scala:288) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystem$.apply(ActorSystem.scala:263) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystem$.create(ActorSystem.scala:191) ~[akka-actor_2.11-2.4.20.jar:?] at akka.actor.ActorSystem.create(ActorSystem.scala) ~[akka-actor_2.11-2.4.20.jar:?] at com.alibaba.schedulerx.worker.SchedulerxWorker.init(SchedulerxWorker.java:119) [schedulerx-worker-0.2.0.jar:?]
- Hessian冲突
java.lang.NoSuchMethodError: com.caucho.hessian.io.SerializerFactory.createDefault()Lcom/caucho/hessian/io/SerializerFactory;
- commons-validator冲突
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/validator/routines/InetAddressValidator at com.aliyun.openservices.log.util.NetworkUtils.getLocalMachineIP(NetworkUtils.java:33) ~[aliyun-log-0.6.31.jar:?] at com.aliyun.openservices.log.Client.<init>(Client.java:250) ~[aliyun-log-0.6.31.jar:?] at com.aliyun.openservices.aliyun.log.producer.ProjectConfigs.buildClient(ProjectConfigs.java:34) ~[aliyun-log-producer-0.2.0.jar:?] at com.aliyun.openservices.aliyun.log.producer.ProjectConfigs.put(ProjectConfigs.java:13) ~[aliyun-log-producer-0.2.0.jar:?] at com.alibaba.schedulerx.worker.logcollector.SlsLogCollector.<init>(SlsLogCollector.java:64) ~[schedulerx-worker-1.0.3.jar:?] at sun.reflect.GeneratedConstructorAccessor156.newInstance(Unknown Source) ~[?:?] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_161] at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_161] at com.alibaba.schedulerx.common.util.ReflectionUtil.newInstance(ReflectionUtil.java:31) ~[schedulerx-common-1.0.2.jar:?]
- javaassist冲突
- httpclient冲突
tablestore protobuf-2.4.1和SchedulerX不兼容
详情请参见使用Java SDK时出现PB库冲突。
Spring应用找不到Bean
- 现象
Spring应用找不到对应的Bean。
- 可能的原因
- 接入方式不正确。
- JobProcessor中未注入Bean。
- pom.xml中添加了
spring-boot-devtools
依赖。 - 在JobProcessor和process方法中添加了事务注解。
- bean被其他切面代理。
- classLoader不一致。
- 处理方法
- 在应用管理页面该分组的操作列单击连接机器,连接机器面板中查看启动方式是否为Spring或Spring Boot。
如果启动方式不是Spring或Spring Boot,请检查您的应用。
- 检查应用代码中是否将JobProcessor注入为Bean,例如添加了@Component注解。
如果JobProcessor没有注入为Bean,请将JobProcessor注入为Bean。
- 检查pom.xml中是否添加了
spring-boot-devtools
。如果pom.xml中添加了
spring-boot-devtools
,请删除spring-boot-devtools
依赖。 - 检查JobProcessor和process方法中是否添加了事务注解。
在JobProcessor和process方法中添加了事务注解,请删除注解。
- 检查bean列表是否被其他切面代理。
把断点打到DefaultListableBeanFactory类,检查beanDefinitionNames成员列表(即是spring注册的bean列表)是否被其他切面代理。
如果bean列表被其他切面代理,请删除代理。
- 调试ThreadContainer.start,查看是否报class.forName错。
如果是报class.forName错,但是class又真实存在,可以确定是classLoader的问题,可能是您使用了某框架导致classLoader不一致。请通过SchedulerxWorker.setClassLoader解决。
如果以上方法都未能解决问题,请联系SchedulerX技术支持人员。
- 在应用管理页面该分组的操作列单击连接机器,连接机器面板中查看启动方式是否为Spring或Spring Boot。
tablestore protobuf-2.4.1和SchedulerX不兼容
submit jobInstanceId to worker timeout
- 现象
submit jobInstanceId=28384771 to worker=WorkerInfo [ip=192.168.32.166, port=41114, workerId=30574_7365, metrics=Metrics(cpuLoad1=0.01, cpuLoad5=0.05600000000000001, cpuProcessors=2, heap1Usage=0.20147679324894516, heap5Usage=0.20379746835443036, heap1Used=191, heapMax=948, diskUsage=0.24241670191853087, diskUsed=9742, diskMax=40187)] timeout, cost=5004ms
- 可能的原因
- JAR包冲突
- 机器负载过高或者重启
- 解决办法
查看worker.log中有没有异常日志。
- 如果有,可能是JAR包冲突,处理详情请参见JAR包冲突。
- 如果没有,可能是机器负载过高或者重启造成的,请检查机器。
重启应用后,任务卡住
- 现象
应用发布没问题,通过Aone重启应用,任务会卡住。
- 可能的原因
如果启动进程的系统环境变量为
user.dir="/"
,但是启动进程的账号不是root,会造成SchedulerX底层消息通知失败。原因是没有权限写akka.persistence.snapshot目录。 - 解决办法
将SchedulerX升级到1.0.9-hotfix-v3及以上版本。
任务运行中卡住
- 现象
调度任务一直处于执行中,不能结束。
- 可能的原因
- 业务的问题
- SchedulerX的问题
- 解决方法
schedulerx-worker
执行每个processor的时候会把任务实例ID放到线程名中,方便查看线程栈。这里以分布式任务某个子任务卡住为例,单机执行/广播执行类似的解决方法类似。- 在控制台执行列表页面查看卡住的任务实例的详情,获取实例ID。
- 登录卡住的机器,执行jstack [pid] | grep [实例id] -A 20,查看线程栈。
- 如果执行结果和下图相似,说明是业务的问题。
- 否则,请联系SchedulerX技术支持人员。
报slf4j.Slf4jMDC异常
- 现象
- 解决方法
排除掉schedulerx2.0依赖的slf4j。
org.apache.commons.logging.impl.LogFactoryImpl类找不到问题
背景
Schedulerx2.0启动时会按一定策略查找LogFactory
的实现类,其中的一个策略是扫描配置文件META-INF/services/org.apache.commons.logging.LogFactory,该配置文件的第一行会定义LogFactory
的实现类名。
现象示例
com.taobao.common.division:common-division:3.0.28
依赖的com.alibaba.common.logging:toolkit-common-logging:1.0
这个JAR包下有一个配置文件META-INF/services/org.apache.commons.logging.LogFactory,该配置文件中声明了LoggerFactory的实现类com.alibaba.common.logging.spi.GenericLoggerFactory
;该实现类依赖了org.apache.commons.logging.impl.LogFactoryImpl
这个具体实现类,而具体实现类是由commons-logging
这个三方包提供的,如果应用排除掉了这个三方包,那么就会遇到java.lang.ClassNotFoundException
的问题。
RAM用户无权限进行应用管理
- 现象
以RAM用户登录控制台,单击应用管理,提示没有权限。
- 解决办法
使用阿里云账号为该RAM用户添加自定义权限,权限内容如下:
{ "Version": "1", "Statement": [ { "Action": "ram:ListUsers", "Resource": "*", "Effect": "Allow" } ] }