SpringBoot--超时熔断器

news2024/10/6 16:31:30

需求背景

如果一个服务中有很多涉及需要服务间熔断的地方,就会出现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/716569.html

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

相关文章

gma 2 教程(一)概述:3. 探索 GMA

组织方式 gma 整体按照库-模块-类/函数-&#xff08;方法/属性/子类&#xff09;的思路构建&#xff0c;详细思路如下所示&#xff1a; 整体架构 gma内主要模块与功能对应关系见下表&#xff1a; 模块名中文名对应主要功能io输入输出栅格/矢量数据输入输出模块crs坐标系统坐…

vim的使用方法及相关按键

目录 一、安装vim 二、vim的使用 1.打开vim 2.vim的四种模式使用 &#xff08;1&#xff09;命令模式&#xff08;快捷键的使用&#xff09; &#xff08;2&#xff09;编辑模式 &#xff08;3&#xff09;末行模式 &#xff08;4&#xff09;可视化模式 一、安装vim …

022:vue中tree结构数据变成扁平化table结构数据的示例

第022个 查看专栏目录: VUE — element UI vue在使用element UI tree的时候,有的时候是要做逆向处理的,即将树形结构的数据转化为table结构的数据,即扁平化的json数据。 如何处理呢? 效果图 原始tree结构数据: let newdata= [ {

redis pipeline

redis 执行多条连续的命令的时候为了减少网络开销RTT&#xff0c;可以使用pipeline技术。 pipeline 与 原生批命令(mset, mget) 对比&#xff1a; 原生批命令是原子性&#xff0c;pipeline是非原子性 (原子性概念:一个事务是一个不可分割的最小工作单位,要么都成功要么都失败…

基于Anime2Sketch算法那将图片转成素描

1.下载源码地址 https://github.com/Mukosame/Anime2Sketch下载项目依赖包&#xff0c;下载模型权重文件 运行看效果 python test.py --datarootE:\01_hjz\datas\00-hjz\pictures --load_size512调整自定义测试图片路径 """Test script for anime-to-sketch…

基于Java+Vue前后端分离网上书城系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

ChatGPT+低代码,好用到飞起?

ChatGPT 凭借短短 2 个月&#xff0c;月活用户突破 1 亿&#xff0c;成为史上用户增长速度最快的消费级应用程序。ChatGPT 的爆火&#xff0c;在全球范围内掀起了一场关于 AI 技术革命的狂潮&#xff0c;AIGC 也迅速成为科技圈最火赛道。 更有国际咨询机构预测&#xff0c;203…

IIS安装配置和简单网站部署流程

IIS安装和网站配置 环境&#xff1a;win10 注意&#xff1a;这是在win10下部署iis&#xff0c;开发环境下部署&#xff0c;开发测试&#xff0c;非windows server IIS简介 Internet Information Services,简称IIS&#xff0c;是微软提供基于windows的互联网信息服务&#x…

微信小程序使用第三方组件wxParse加载富文本html

微信小程序使用第三方组件wxParse加载富文本html 微信小程序微信小程序加载富文本html微信小程序富文本第三方组件wxParsewxParse富文本html wxParse简介 wxParse 是一个微信小程序富文本解析组件&#xff0c;支持支持Html及markdown转wxml。 wxParse gitHub地址&#xff1…

亿发软件:玩具制造行业批发ERP系统解决方案,赋能传统制造商数字化

我国长期以来被公认为玩具制造大国&#xff0c;受益于其制造基础设施和成本优势。此外&#xff0c;可支配收入的增加和用户生活方式的改变增加了国内外对玩具的需求。然而&#xff0c;行业也面临着挑战和转型。随着数字技术的出现和用户偏好的变化&#xff0c;玩具ERP系统在确保…

TCP三次握手和自连接的条件和缺点

详解三次握手 为什么 SYN 段不携带数据却要消耗一个序列号呢&#xff1f; 记住&#xff1a; • 不占用序列号的段是不需要确认的&#xff0c;比如纯 ACK 包 • SYN 段需要对方的确认&#xff0c;需要占用一个序列号 • 凡是消耗序列号的 TCP 报文段&#xff0c;一定需要对端确认…

旅游宣传软文怎么写吸引人?纯干货

世界那么大&#xff0c;我想去看看&#xff0c;旅游是一种非常放松解压的方式&#xff0c;在旅行中放飞自我&#xff0c;在旅行中寻找自我&#xff0c;一个景点的客流量很大程度取决于其宣传效果&#xff0c;旅游宣传软文就是一种通过文字来吸引人们前往旅游目的地的宣传手段。…

嵌入式系统中详解 Modbus 通信协议(清晰易懂)

本文总结关于 Modbus 相关的知识&#xff0c;浅显易懂&#xff0c;旨在对 Modbus 有一个很直观的了解。如有错误&#xff0c;欢迎修改意见和建议。 什么是协议 在了解什么是Modbus之前&#xff0c;我们先来看下什么是协议。 协议是一个汉语词汇&#xff0c;读音为xi y&#…

Nftables栈溢出漏洞(CVE-2022-1015)复现

背景介绍 Nftables Nftables 是一个基于内核的包过滤框架&#xff0c;用于 Linux 操作系统中的网络安全和防火墙功能。nftables 的设计目标是提供一种更简单、更灵活和更高效的方式来管理网络数据包的流量。 钩子点&#xff08;Hook Point&#xff09; 钩子点的作用是拦截数…

Linux环境下配置安装RocketMQ

1.下载 官网下载&#xff1a;下载链接 根据需要下载自己需要的版本、本文使用下载的是:4.7.0版本 2.安装 创建目录&#xff0c;使用ftp工具上传下载的包到上面创建的目录下。 cd /usr/local mkdir rocketmq-all-4.7.0注意&#xff1a;rocketmq 需要 Linux 上安装JDK&…

7、卷积神经网络:基础部件+LeNet

1、图像卷积 1. 互相关运算 严格来说&#xff0c;卷积层是个错误的叫法&#xff0c;因为它所表达的运算其实是互相关运算&#xff08;cross-correlation&#xff09;&#xff0c;而不是卷积运算。在卷积层中&#xff0c;输入张量和核张量通过(互相关运算)产生输出张量。 首先…

【运维工程师学习】安装ubuntu20.04并配置SSH

【运维工程师学习】安装ubuntu20.04 1、镜像获取2、创建虚拟机3、开始安装4、配置SSH(1) 查看本地ssh版本(2) 安装ssh(3) 查看ssh运行状态(4) 设置开机自动启动(5) 重启(6) 安装net-tools(7) 查看ip5、SSH连接 1、镜像获取 https://next.itellyou.cn/Original/#cbpProduct?ID…

pdf如何导出为图片?分享三个方法PDF转图片!

将PDF文件转换为图片是在许多场景下都非常有用的操作&#xff0c;不仅能够保留原始文档的内容&#xff0c;还方便在各种平台上共享和展示。在本文中&#xff0c;我们将介绍三种简便的方法&#xff0c;帮助您将PDF文件快速转换为图片格式。 方法一&#xff1a;使用记灵在线工具…

黑客是这样的炼成的

---黑客的态度 黑客们解决问题&#xff0c;建设事物&#xff0c;信仰自由和双向的帮助&#xff0c;人人为我, 我为人人。 要想被认为是一名黑客&#xff0c;你的行为必须显示出你已经具备了这种态度。要想做的好象你具备这种态度&#xff0c;你就不得不真的具备这种态度。但…

物理人机交互Physical human-robot interaction (pHRI)

物理人机交互是指人与机器之间通过物理接触或力传递进行交互的过程。它可以通过各种感知和操控技术实现,包括传感器、执行器、机器人和人体接口等。这种交互方式可以在多个领域和应用中发挥重要作用,例如机器人操作、虚拟现实、协作机器人和康复医疗等。 在物理人机交互中,…