多个节点在获取数据库中的任务时,会存在多个节点的同步获取而导致的任务多次处理情况。
因此,如果想要避免重复执行任务,必须找到合适的解决方案。
下面,主要介绍项目中用到的解决方案:
- 第一,假设存在一个任务uploadFileTask线程,专门用于上传文件,而文件路径及其信息存放在tb_upload_file_task表中。
- 第二,为了实现一个任务只被一个节点获取到,为任务表加入node_key字段,用于区别那个节点获取到当前的任务。
- 第三,每当一个任务节点获取到这个任务时,均更新任务表中的node_key.上面为任务表的设计(保证数据库支持行级锁),下面为避免多节点同时获取同一条任务的解决方案:
- 解决方案:加入一个中间表tb_persmtic_lock(专门用于获取任务时,被锁住的一个中间表),包含class_name,node_key等两个关键字段(这个表需要在每次新增任务时,新增UploadFileTask的class_name为UploadFileTask,node_key为空).
- 在获取任务时,同一个事务中,需要根据当前任务对象的class_name获取tb_persmtic_lock对应行的锁,并将node_key更新进去,这样如果node_key不为空时(另外一个相同的任务不会获取到这个锁),同时在任务表中获取一批任务数据,并更新这批数据的状态flag=1表示正在处理(假设任务只获取flag=0)的任务,获取完成后,将被锁的tb_persmtic_lock中的这个行释放掉锁,并更新node_key为空。即完成了多个节点同时获取一批任务的同步问题。
下面为流程图: