一、前言
在业务多、并发高的情况下,我们的系统,一般都会拆分为多个子系统,子系统之前通过 RPC 联系。
RPC 调用偶尔会出现失败的问题,而有些问题实际上不是问题,例如只是网络延迟,方法调用超时,再试一遍就完事了。
这时候,重试的引入即势在必行了。
二、正文
下面写一个简单的 demo,模拟远程服务重试的最简单实现方式——循环实现
1.模拟调用远程服务
重点在于引入 try catch 处理逻辑
package com.cun.retry.client;
import com.cun.retry.service.RemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
private static final int RETRY_TIMES = 3;
private static final Logger logger = LoggerFactory.getLogger(Test.class);
public static void main(String[] args) {
int retryCount = 0;
while (retryCount < RETRY_TIMES) {
try {
RemoteService.execute();
break; // 能执行到这行,说明执行没有异常
} catch (Exception e) {
retryCount++;
logger.info("【远程服务调用失败,重试中】");
}
}
if (retryCount >= RETRY_TIMES){
logger.info("【无法调用远程服务】");
}
logger.info(String.format("【重试次数:%s >>> 最终执行是否成功:%s】", retryCount, retryCount < RETRY_TIMES));
}
}
2.模拟远程的服务方法
有几率 ÷0
引发失败
package com.cun.retry.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Random;
public class RemoteService {
private static final Logger logger = LoggerFactory.getLogger(RemoteService.class);
public static int execute() {
logger.info("【远程服务执行中】");
int num = new Random().nextInt(3);
return 10 / num;
}
}
可能结果
完整代码放在 GitHub 上了:https://github.com/larger5/retry
三、结尾
实际业务中,我们会把调用失败的操作暂存起来,等其他业务过一遍后。再重复执行,以确保大量的其他业务完成,而不至于卡在一个点上。