SpringBoot中间件—封装超时熔断器

news2024/9/30 5:30:28

需求背景

如果一个服务中有很多涉及需要服务间熔断的地方,就会出现N多下述代码:

1.N个fegnClient接口

@FeignClient(name = "hello-world-service", fallback = HelloWorldFallback.class)
public interface HelloWorldService {
    @GetMapping("/hello")
    String sayHello();
}

2.N个降级结果类

@Component
public class HelloWorldFallback implements HelloWorldService {

    @Override
    public String sayHello() {
        return "fallback";
    }
}

feign调用接口上都要加上fallback降级类,只是想简单方便且不需要关心创建及返回结果,并且可以把hystrix的框架包装在中间件中,屏蔽调用逻辑,让开发者更加关注于业务本身。

方案设计

1.使用注解和切面技术,拦截需要熔断保护的方法

2.继承com.netflix.hystrix.HystrixCommand.class(奈飞熔断器源码),实现自定义的超时熔断处理

代码实现

自定义注解DoHystrix

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface DoHystrix {

    String returnJson() default "";         // 失败结果 JSON
    int timeoutValue() default 0;           // 超时熔断

}

熔断器的具体实现--HystrixValveImpl.class

public class HystrixValveImpl extends HystrixCommand<Object> implements IValveService {

    private ProceedingJoinPoint jp;
    private Method method;
    private DoHystrix doHystrix;

    public HystrixValveImpl() {

        /*********************************************************************************************
         * 置HystrixCommand的属性
         * GroupKey:            该命令属于哪一个组,可以帮助我们更好的组织命令。
         * CommandKey:          该命令的名称
         * ThreadPoolKey:       该命令所属线程池的名称,同样配置的命令会共享同一线程池,若不配置,会默认使用GroupKey作为线程池名称。
         * CommandProperties:   该命令的一些设置,包括断路器的配置,隔离策略,降级设置,以及一些监控指标等。
         * ThreadPoolProperties:关于线程池的配置,包括线程池大小,排队队列的大小等
         *********************************************************************************************/

        super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GovernGroup"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("GovernKey"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("GovernThreadPool"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD))
                .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter().withCoreSize(10))
        );
    }

    @Override
    public Object access(ProceedingJoinPoint jp, Method method, DoHystrix doHystrix, Object[] args) {
        this.jp = jp;
        this.method = method;
        this.doHystrix = doHystrix;

        // 设置熔断超时时间
        Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GovernGroup"))
                .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                        .withExecutionTimeoutInMilliseconds(doHystrix.timeoutValue()));

        return this.execute();
    }

    @Override
    protected Object run() throws Exception {
        try {
            return jp.proceed();
        } catch (Throwable throwable) {
            return null;
        }
    }

    @Override
    protected Object getFallback() {
        return JSON.parseObject(doHystrix.returnJson(), method.getReturnType());
    }

}

主要是对HystrixCommand的再次封装,通过继承父类构造函数来配置熔断器启动参数,包括熔断器工厂分组,key,线程隔离策略,线程池的核心线程数等

HystrixCommand.run()方法:返回正确方法调用结果
HystrixCommand.getFallback()方法:返回超时熔断降级结果

切面实现--DoHystrixPoint.class

@Aspect
@Component
public class DoHystrixPoint {

    @Pointcut("@annotation(cn.bugstack.middleware.hystrix.annotation.DoHystrix)")
    public void aopPoint() {
    }

    @Around("aopPoint() && @annotation(doGovern)")
    public Object doRouter(ProceedingJoinPoint jp, DoHystrix doGovern) throws Throwable {
        IValveService valveService = new HystrixValveImpl();
        return valveService.access(jp, getMethod(jp), doGovern, jp.getArgs());
    }

    private Method getMethod(JoinPoint jp) throws NoSuchMethodException {
        Signature sig = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) sig;
        return jp.getTarget().getClass().getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
    }

}

切面中的逻辑已经在统一白名单中间件  文章中详细梳理过了,需要请移步

测试

在被调用方法上加自定义熔断注解,超时时长设置为500毫秒,当前线程睡一秒

 方法调用大于500毫秒:
 

{"code":"0","info":"调用超500毫秒"}

将线程睡一秒干掉,方法调用小于500毫秒:
 

{"name":"xxx","age":20,"address":"xxx"}

总结

通过对中间件的设计屏蔽掉底层应用的复杂性,让整个功能服务的业务代码更加纯粹,同时可以让使用此功能的研发不会过多的参与到插件的使用中,把更多的关心放在业务逻辑开发中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/737205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

U盘写保护怎样去掉?分享3种简单方法!

不知道为什么我的u盘突然就显示被写保护了呢&#xff0c;大家有没有遇到过类似的情况呀&#xff1f;有什么比较好的解决方法可以推荐一下吗&#xff1f; 很多朋友可能对u盘写保护没有什么概念&#xff0c;实际上&#xff0c;u盘写保护可能会阻止我们对其中的文件进行修改或者添…

含生僻字中文校验方式优化

项目姓名校验原本一直是通过utf8正则进行校验&#xff0c;但近期出现的客户生僻字包含双码字&#xff0c;原有校验方式无法实现。需要修改扩大校验范围。 知识点回顾&#xff1a; Unicode是Unicode Standard&#xff08;Unicode标准&#xff09;的简写&#xff1b;Unicode为每…

HNU-操作系统OS-学习感悟

初次接触如此底层的计算机基础课程&#xff0c;我还是很不适应的。 教材用的这本书&#xff0c;实验用的清华大学的ucore实验 好在应试水平没有丢。最后总评94/100。 下面仅从应试角度谈一谈学习的理解 总领 HNU的OS课程平时分给的比较模糊&#xff0c;大致由 作业实验验…

先导式比例溢流阀放大器

EDBW10PL350XY/224、EDBW20PL210XY/724、EDBW30PL105XY/224、EDBW10PL055XY/224先导式比例溢流阀&#xff0c;板式安装&#xff0c;由主阀芯和先导级阀beuec比例放大器组成:先导级阀为比例溢流阀&#xff0c;主阀阅芯可独立调节压力作为安全限压压力&#xff0c;比例先导阀压力…

selenium怎么使用代理IP

什么是selenium Selenium 是一个自动化测试框架&#xff0c;用于测试 Web 应用程序的功能性。它支持多个编程语言&#xff08;如Java&#xff0c;Python&#xff0c;C#等&#xff09;并且可以在操作系统和不同浏览器上运行测试。Selenium 可以模拟用户在浏览器中的操作&#x…

PC端实现滚动分页懒加载

思路 监听列表元素的滚动事件&#xff0c;滚动到底部的时候&#xff0c;加载下一页的数据监听数据加载&#xff0c;判断是否已全部加载结束 实现 监听滚动事件 为列表元素 listBox 绑定 scroll 事件进行监听 <div class"listBox" scroll"watchScroll&qu…

Github点赞120k的Spring全家桶笔记,吃透Offer拿到手软!

Spring框架自诞生以来一直备受开发者青睐&#xff0c;有人亲切的称之为&#xff1a;Spring 全家桶。它包SpringMVC、SpringBoot、Spring Cloud、Spring Data等解决方案。 很多研发人员把spring看作心目中最好的java项目&#xff0c;没有之一。Spring系列包含非常多的项目&…

【LLM】DeepSpeed分布式训练框架

文章目录 一、DeepSpeed介绍1. 分布式背景介绍2. deepspeed介绍 二、deepspeedtransformer代码实战1. 预处理和Json文件2. 训练代码 三、deepspeed加速Bloom lora微调1. 配置文件2. 训练代码 Reference 一、DeepSpeed介绍 1. 分布式背景介绍 分布式计算环境中&#xff0c;主节…

进程间通信方法——命名管道

命名管道 匿名管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。如果我们想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件来做这项工作&#xff0c;它经常被称为命名管道。&#xff08;命名管道是有文件名的&#xff0…

Vs窗口布局移动窗口vs直接卡死2

(1条消息) Vs窗口布局移动窗口vs直接卡死_vs拖动窗口布局卡死_Ma_Hong_Kai的博客-CSDN博客 由于莫名其妙的更新导致又卡死了&#xff0c;导致最近一年多无法拖动vs的框挺折磨 前一段时间看到一个有意思的命令 搞了搞了 可以拖动了&#xff08;目测应该是微软自己发现这个问…

【图像识别】openCV基础知识

图像处理基础 一、使用OpenCV前要准备的工作1.先导入需要用到的库2.自定义&#xff0c;图片展示函数 二、开始学习常用函数1.生成随机整数①. 函数说明②.代码a. 二维灰度图b. 三维彩色图 ③.代码现象a. 二维灰度图b. 三维彩色图 2.通道的分离与合并①先导入一张图片② 将其RGB…

多元回归预测 | Matlab基于麻雀算法(SSA)优化高斯过程回归(SSA-GPR)的数据回归预测,matlab代码,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于麻雀算法(SSA)优化高斯过程回归(SSA-GPR)的数据回归预测,matlab代码,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源…

合宙Air001震撼来袭!

Air001芯片特性 采用ARM 32位的M0内核&#xff0c;主频可达48MHz&#xff1b; 4K RAM32K Flash&#xff1b; 1.7&#xff5e;5.5V超宽范围供电&#xff0c;USB和电池都能直接供电&#xff1b; 内嵌可配4/8/16/22.12/24MHz的RC振荡器&#xff0c;无需外挂晶振就能48MHz运行…

你连存活到JDK8中著名的Bug都不知道,你怎么敢跳槽涨薪的?

在笔者研究 JDK 源码时&#xff0c;注意到在CopyOnWriteArrayList 和ArrayList 的构造器中都出现了如下 bug 字样 6260652 其实代表的JDK bug 列表中的编号 http://bugs.java.com/bugdatabase/view_bug.do?bug_id6260652 http://bugs.java.com/bugdatabase/view_bug.do?bug…

GBU808-ASEMI薄体整流桥GBU808

编辑&#xff1a;ll GBU808-ASEMI薄体整流桥GBU808 型号&#xff1a;GBU808 品牌&#xff1a;ASEMI 芯片个数&#xff1a;4 封装&#xff1a;GBU-4 恢复时间&#xff1a;≥2000ns 工作温度&#xff1a;-50C~150C 浪涌电流&#xff1a;200A 正向电流&#xff1a;8A 反…

Golang 命令源码文件

Go 语言标准库中专门用于接收和解析命令参数。这个代码包的名字叫 flag。 函数 flag.StringVar 接受 4 个参数。 第 1 个参数是用于存储该命令参数值的地址&#xff0c;具体到这里就是在前面声明的变量 name 的地 址了&#xff0c;由表达式 &name 表示。 第 2 个参数是为…

高级运维开发工程师带你处理linux木马(挖矿病毒)实战例子

一、事态描述 centos7测试服务器&#xff0c;突然密码登不上去了&#xff0c;然后CPU占100%。已经猜到&#xff0c;登录密码过于简单&#xff0c;密码被破解挂马了。大概率是CPU挖矿病毒。 二、重置centos7登录root密码 步骤1 启动Linux Centos7系统&#xff0c;当出现如下画…

JavaWeb JSP 内置对象

1.JSP 内置对象 在jsp自动转换成的java文件的service方法中&#xff0c;我们可以看到这九个内置对象&#xff1a; 具体如下&#xff1a; request&#xff08;HttpServletRequest&#xff09;&#xff1a;代表客户端的HTTP请求。通过该对象&#xff0c;可以获取请求参数、请求…

时序区间预测 | Matlab基于高斯过程回归(GPR)时间序列区间预测,matlab代码,单变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列预测 | Matlab基于高斯过程回归(GPR)时间序列区间预测,matlab代码,单变量输入模型 评价指标包括:MAE、MBE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分源码 %% 清空环境变量…

【Spring Boot丨(十 )】日志

上文讲了 类型安全配置属性 本篇来讲一下 Spring boot 的默认日志相关 Logging &#x1f351; 概述&#x1f34f; 日志格式&#x1f350; 控制台输出&#x1f965; 文件输出&#x1f95d; 文件轮换&#x1f352; 文件级别 &#x1f351; 概述 Spring Boot在所有内部日志中使用C…