Skip to content

服务端上报相关参数-demo

那么讲解完成这些参数后,我们通过案例来讲解一下这几个参数的具体使用方法吧。 由于后续的案例的都涉及到了客户端和服务端的交互,需要客户端也处于启动状态,所以后续的用例我们通过HTTP接口访问的形式来进行测试。 在使用远程重试相关的功能前,我们首先需要创建一个组,组名既是我们之前在SpringbootApplication中给出的@EnableEasyRetry注解指定的组名,在这个案例中组名为easy_retry_demo_group,因为需要我们手动指定相关的路由策略和Id生成模式。 Id生成模式指的是我们重试请求的唯一键,SnailJob中为我们指定了两种模式,分别是雪花算法模式和号段模式,大家可以根据业务场景自行选取。 指定分区的配置允许我们将不同的任务放置在不同的分区中进行管理,项目中自带的建表语句中为我们创建了表retry_task_0retry_dead_letter_0,因此此处我们将指定分区的值设置为0,如果选择了其他的分区,那么我们需要在数据库中创建相关的表。

在创建完成相关组之后,写一个远程重试的方法。

java
@Component
public class RemoteRetryService {
    @Retryable(scene = "remoteRetry",retryStrategy = RetryType.ONLY_REMOTE)
    public void remoteRetry(){
        System.out.println("远程重试方法启动");
        double i = 1 / 0;
    }
}

然后在Controller层调用这个方法

java
@RestController
    @RequestMapping("/remote")
    public class RemoteRetryController {
        @Autowired
        private RemoteRetryService remoteRetryService;

        @GetMapping("/retry")
        public void remote(){
            remoteRetryService.remoteRetry();
        }
    }

启动客户端的服务,随后通过IDEA发起一个HTTP请求

此时可以看到我们的控制台已经可以看到本次执行的任务

随后我们进入任务管理列表中查看请求的详情,可以看到已经产生了一条正在执行中的重试任务,目前的执行次数是8。

点击进入重试数据的详情,我们可以看到,本次请求的详细调度日志,由于在重试过程中还在持续发生异常,因此会不断地执行重试。

那么这个重试会有上限吗?当然会有,我们在组管理中找到对应的组,当我们启动服务的时候,会自动注册一个场景,此时场景初始化时最大的重试次数是21,调用链超时时间是6000毫秒。

我们调低这个默认值,将最大重试次数调整到10次,看一下当超过最大重试次数时会发生什么。 可以看到,当重试数据达到最大次数时,此时会产生一条回调数据的任务。

你可能会比较好奇为什么会产生两条任务?这就要从我们的交互流程来说起了,在远程重试的场景中,客户端遭遇异常后会进行重试的数据上报,服务端在接受到客户端的重试数据后会进行重试数据的持久化,随后会由调度器下发调度任务。此时会有两个执行器在等待,一个是重试执行器,一个是回调执行器,重试执行器的作用是触发任务调度,而回调执行器的作用则是将服务端调度的状态通知给客户端,客户端在接受到服务端的回调任务后可以执行自定义方法,来指定重试完成之后的后置动作,这部分内容在下面retryCompleteCallback中会详细介绍。

倘若重试任务超过最大重试次数后,将会从"任务管理"一栏中取消,加入到"死信队列管理"一栏中,此时我们认为这条任务是一条死信,不再进行重试执行。当然,如果在业务中因为下游的bug导致本任务的重试一直不成功,我们也可以点击死信队列管理中的回滚,将这条死信消息重新放入到"任务管理"Tab下面,再次执行重试任务。

接下来我们来用一个案例演示一下retryStrategy中的LOCAL_REMOTE、async、timeout、unit这四个参数,因为这几个参数都比较简单,因此我就放到一个案例中来进行处理了。首先我们定义一个同步上传的方法。

java
/**
 * 使用先本地再远程的策略同步上传重试请求
 * retryStrategy = LOCAL_REMOTE 代表本地重试3次后再执行远程上报
 * async = false 代表使用同步上传的方式
 * timeout = 1 代表超时时间为1
 * unit = MINUTES 代表超时时间的单位是分钟
 */
@Retryable(scene = "remoteRetryWithSync",retryStrategy = RetryType.LOCAL_REMOTE,
                async = false, timeout = 1, unit = TimeUnit.MINUTES)
public String remoteRetryWithLocalRemote(String requestId){
    double i = 1 / 0;
    return requestId;
}

观察结果我们可以看到,首先执行了三次本地重试,随后在本地抛出异常。

然后任务管理中出现了我们上报的任务。