首页 > 其他分享 >16、实现Client远程调用的重试机制

16、实现Client远程调用的重试机制

时间:2023-10-20 11:34:06浏览次数:41  
标签:16 int retryTimes 重试 Client org import public

由于远程程序服务健壮性和网络的波动等因素,可能造成接口调用失败,因此有必要实现Client远程调用的重试机制

一、基于异常捕捉的重试机制:

    public String getDetailFromClient(){
        //重试次数
        int retryCount = 3;
        //重试时长(单位:ms)
        int retryTimes = 5000;
        while (retryCount > 0) {
            log.info("重试次数{}", retryCount);
            try {
                //远程调用的服务
                String result = httpClient.list();
             //判断返回的数据是否为零
                if (ObjectUtils.isEmpty(result)) {
                    log.info("数据为空,开始重试,retryTimes:{}", retryTimes);
                    //返回数据为零,进行重试
                    retryCount--;
                    //重试时长间隔
                    Thread.sleep(retryTimes);
                    continue;
                }
                // 返回非零数据,直接返回结果
                return result;
            } catch (Exception e) {
                //超时异常:进行重试
                retryCount--;
                try {
                    //重试时长间隔
                    Thread.sleep(retryTimes);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                log.error("调用发生异常,开始重试,retryTimes:{},异常信息{}", retryTimes, e);
            }
        }
        // 重试次数用尽,返回空值
        return "重试次数用尽,返回空值";
    }

 

二、基于Spring-AOP切面的重试机制:

1、引入AOP依赖:

<!--AOP切面-->
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
     <version>2.6.13</version>
</dependency>    

2、自定义重试注解:

import java.lang.annotation.*;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatableAnnotateBus {
 
    /**
     * 重试次数
     * @return
     */
    int repeatAmount() default 3;
 
    /**
     * 重试时间
     * @return
     */
    int repeatTime() default 1;
}

3、重试机制切面:

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Slf4j
@Component
@Aspect
public class RepeatableAspectUtil {
 
    @Pointcut("@annotation(com.iven.aspect.RepeatableAnnotateBus)")
    public void cutRepeatableMethod() {
 
    }
 
    @Around("cutRepeatableMethod()")
    public Object repeat(ProceedingJoinPoint joinPoint) throws InterruptedException {
        // 获取重试次数和重试间隔
        RepeatableAnnotateBus repeatableBus = ((MethodSignature) joinPoint.getSignature())
                .getMethod().getAnnotation(RepeatableAnnotateBus.class);
        int amount = repeatableBus.repeatAmount();
        int time = repeatableBus.repeatTime();
 
        Throwable error = new RuntimeException();
        for (int i = 1 ; i <= amount ; i++){
            try {
                //joinpoint.proceed():用于执行目标对象的原本方法,也就是切入点 (join point) 所表示的方法。
                //通过使用 proceed() 方法,可以在切面中实现方法拦截、日志记录等功能。
                Object result = joinPoint.proceed();
                if (ObjectUtils.isEmpty(result)) {
                    log.info("数据为空,开始重试,retryTimes:{}", i * time * 10000L);
                    //返回数据为零,进行重试, 重试时长间隔
                    Thread.sleep(i * time * 10000L);
                    continue;
                }
                return result;
            } catch (Throwable throwable) {
                error = throwable;
                log.warn("调用发生异常,开始重试,retryTimes:{}", i * time * 10000L);
            }
            //重试时长间隔
            Thread.sleep(i * time * 10000L);
        }
        log.error("重试次数耗尽,{}", error);
        return null;
    }
}

4、相关使用:

@RepeatableAnnotateBus
public String getDetailFromAspect(){
    //远程调用服务
    return httpClient.list();
}

 

三、参考:

java实现重试机制

 

标签:16,int,retryTimes,重试,Client,org,import,public
From: https://www.cnblogs.com/Iven-L/p/17776660.html

相关文章

  • 16.1 Socket 端口扫描技术
    端口扫描是一种网络安全测试技术,该技术可用于确定对端主机中开放的服务,从而在渗透中实现信息搜集,其主要原理是通过发送一系列的网络请求来探测特定主机上开放的TCP/IP端口。具体来说,端口扫描程序将从指定的起始端口开始,向目标主机发送一条TCP或UDP消息(这取决于端口的协议类型)。如......
  • AtCoder Regular Contest 167——B - Product of Divisors
    题目很明显,给定 所有因数的积不断除以最多能除几次。首先,很容易发现,对于每一对因子,都可以对答案得出B的贡献,设A的因子数目为n。将A进行质因数分解,PBa1,PBa2,PBa3……PBam,那么因数个数就是质因子加一的乘积。那么因子对数也就是前者一半。答案就是B乘因子对数除以二注意此处......
  • 文心一言 VS 讯飞星火 VS chatgpt (116)-- 算法导论10.3 1题
    一、用go语言,画图表示序列(13,4,8,19,5,11),其存储形式为多数组表示的双向链表。同样画出单数组表示的形式。文心一言:在Go语言中,我们无法直接画图,但我可以帮助你描述如何使用Go语言来表示和操作多数组表示的双向链表和单数组表示。首先,多数组表示的双向链表可以表示为以下的数据结构:......
  • MQ系列16:MQ实现消息过滤处理
    MQ系列1:消息中间件执行原理MQ系列2:消息中间件的技术选型MQ系列3:RocketMQ架构分析MQ系列4:NameServer原理解析MQ系列5:RocketMQ消息的发送模式MQ系列6:消息的消费MQ系列7:消息通信,追求极致性能MQ系列8:数据存储,消息队列的高可用保障MQ系列9:高可用架构分析MQ系列10:如何保证消......
  • ARC166B题解
    发现还没有和我一样的做法。觉得B比A好想的多。令\(A_i\)为\(a_i\)变成\(A\)的倍数最少次数,\(B_i,C_i,AB_i,AC_i,BC_i,ABC_i\)同理。那么我们就有\(A_i=(A-A\bmod{a_i})\bmodA\),其他同理。这一大坨东西显然都能在\(O(n)\)的时间复杂度内算出来。剩下的就很好......
  • 初学Bokeh:使用自适应绘图大小【16】跬步
    学习Bokeh:使用自适应绘图大小【16】跬步在绘图的过程中,如果要使绘图自动适应浏览器或屏幕大小,可以使用属性:sizing_modefrombokeh.plottingimportfigure,show#preparesomedata#定义显示数据x=[1,2,3,4,5]y=[4,5,5,7,2]#createanewplotwithrespo......
  • 题解 CF1651F【Tower Defense】
    题解CF1651F【TowerDefense】problem一个塔防游戏。一共有\(n\)个塔按\(1\simn\)的顺序排成一列,每座塔都有魔力容量\(c_i\)和魔力恢复速率\(r_i\)。对于一座塔\(i\),每过一秒它的魔力\(m_i\)会变为\(\min(m_i+r_i,c_i)\)。每座塔初始时满魔力。一共有\(q\)个......
  • 204 K8S API资源对象介绍03 (Job CronJob Endpoint ConfigMap Secret) 2.12-2.16
    一、API资源对象Job一次性运行后就退出的Pod1.1使用kubect生成YAML文件#kubectlcreatejobjob01--image=busybox--dry-run=client-oyaml>job01.yaml#vimjob01.yaml#catjob01.yamlapiVersion:batch/v1kind:Jobmetadata:creationTimestamp:nullnam......
  • 10.16
    今日代码:500行今日时间:4小时学习内容:今天大数据学习了MapReduce知识,人机交互学习了css的选择器知识。写了一下大数据作业词频统计任务编程实践,任务要求:在Linux系统本地创建两个文件,即文件wordfile1.txt和wordfile2.txt,文件wordfile1.txt的内容格式如下,需要将zhangsan换成自己名字......
  • 169. 多数元素
    给定一个大小为n的数组nums,返回其中的多数元素。多数元素是指在数组中出现次数大于⌊n/2⌋的元素。你可以假设数组是非空的,并且给定的数组总是存在多数元素。示例1:输入:nums=[3,2,3]输出:3思路本题常见的三种解法:哈希表统计法:遍历数组nums,用HashMap......