首先我们最初的业务就是使用任务调度xxl处理内容管理服务中的消息表中的数据,完成消息表中的任务,将课程信息插入到redis,elasticsearch Minio 但是我们要怎么实现这个消息服务呢,还是像3我们之前视频处理任务一样,在本微服务上定义一个任务调度的方法,然后只执行本微服务中的特定任务需求,这样明显扩展性不强。因此我们向要将她独立出来。
正如上图所述,我们可能不仅仅内容管理服务要实现任务调度,其他微服务可能也要实现任务调度,当然我们这里的任务调度主要是为了实现数据的最终一致性。
所以我要将消息处理服务单独抽取出来一个SDK(其实就是一个资源文件本身不能执行)然后其他微服务可以依赖这个SDK这样就能实现消息处理的扩展性要求。
最终抽取得SDK我会上传文件上。
对于SDK任务的设计如下细节需要注意和考虑
下边对消息SDK的设计内容进行说明:
sdk需要提供执行任务的逻辑吗?
拿课程发布任务举例,执行课程发布任务是要向redis、索引库等同步数据,其它任务的执行逻辑是不同的,所以执行任务在sdk中不用实现任务逻辑,只需要提供一个抽象方法由具体的执行任务方去实现。
如何保证任务的幂等性?
我们之前使用了状态字段进行解决
在视频处理章节介绍的视频处理的幂等性方案,这里可以采用类似方案,任务执行完成后会从消息表删除,如果消息的状态是完成或不存在消息表中则不用执行。
如何保证任务不重复执行?
我们之前使用了乐观锁进行解决 但是这里不需要了(出现任务重复执行情况就是执行器宕机然后其他执行器重新编号导致重复执行任务)因为之前的视频处理任务耗费CPU要使用乐观锁防止再次执行,现在的上传任务没有很耗费CPU*(所以不用开启任务进行抢锁了,也就是更改状态字段。乐观锁部分请看文档或者博客)当然如果想增加性能还是可以加的。
采用和视频处理章节一致方案,除了保证任务的幂等性外,任务调度采用分片广播,根据分片参数去获取任务,另外阻塞调度策略为丢弃任务。
注意:这里是信息同步类任务,即使任务重复执行也没有关系,不再使用抢占任务的方式保证任务不重复执行。
还有一个问题,根据消息表记录是否存在或消息表中的任务状态去保证任务的幂等性,如果一个任务有好几个小任务,比如:课程发布任务需要执行三个同步操作:存储课程到redis、存储课程到索引库,存储课程页面到文件系统。如果其中一个小任务已经完成也不应该去重复执行。这里该如何设计?
将小任务作为任务的不同的阶段,在消息表中设计阶段状态。
每完成一个阶段在相应的阶段状态字段打上完成标记,即使这个大任务没有完成再重新执行时,如果小阶段任务完成了也不会重复执行某个小阶段的任务。