功能介绍 业务开发中会有方法重推的需求,比如调用第三方系统接口,如果调用失败,需要能够重推,重推后需要更新业务信息,例如业务单据的状态更新为:推送失败(成功)。 因此决定写一套通用的接口重推功能,能实现自动重推和手动重推。并且记录的接口调用的信息。 该功能模块目录如下: 主要功能为:1。在需要记录日志的方法上面添加注解2。调用方法,调用信息记录数据库3。调用重试方法,重试调用异常方法 日志记录注解 注解EnableLog说明:Target({ElementType。METHOD})Retention(RetentionPolicy。RUNTIME)DocumentedpublicinterfaceEnableLog{OperationTypetype();接口提供方returnStringprovider();StringcurrentSystem()defaultStringUtils。EMPTY;类型IN本系统对外apiorOUT调的外部接口returnModelTypemodel();成功标志StrreturnStringsuccessStr()defaultStringUtils。EMPTY;允许重试次数,默认1,即可无限重试returnlongallowRetry()default1;是否自动重试0否returnStringneedAuto()defaultSystemConstant。NO;方法描述returnStringdesc()defaultStringUtils。EMPTY;} 调用示例EnableLog(typeOperationType。INSERT,providerOA,modelModelType。OUT,successStrsuccess,descOA接口消息提醒)publicStringsendNotify(OaTaskMessageoaTaskMessage){OaMessageParamoaMessageParamBeanUtils。copy(oaTaskMessage,OaMessageParam。class);oaMessageParam。setOpenMode(5);oaMessageParam。setModuleCode(srm);oaMessageParam。setMsgType(1);returnoaApiClient。sendMessage(oaMessageParam);} 参数说明:1。type:目标方法的操作类型。增,删,改,查2。provider:接口来源方3。model:IN本系统对外apiorOUT调的外部接口4。successStr:指定接口调成功的返回5。目标方法的描述重试方法(手动) 如果标出的方法调用异常,那么就可以执行这个重试方法。该方法主要执行逻辑为:1。在日志记录表获取指定主键id的异常状态方法调用记录2。重复执行次数校验3。反射执行方法4。更细记录状态重试方法(自动) 该系统默认手动重试,如果在EnableLog注解中我们设置needAutotrue,那么系统自动重试,自动重试功能如下对注解标注的方法放入redis阻塞队列异常重试线程消费阻塞队列 放入异常队列exceptionResultQueueService。pushExceptionQueue(logId); 重试线程消费阻塞队列中的值:privatevoidloop(){StringnameThread。currentThread()。getName();log。info(异常方法重试线程启动,当前线程:【{}】,name);while(!Thread。interrupted()){StringapiLogId(String)redisUtils。blockRightPop(EXCEPTIONQUEUEKEY);LogExecutor。LogMethodParamparamnewLogExecutor。LogMethodParam();param。setLogId(apiLogId);logExecutor。executorMethod(param);每隔5s循环一次。减少资源消耗try{Thread。sleep(5000);}catch(InterruptedExceptione){e。printStackTrace();}}}异常重试后业务处理扩展 如果重新执行方法后需要处理业务逻辑,可以使用这个扩展接口ComponentpublicclassExampleRetryResultHandlerimplementsRetryResultHandler{OverridepublicStringresultHandler(Objectobj){重试方法执行后业务处理}OverridepublicStringinvokeMethodStr(){}OverridepublicStringmethodName(){returnsendTaskM}} 只需实现RetryResultHandler接口即可。 RetryResultHandler说明如下:publicinterfaceRetryResultHandler{方法结果处理器paramobjreturnStringresultHandler(Objectobj);该方法的父层调用方法,全路径returnStringinvokeMethodStr();Enable注解标注的方法名称returnStringmethodName();} 业务处理逻辑写在resultHandler()方法即可。invokeMethodStr()为该方法的父层方法(全路径),methodName()为该方法的方法名称。 至此,一套方法日志记录,方法重试的系统完成。分布式系统调用 在分布式系统中,各系统如何调用这个公用的重试方法呢,我们需要将上述功能封装到一个SDK中,需要调用的系统就引入这个SDK。各业务系统中引入SDK后编写Controller层方法:RestControllerRequestMapping(apiLog)publicclassApiLogController{AutowiredprivateSysLogApiClientsysLogApiC执行调用异常的方法returnApiMetadata(actionName执行调用异常的方法,permissionLevelPermissionLevel。PermissionRequired)PostMapping(valueexecutorExceptionMethod)ResponseBodypublicObjectexecutorExceptionMethod(RequestBodyLogMethodParamparam){returnsysLogApiClient。executorExceptionMethod(param);}} 同时我们需要一个公共服务,该公共服务需要写一个共前端调用的重试接口,前端传入logId,通过路由执行各个业务系统中SDK的executorExceptionMethod方法。 这样就可以实现在分布式系统中调用公共方法去执行重试了。 本篇内容到这里就结束了,如果内容对你有帮助,欢迎点赞收藏。