一种基于内存实现分布式重试调度的方法转让专利

申请号 : CN202310515644.3

文献号 : CN116225724B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 张兴俊

申请人 : 云筑信息科技(成都)有限公司

摘要 :

本发明公开了一种基于内存实现分布式重试调度的方法,属于计算机技术领域,本发明提供了一种基于内存实现分布式重试调度的方法,支持事务表录入分布式事务失败前后的上下文信息,实现指定业务异常重试;通过内存任务定时调度实现分布式重试调度,并且支持指定重试次数和最大重试次数;采用随机的重试间隔,减少重试时的下游系统压力,实现重试退避和随机退避。

权利要求 :

1.一种基于内存实现分布式重试调度的方法,其特征在于,包括以下步骤:

步骤1、请求事务,执行事务,若事务执行失败,对事务进行内存重试,内存重试仍为失败,将内存重试失败的事务设定为重试事务;

步骤2、创建事务表和数据库锁表,监听重试事务的上下文信息,将上下文信息生成唯一约束字段并作为主键保存至事务表;

步骤3、将唯一约束字段作用于数据库锁表,完成加锁;查询事务表,基于数据库锁表提取重试事务的执行数据,采用定时器对重试事务发起重试;

步骤4、重试执行成功,更新事务表的执行状态为成功,结束流程;重试执行失败,更新下次重试的执行时间,重复步骤3 步骤4,直至重试执行成功,更新事务表的执行状态为成~功,结束流程;

重试事务的上下文信息至少包括事务接口方法、事务接口方法的参数、以及事务执行时的上下文;

所述步骤3包括:步骤31,当在最大重试次数以内时,将唯一约束字段作用于数据库锁表进行主键索引,调用数据库连接驱动程序连接数据库并插入执行数据;步骤32,如果插入执行数据失败代表获取锁失败,则等待定时器下一次的重试调度;如果插入执行数据成功代表获取锁成功,则等待定时器本次的重试调度;步骤33,重试调度前预先在事务表的事务接口方法上插入重试注解,开始执行重试时,检查事务接口方法是否有该重试注解,有重试注解则自动执行重试。

2.根据权利要求1所述的一种基于内存实现分布式重试调度的方法,其特征在于,在所述步骤2中,将事务接口方法、事务接口方法的参数、事务执行时的上下文分别生成对应的唯一约束字段,将各唯一约束字段作为主键保存至事务表。

3.根据权利要求1所述的一种基于内存实现分布式重试调度的方法,其特征在于,重试事务每次执行失败时,都会抛出对应的错误异常信息,重试注解基于错误异常信息实现,实现后重试注解加在重试事务的事务接口方法上。

4.根据权利要求1所述的一种基于内存实现分布式重试调度的方法,其特征在于,唯一约束字段采用哈希生成。

5.根据权利要求1所述的一种基于内存实现分布式重试调度的方法,其特征在于,最大重试次数至少为10次,若第10次重试执行仍为失败,结束流程。

6.根据权利要求1所述的一种基于内存实现分布式重试调度的方法,其特征在于,重试的执行时间为上一次执行失败时间点加上当次重试的时间间隔。

7.根据权利要求6所述的一种基于内存实现分布式重试调度的方法,其特征在于,每次重试的时间间隔依次增加。

说明书 :

一种基于内存实现分布式重试调度的方法

技术领域

[0001] 本发明属于计算机技术领域,具体涉及一种基于内存实现分布式重试调度的方法。

背景技术

[0002] 随着公司业务的发展,涉及分布式事务的场景越来越多,对业务来说是一件头疼的事情,大部分都需要通过重试或者分布式任务调度完成分布式事务的一致性处理,保证业务数据的最终一致性。然而要实现分布式任务调度需要引入第三方中间件组件并且需要额外编写任务代码实现分布式调度任务,进而导致业务系统依赖过重。
[0003] 基于以上解决分布式事务的情况,现在需要提供一款分布式重试调度解决方法,保证分布式事务数据一致性,并且从业务系统中解耦出来。

发明内容

[0004] 本发明要解决的技术问题是:提供一种基于内存实现分布式重试调度的方法,以至少解决上述部分技术问题。
[0005] 为实现上述目的,本发明采用的技术方案如下:
[0006] 一种基于内存实现分布式重试调度的方法,包括以下步骤:
[0007] 步骤1、请求事务,执行事务,若事务执行失败,对事务进行内存重试,内存重试仍为失败,将内存重试失败的事务设定为重试事务;
[0008] 步骤2、创建事务表和数据库锁表,监听重试事务的上下文信息,将上下文信息生成唯一约束字段并作为主键保存至事务表;
[0009] 步骤3、将唯一约束字段作用于数据库锁表,完成加锁;查询事务表,基于数据库锁表提取重试事务的执行数据,采用定时器对重试事务发起重试;
[0010] 步骤4、重试执行成功,更新事务表的执行状态为成功,结束流程;重试执行失败,更新下次重试的执行时间,重复步骤3 步骤4,直至重试执行成功,更新事务表的执行状态~为成功,结束流程。
[0011] 进一步地,重试事务的上下文信息至少包括事务接口方法、事务接口方法的参数、以及事务执行时的上下文。
[0012] 进一步地,在所述步骤2中,将事务接口方法、事务接口方法的参数、事务执行时的上下文分别生成对应的唯一约束字段,将各唯一约束字段作为主键保存至事务表。
[0013] 进一步地,所述步骤3包括:步骤31,当在最大重试次数以内时,将唯一约束字段作用于数据库锁表进行主键索引,调用数据库连接驱动程序连接数据库并插入执行数据;步骤32,如果插入执行数据失败代表获取锁失败,则等待定时器下一次的重试调度;如果插入执行数据成功代表获取锁成功,则等待定时器本次的重试调度;步骤33,重试调度前预先在事务表的事务接口方法上插入重试注解,开始执行重试时,检查事务接口方法是否有该重试注解,有重试注解则自动执行重试。
[0014] 进一步地,重试事务每次执行失败时,都会抛出对应的错误异常信息,重试注解基于错误异常信息实现,实现后重试注解加在重试事务的事务接口方法上。
[0015] 进一步地,唯一约束字段采用哈希生成。
[0016] 进一步地,最大重试次数至少为10次,若第10次重试执行仍为失败,结束流程。
[0017] 进一步地,重试的执行时间为上一次执行失败时间点加上当次重试的时间间隔。
[0018] 进一步地,每次重试的时间间隔依次增加。
[0019] 与现有技术相比,本发明具有以下有益效果:
[0020] 基于spring‑retry的重试原理,本发明提供了一种基于内存实现分布式重试调度的方法,支持事务表录入分布式事务失败前后的上下文信息,实现指定业务异常重试;通过内存任务定时调度实现分布式重试调度,并且支持指定重试次数和最大重试次数;采用随机的重试间隔,减少重试时的下游系统压力,实现重试退避和随机退避。

附图说明

[0021] 图1为本发明的方法流程图。实施方式
[0022] 术语解释:
[0023] guava‑retry:Google Guava库的一个扩展包,可以为任意函数调用创建可配置的重试机制;
[0024] spring‑retry:Spring提供的一个基于Spring的重试框架,对一些异常情况下的方法进行重试;
[0025] Listener:监听器;
[0026] Timer:定时器。
[0027] 为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图,对本发明进一步详细说明。显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
[0028] 业界开源的基于内存的重试算法包括guava‑retry、spring‑retry等,但是都只能实现内存级重试本地事务,在事务请求错误时执行内存重试后不再重试,没法实现事务的补偿机制解决事务数据的一致性。这就需要实现分布式事务重试调度器,保证多个服务在同一时刻只能有一个服务执行重试调度,保证事务数据的一致性。
[0029] 为此,如图1所示,本发明提供一种基于内存实现分布式重试调度的方法,包括以下步骤:
[0030] 步骤1、请求事务,执行事务,若事务执行失败,对事务进行内存重试,内存重试仍为失败,将内存重试失败的事务设定为重试事务;
[0031] 步骤2、创建事务表和数据库锁表,监听重试事务的上下文信息,将上下文信息生成唯一约束字段并作为主键保存至事务表;
[0032] 步骤3、将唯一约束字段作用于数据库锁表,完成加锁;查询事务表,基于数据库锁表提取重试事务的执行数据,采用定时器对重试事务发起重试;
[0033] 步骤4、重试执行成功,更新事务表的执行状态为成功,结束流程;重试执行失败,更新下次重试的执行时间,重复步骤3 步骤4,直至重试执行成功,更新事务表的执行状态~为成功,结束流程。
[0034] 本发明通过新增事务表(retry_task表),以保存重试事务执行失败的上下文信息,执行失败的信息通过监听器(Listener)实现监听和保存写入。重试事务的上下文信息至少包括事务接口方法、事务接口方法的参数、以及事务执行时的上下文。在spring‑retry内存重试结束仍然失败时,调用Listener提供的close(关闭重试)方法,在close方法内部将当前重试事务的事务接口方法、事务接口方法的参数、事务执行时的上下文分别生成对应的唯一约束字段,将各唯一约束字段作为主键保存至事务表,用于分布式调度算法进行重试时查询事务表的数据、还原重试事务的上下文信息。事务表的其他字段则是事务执行的基本信息,通过基本信息调用要执行的事务方法,属于常用的java技术,故不做赘述。
[0035] 所述步骤3包括:步骤31,当在最大重试次数以内时,将唯一约束字段作用于数据库锁表进行主键索引,调用数据库连接驱动程序连接数据库并插入执行数据;步骤32,如果插入执行数据失败代表获取锁失败,则等待定时器下一次的重试调度;如果插入执行数据成功代表获取锁成功,则等待定时器本次的重试调度;步骤33,重试调度前预先在事务表的事务接口方法上插入重试注解,开始执行重试时,检查事务接口方法是否有该重试注解,有重试注解则自动执行重试。本发明利用Mysql数据库唯一性实现分布式锁,将唯一约束作用于数据库锁表,保证数据库锁表只能有一个事务插入成功。
[0036] 基于java语言的注解机制,重试事务每次执行失败时,都会抛出对应的错误异常信息,所述重试注解基于错误异常信息实现,实现后重试注解加在重试事务的事务接口方法上,用于下一次重试操作的判断。
[0037] 本发明通过内存任务定时实现分布式重试调度的重试退避,最大重试次数至少为10次,若第10次重试执行仍为失败,则人工进行干预结束流程。基于Timer,将10次重试次数分为10个级别执行,每次重试的执行时间为上一次执行失败的时间点加上当次重试的时间间隔。每次重试的时间间隔依次增加,递增可设定为随机增加。
[0038] 演示如下:S代表事务,C代表执行步骤,D代表重试间隔(30s、1min、2min、5min、10min、20min、30min、45min、1h、2h),K代表当前时间,F代表重试时间。
[0039] 第1次重试C1:F1 = K + D1,D1为30s,在F1时执行重试事务S;
[0040] 第2次重试C2:F2 = F1 + D2,D2为1min,在F2时执行重试事务S;
[0041] 第3次重试C3:F3 = F2 + D3,D3为2min,在F3时执行重试事务S;
[0042] 第4次重试C4:F4 = F3 + D4,D4为5min,在F4时执行重试事务S;
[0043] 第5次重试C5:F5 = F4 + D5,D5为10min,在F5时执行重试事务S;
[0044] 第6次重试C6:F6 = F5 + D6,D6为20min,在F6时执行重试事务S;
[0045] 第7次重试C7:F7 = F6 + D7,D7为30min,在F7时执行重试事务S;
[0046] 第8次重试C8:F8 = F7 + D8,D8为45min,在F8时执行重试事务S;
[0047] 第9次重试C9:F9 = F8 + D9,D9为1h,在F9时执行重试事务S;
[0048] 第10次重试C10:F10 = F9 + D10,D10为2h,在F10时执行重试事务S。
[0049] 如果最后一次执行仍然失败,不再进行重试需要人工干预,如果中间某一次成功则分布式重试成功,重试结束。最大重试次数至少为10次,重试10次基本可以满足大多业务重试述求,如果业务需要可以调整最大重试次数和时间间隔。
[0050] 本发明提供的一种基于内存实现分布式重试调度的方法,通过事务表将执行上下文信息保存后重放执行,上下文信息主要是保存事务执行时需要的上下文信息,便于重试时还原重试现场;每次重试执行前均需要加锁处理,在加锁成功后再执行分布式重试操作。
[0051] 最后应说明的是:以上各实施例仅仅为本发明的较优实施例用以说明本发明的技术方案,而非对其限制,当然更不是限制本发明的专利范围;尽管参照前述各实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的范围;也就是说,但凡在本发明的主体设计思想和精神上作出的毫无实质意义的改动或润色,其所解决的技术问题仍然与本发明一致的,均应当包含在本发明的保护范围之内;另外,将本发明的技术方案直接或间接的运用在其他相关的技术领域,均同理包括在本发明的专利保护范围内。