1.原理
弹性分布式:
1) 任务上线时会自动将服务器信息注册到注册中心,下线会自动更新服务器状态
2) 每次分片都会按服务器ip排序
注册中心:
1) 注册中心在定义的命名空间下,创建作业名称节点,用于区分不同作业,作业一旦创建则不能修改作业名称,修改名称视为新的作业
作业名称节点包含:
config节点:作业配置信息
instances节点:作业运行实例信息
sharding节点:作业分片信息
servers节点:作业服务器信息
leader节点:作业服务器主节点信息
作业启动:
作业执行:
2.使用
Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务;
Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能。
作业类型:
(1) Simple:简单作业,常用, 意为简单实现,未经任何封装的类型。需实现SimpleJob接口。
该接口仅提供单一方法用于覆盖,此方法将定时执行。与Quartz原生接口相似,但提供了弹性扩缩容和分片等功能
public class MyElasticJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
switch (context.getShardingItem()) { //分片数
case 0:
// do something by sharding item 0
break;
case 1:
// do something by sharding item 1
break;
case 2:
// do something by sharding item 2
break;
// case n: ...
}
}
}
(2)DataFlow:Dataflow类型用于处理数据流,需实现DataflowJob接口。
该接口提供2个方法可供覆盖,分别用于抓取(fetchData)和处理(processData)数据
public class MyElasticJob implements DataflowJob<Foo> {
@Override
public List<Foo> fetchData(ShardingContext context) { //数据获取
switch (context.getShardingItem()) {
case 0:
List<Foo> data = // get data from database by sharding item 0
return data;
case 1:
List<Foo> data = // get data from database by sharding item 1
return data;
case 2:
List<Foo> data = // get data from database by sharding item 2
return data;
// case n: ...
}
}
@Override
public void processData(ShardingContext shardingContext, List<Foo> data) { //处理数据
// process data
// ...
}
}
(3) Script:Script类型作业意为脚本类型作业,支持shell,python,perl等所有类型脚本。
自定义异常,以及监听器使用
<job:simple id="syncCheckResultJob" class="dsp.ps.qcm.task.job.SyncCheckResultJob" registry-center-ref="regCenter" cron="0 0 */1 * * ?" sharding-total-count="1" description="平台验收结果同步" job-exception-handler="dsp.ps.qcm.task.exception.ElasticJobException" overwrite="true">
<job:listener class="dsp.ps.qcm.task.listener.MessageElasticJobListener"></job:listener>
</job:simple>
//监听
public class MessageElasticJobListener implements ElasticJobListener
{
@Override
public void beforeJobExecuted(ShardingContexts shardingContexts)
{
System.out.println("=====================start");
}
@Override
public void afterJobExecuted(ShardingContexts shardingContexts)
{
System.out.println("=====================end");
}
}
//自定义异常
public class ElasticJobException implements JobExceptionHandler
{
@Override
public void handleException(String jobName, Throwable cause)
{
System.out.println("==============================job:" + jobName + ",cause:" + cause);
LogUtils.logger()
.error("==============================jobName:{},cause = {}", jobName, cause);
}
}
3.问题
(1)elastic-job的使用限制
i:作业启动成功后修改作业名称视为新作业,原作业废弃
ii:同一台作业服务器可以运行多个相同的作业实例,但每个作业实例必须使用不同的JobInstanceId,因为作业运行时是按照IP和JobInstanceId注册和管理的。JobInstanceId可在作业配置中设置
iii:一旦有服务器波动,或者修改分片项,将会触发重新分片;触发重新分片将会导致运行中的流式处理的作业在执行完本次作业后不再继续执行,等待分片结束后再恢复正常。
iv:开启monitorExecution才能实现分布式作业幂等性(即不会在多个作业服务器运行同一个分片)的功能,但monitorExecution对短时间内执行的作业(如每5秒一触发)性能影响较大,建议关 闭并自行实现幂等性。
(2)在代码或Spring配置文件中修改了作业配置,注册中心配置却没有更新
Elastic-Job-Lite采用无中心化设计,若每个客户端的配置不一致,不做控制的话,最后一个启动的客户端配置将会成为注册中心的最终配置.overwrite=true即允许客户端配置覆盖注册中心,反之则不允许。如果注册中心无相关作业的配置,则无论overwrite是否配置,客户端配置都将写入注册中心
(3)在2.0.6之前的版本中,网络不稳定的环境下Elastic-Job有可能有的作业分片并未执行,重启一下就能修复。
在2.0.6,版本中Elastic-Job在提供reconcileIntervalMinutes设置修复状态服务执行间隔分钟数,用于修复作业服务器不一致状态,默认每10分钟检测并修复一次。
(4)执行重复问题
检查是否配置了失效转移,如果在任务执行过程中有一个执行实例挂了,那么之前被分配到这个实例的任务(或者分片)会在下次任务执行之前被重新分配到其他正常节点实例上执行
弹性分布式:
1) 任务上线时会自动将服务器信息注册到注册中心,下线会自动更新服务器状态
2) 每次分片都会按服务器ip排序
注册中心:
1) 注册中心在定义的命名空间下,创建作业名称节点,用于区分不同作业,作业一旦创建则不能修改作业名称,修改名称视为新的作业
作业名称节点包含:
config节点:作业配置信息
instances节点:作业运行实例信息
sharding节点:作业分片信息
servers节点:作业服务器信息
leader节点:作业服务器主节点信息
作业启动:
作业执行:
2.使用
Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务;
Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能。
作业类型:
(1) Simple:简单作业,常用, 意为简单实现,未经任何封装的类型。需实现SimpleJob接口。
该接口仅提供单一方法用于覆盖,此方法将定时执行。与Quartz原生接口相似,但提供了弹性扩缩容和分片等功能
public class MyElasticJob implements SimpleJob {
@Override
public void execute(ShardingContext context) {
switch (context.getShardingItem()) { //分片数
case 0:
// do something by sharding item 0
break;
case 1:
// do something by sharding item 1
break;
case 2:
// do something by sharding item 2
break;
// case n: ...
}
}
}
(2)DataFlow:Dataflow类型用于处理数据流,需实现DataflowJob接口。
该接口提供2个方法可供覆盖,分别用于抓取(fetchData)和处理(processData)数据
public class MyElasticJob implements DataflowJob<Foo> {
@Override
public List<Foo> fetchData(ShardingContext context) { //数据获取
switch (context.getShardingItem()) {
case 0:
List<Foo> data = // get data from database by sharding item 0
return data;
case 1:
List<Foo> data = // get data from database by sharding item 1
return data;
case 2:
List<Foo> data = // get data from database by sharding item 2
return data;
// case n: ...
}
}
@Override
public void processData(ShardingContext shardingContext, List<Foo> data) { //处理数据
// process data
// ...
}
}
(3) Script:Script类型作业意为脚本类型作业,支持shell,python,perl等所有类型脚本。
自定义异常,以及监听器使用
<job:simple id="syncCheckResultJob" class="dsp.ps.qcm.task.job.SyncCheckResultJob" registry-center-ref="regCenter" cron="0 0 */1 * * ?" sharding-total-count="1" description="平台验收结果同步" job-exception-handler="dsp.ps.qcm.task.exception.ElasticJobException" overwrite="true">
<job:listener class="dsp.ps.qcm.task.listener.MessageElasticJobListener"></job:listener>
</job:simple>
//监听
public class MessageElasticJobListener implements ElasticJobListener
{
@Override
public void beforeJobExecuted(ShardingContexts shardingContexts)
{
System.out.println("=====================start");
}
@Override
public void afterJobExecuted(ShardingContexts shardingContexts)
{
System.out.println("=====================end");
}
}
//自定义异常
public class ElasticJobException implements JobExceptionHandler
{
@Override
public void handleException(String jobName, Throwable cause)
{
System.out.println("==============================job:" + jobName + ",cause:" + cause);
LogUtils.logger()
.error("==============================jobName:{},cause = {}", jobName, cause);
}
}
3.问题
(1)elastic-job的使用限制
i:作业启动成功后修改作业名称视为新作业,原作业废弃
ii:同一台作业服务器可以运行多个相同的作业实例,但每个作业实例必须使用不同的JobInstanceId,因为作业运行时是按照IP和JobInstanceId注册和管理的。JobInstanceId可在作业配置中设置
iii:一旦有服务器波动,或者修改分片项,将会触发重新分片;触发重新分片将会导致运行中的流式处理的作业在执行完本次作业后不再继续执行,等待分片结束后再恢复正常。
iv:开启monitorExecution才能实现分布式作业幂等性(即不会在多个作业服务器运行同一个分片)的功能,但monitorExecution对短时间内执行的作业(如每5秒一触发)性能影响较大,建议关 闭并自行实现幂等性。
(2)在代码或Spring配置文件中修改了作业配置,注册中心配置却没有更新
Elastic-Job-Lite采用无中心化设计,若每个客户端的配置不一致,不做控制的话,最后一个启动的客户端配置将会成为注册中心的最终配置.overwrite=true即允许客户端配置覆盖注册中心,反之则不允许。如果注册中心无相关作业的配置,则无论overwrite是否配置,客户端配置都将写入注册中心
(3)在2.0.6之前的版本中,网络不稳定的环境下Elastic-Job有可能有的作业分片并未执行,重启一下就能修复。
在2.0.6,版本中Elastic-Job在提供reconcileIntervalMinutes设置修复状态服务执行间隔分钟数,用于修复作业服务器不一致状态,默认每10分钟检测并修复一次。
(4)执行重复问题
检查是否配置了失效转移,如果在任务执行过程中有一个执行实例挂了,那么之前被分配到这个实例的任务(或者分片)会在下次任务执行之前被重新分配到其他正常节点实例上执行