feat(sj_1.1.0): 优化客户端传递上下文
1. 客户端上报的上下文只上报add的值,不上报全量的值 2. sj_distributed_lock 分布式锁表去掉自增主键
This commit is contained in:
		
							parent
							
								
									aeaa73776f
								
							
						
					
					
						commit
						983f6006ec
					
				| @ -235,15 +235,13 @@ CREATE TABLE `sj_server_node` | |||||||
| 
 | 
 | ||||||
| CREATE TABLE `sj_distributed_lock` | CREATE TABLE `sj_distributed_lock` | ||||||
| ( | ( | ||||||
|     `id`         bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键', |  | ||||||
|     `name`       varchar(64)         NOT NULL COMMENT '锁名称', |     `name`       varchar(64)         NOT NULL COMMENT '锁名称', | ||||||
|     `lock_until` timestamp(3)        NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '锁定时长', |     `lock_until` timestamp(3)        NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '锁定时长', | ||||||
|     `locked_at`  timestamp(3)        NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '锁定时间', |     `locked_at`  timestamp(3)        NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '锁定时间', | ||||||
|     `locked_by`  varchar(255)        NOT NULL COMMENT '锁定者', |     `locked_by`  varchar(255)        NOT NULL COMMENT '锁定者', | ||||||
|     `create_dt`  datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |     `create_dt`  datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | ||||||
|     `update_dt`  datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', |     `update_dt`  datetime            NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', | ||||||
|     PRIMARY KEY (`id`), |     PRIMARY KEY (`name`) | ||||||
|     UNIQUE KEY `uk_name` (`name`) |  | ||||||
| ) ENGINE = InnoDB | ) ENGINE = InnoDB | ||||||
|   AUTO_INCREMENT = 0 |   AUTO_INCREMENT = 0 | ||||||
|   DEFAULT CHARSET = utf8mb4 COMMENT ='锁定表' |   DEFAULT CHARSET = utf8mb4 COMMENT ='锁定表' | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ package com.aizuda.snailjob.client.job.core.dto; | |||||||
| 
 | 
 | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import lombok.Data; | import lombok.Data; | ||||||
|  | import lombok.Getter; | ||||||
| 
 | 
 | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Objects; | import java.util.Objects; | ||||||
| @ -22,12 +23,22 @@ public class JobArgs { | |||||||
| 
 | 
 | ||||||
|     private Map<String, Object> wfContext; |     private Map<String, Object> wfContext; | ||||||
| 
 | 
 | ||||||
|  |     private Map<String, Object> changeWfContext; | ||||||
|  | 
 | ||||||
|     public void appendContext(String key, Object value) { |     public void appendContext(String key, Object value) { | ||||||
|         if (Objects.isNull(wfContext) || StrUtil.isBlank(key) || Objects.isNull(value)) { |         if (Objects.isNull(wfContext) || StrUtil.isBlank(key) || Objects.isNull(value)) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         wfContext.put(key, value); |         changeWfContext.put(key, value); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Object getWfContext(String key) { | ||||||
|  |         if (Objects.isNull(wfContext) || StrUtil.isBlank(key)) { | ||||||
|  |             return null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return wfContext.get(key); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -13,15 +13,16 @@ import com.aizuda.snailjob.client.model.ExecuteResult; | |||||||
| import com.aizuda.snailjob.common.core.enums.JobTaskTypeEnum; | import com.aizuda.snailjob.common.core.enums.JobTaskTypeEnum; | ||||||
| import com.aizuda.snailjob.common.core.enums.MapReduceStageEnum; | import com.aizuda.snailjob.common.core.enums.MapReduceStageEnum; | ||||||
| import com.aizuda.snailjob.common.core.model.JobContext; | import com.aizuda.snailjob.common.core.model.JobContext; | ||||||
| import com.aizuda.snailjob.common.core.util.JsonUtil; |  | ||||||
| import com.aizuda.snailjob.common.log.enums.LogTypeEnum; | import com.aizuda.snailjob.common.log.enums.LogTypeEnum; | ||||||
| import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||||
|  | import com.google.common.collect.Maps; | ||||||
| import com.google.common.util.concurrent.Futures; | import com.google.common.util.concurrent.Futures; | ||||||
| import com.google.common.util.concurrent.ListenableFuture; | import com.google.common.util.concurrent.ListenableFuture; | ||||||
| import com.google.common.util.concurrent.ListeningExecutorService; | import com.google.common.util.concurrent.ListeningExecutorService; | ||||||
| import com.google.common.util.concurrent.MoreExecutors; | import com.google.common.util.concurrent.MoreExecutors; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| 
 | 
 | ||||||
|  | import java.util.Map; | ||||||
| import java.util.concurrent.ThreadPoolExecutor; | import java.util.concurrent.ThreadPoolExecutor; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
| 
 | 
 | ||||||
| @ -45,6 +46,8 @@ public abstract class AbstractJobExecutor implements IJobExecutor { | |||||||
|         // 将任务添加到时间轮中,到期停止任务 |         // 将任务添加到时间轮中,到期停止任务 | ||||||
|         TimerManager.add(new StopTaskTimerTask(jobContext.getTaskBatchId()), jobContext.getExecutorTimeout(), TimeUnit.SECONDS); |         TimerManager.add(new StopTaskTimerTask(jobContext.getTaskBatchId()), jobContext.getExecutorTimeout(), TimeUnit.SECONDS); | ||||||
| 
 | 
 | ||||||
|  |         Map<String, Object> changeWfContext = Maps.newConcurrentMap(); | ||||||
|  | 
 | ||||||
|         // 执行任务 |         // 执行任务 | ||||||
|         ListenableFuture<ExecuteResult> submit = decorator.submit(() -> { |         ListenableFuture<ExecuteResult> submit = decorator.submit(() -> { | ||||||
|             JobArgs jobArgs; |             JobArgs jobArgs; | ||||||
| @ -63,6 +66,7 @@ public abstract class AbstractJobExecutor implements IJobExecutor { | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             jobArgs.setWfContext(jobContext.getWfContext()); |             jobArgs.setWfContext(jobContext.getWfContext()); | ||||||
|  |             jobArgs.setChangeWfContext(changeWfContext); | ||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
|                 // 初始化调度信息(日志上报LogUtil) |                 // 初始化调度信息(日志上报LogUtil) | ||||||
| @ -76,7 +80,7 @@ public abstract class AbstractJobExecutor implements IJobExecutor { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         FutureCache.addFuture(jobContext.getTaskBatchId(), submit); |         FutureCache.addFuture(jobContext.getTaskBatchId(), submit); | ||||||
|         Futures.addCallback(submit, new JobExecutorFutureCallback(jobContext), decorator); |         Futures.addCallback(submit, new JobExecutorFutureCallback(jobContext, changeWfContext), decorator); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void initLogContext(JobContext jobContext) { |     private void initLogContext(JobContext jobContext) { | ||||||
|  | |||||||
| @ -66,9 +66,11 @@ public class JobExecutorFutureCallback implements FutureCallback<ExecuteResult> | |||||||
|             }).build(); |             }).build(); | ||||||
| 
 | 
 | ||||||
|     private final JobContext jobContext; |     private final JobContext jobContext; | ||||||
|  |     private final Map<String, Object> changeWfContext; | ||||||
| 
 | 
 | ||||||
|     public JobExecutorFutureCallback(final JobContext jobContext) { |     public JobExecutorFutureCallback(final JobContext jobContext, Map<String, Object> changeWfContext) { | ||||||
|         this.jobContext = jobContext; |         this.jobContext = jobContext; | ||||||
|  |         this.changeWfContext = changeWfContext; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -163,9 +165,8 @@ public class JobExecutorFutureCallback implements FutureCallback<ExecuteResult> | |||||||
|         dispatchJobRequest.setRetry(jobContext.isRetry()); |         dispatchJobRequest.setRetry(jobContext.isRetry()); | ||||||
|         dispatchJobRequest.setRetryScene(jobContext.getRetryScene()); |         dispatchJobRequest.setRetryScene(jobContext.getRetryScene()); | ||||||
|         // 传递上下文 |         // 传递上下文 | ||||||
|         Map<String, Object> wfContext = jobContext.getWfContext(); |         if (CollUtil.isNotEmpty(changeWfContext)) { | ||||||
|         if (CollUtil.isNotEmpty(wfContext)) { |             dispatchJobRequest.setWfContext(JsonUtil.toJsonString(changeWfContext)); | ||||||
|             dispatchJobRequest.setWfContext(JsonUtil.toJsonString(wfContext)); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return dispatchJobRequest; |         return dispatchJobRequest; | ||||||
|  | |||||||
| @ -17,15 +17,10 @@ import java.time.LocalDateTime; | |||||||
| @TableName("sj_distributed_lock") | @TableName("sj_distributed_lock") | ||||||
| public class DistributedLock extends CreateUpdateDt { | public class DistributedLock extends CreateUpdateDt { | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 主键 |  | ||||||
|      */ |  | ||||||
|     @TableId(value = "id", type = IdType.AUTO) |  | ||||||
|     private Long id; |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * 锁名称 |      * 锁名称 | ||||||
|      */ |      */ | ||||||
|  |     @TableId(value = "name") | ||||||
|     private String name; |     private String name; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
| @ -168,6 +168,7 @@ public class WorkflowExecutorActor extends AbstractActor { | |||||||
|         Map<Long, Job> jobMap = StreamUtils.toIdentityMap(jobs, Job::getId); |         Map<Long, Job> jobMap = StreamUtils.toIdentityMap(jobs, Job::getId); | ||||||
| 
 | 
 | ||||||
|         // TODO 合并job task的结果到全局上下文中 |         // TODO 合并job task的结果到全局上下文中 | ||||||
|  |         // 此次的并发数与当时父节点的兄弟节点的数量一致 | ||||||
|          workflowBatchHandler.mergeWorkflowContextAndRetry(workflowTaskBatch, |          workflowBatchHandler.mergeWorkflowContextAndRetry(workflowTaskBatch, | ||||||
|             StreamUtils.toSet(allJobTaskBatchList, JobTaskBatch::getId)); |             StreamUtils.toSet(allJobTaskBatchList, JobTaskBatch::getId)); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -324,7 +324,7 @@ public class WorkflowBatchHandler { | |||||||
|      * 合并工作流上下文若合并失败先自旋3次1.5s, 若失败了升级到悲观锁 |      * 合并工作流上下文若合并失败先自旋3次1.5s, 若失败了升级到悲观锁 | ||||||
|      * |      * | ||||||
|      * @param workflowTaskBatch 工作流批次 |      * @param workflowTaskBatch 工作流批次 | ||||||
|      * @param taskBatchIds 批次列表 |      * @param taskBatchIds      批次列表 | ||||||
|      */ |      */ | ||||||
|     public void mergeWorkflowContextAndRetry(WorkflowTaskBatch workflowTaskBatch, Set<Long> taskBatchIds) { |     public void mergeWorkflowContextAndRetry(WorkflowTaskBatch workflowTaskBatch, Set<Long> taskBatchIds) { | ||||||
|         if (CollUtil.isEmpty(taskBatchIds)) { |         if (CollUtil.isEmpty(taskBatchIds)) { | ||||||
| @ -358,7 +358,7 @@ public class WorkflowBatchHandler { | |||||||
|             retryer.call(() -> mergeAllWorkflowContext(workflowTaskBatch, taskBatchIds)); |             retryer.call(() -> mergeAllWorkflowContext(workflowTaskBatch, taskBatchIds)); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             SnailJobLog.LOCAL.warn("update workflow global context error. workflowTaskBatchId:[{}] taskBatchIds:[{}]", |             SnailJobLog.LOCAL.warn("update workflow global context error. workflowTaskBatchId:[{}] taskBatchIds:[{}]", | ||||||
|                 workflowTaskBatch.getId(), taskBatchIds, e); |                     workflowTaskBatch.getId(), taskBatchIds, e); | ||||||
|             if (e.getClass().isAssignableFrom(RetryException.class)) { |             if (e.getClass().isAssignableFrom(RetryException.class)) { | ||||||
|                 // 如果自旋失败,就使用悲观锁 |                 // 如果自旋失败,就使用悲观锁 | ||||||
|                 distributedLockHandler.lockWithDisposableAndRetry(() -> { |                 distributedLockHandler.lockWithDisposableAndRetry(() -> { | ||||||
| @ -408,8 +408,8 @@ public class WorkflowBatchHandler { | |||||||
|         waitUpdateWorkflowTaskBatch.setWfContext(JsonUtil.toJsonString(mergeMap)); |         waitUpdateWorkflowTaskBatch.setWfContext(JsonUtil.toJsonString(mergeMap)); | ||||||
|         waitUpdateWorkflowTaskBatch.setVersion(1); |         waitUpdateWorkflowTaskBatch.setVersion(1); | ||||||
|         return 1 == workflowTaskBatchMapper.update(waitUpdateWorkflowTaskBatch, new LambdaQueryWrapper<WorkflowTaskBatch>() |         return 1 == workflowTaskBatchMapper.update(waitUpdateWorkflowTaskBatch, new LambdaQueryWrapper<WorkflowTaskBatch>() | ||||||
|             .eq(WorkflowTaskBatch::getId, workflowTaskBatch.getId()) |                 .eq(WorkflowTaskBatch::getId, workflowTaskBatch.getId()) | ||||||
|             .eq(WorkflowTaskBatch::getVersion, workflowTaskBatch.getVersion()) |                 .eq(WorkflowTaskBatch::getVersion, workflowTaskBatch.getVersion()) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 opensnail
						opensnail