【从0到1设计一个网关】基于Hystrix实现熔断降级

上文我们已经成功实现了请求重试与请求限流,接下来我们开始实现熔断与服务降级。 熔断与服务降级,在SpringCloud中设计到的就是我们的hystrix,这里我们也将会考虑配合hystrix来实现熔断与服务降级。 如果不了解hystix的可以先进行一下了解。

依赖引入

由于这里我是用的是基于hystrix的熔断降级,所以首先需要将服务整合hystrix

c 复制代码
	<hystrix.core.version>1.5.12</hystrix.core.version>
        <hystrix.javanica.version>1.5.12</hystrix.javanica.version>
        <hystrix.metrics.version>1.5.12</hystrix.metrics.version>
               <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-core</artifactId>
            <version>${hystrix.core.version}</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-metrics-event-stream</artifactId>
            <version>${hystrix.metrics.version}</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
            <version>${hystrix.javanica.version}</version>
        </dependency>

引入如上的依赖之后,我们就可以开始基于hystrix编写如何进行熔断限流了。 我先贴出一套代码来大致介绍一下如何使用hystrix实现熔断降级。

java 复制代码
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixThreadPoolProperties;

public class MyHystrixCommand extends HystrixCommand<String> {

    private final String fallbackValue;

    protected MyHystrixCommand(String fallbackValue) {
        super(Setter
            .withGroupKey(HystrixCommandGroupKey.Factory.asKey("MyGroup"))
            .andCommandKey(HystrixCommandKey.Factory.asKey("MyCommand"))
            .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                .withExecutionTimeoutInMilliseconds(1000)) // 设置超时时间
            .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                .withCoreSize(10) // 设置线程池大小
            );
        this.fallbackValue = fallbackValue;
    }

    @Override
    protected String run() throws Exception {
        // 执行你的业务逻辑
        return "Result of the actual operation";
    }

    @Override
    protected String getFallback() {
        // 执行降级逻辑
        return fallbackValue;
    }
}

上述代码中,我创建了一个自定义的 MyHystrixCommand 类,继承自 HystrixCommand 类。在该类的构造函数中,你可以配置Hystrix的一些属性,如组、命令名称、执行超时等。然后,你需要实现 run 方法来执行实际的业务逻辑,以及 getFallback 方法来执行降级逻辑。

接下来,你可以在应用中使用这个自定义的Hystrix命令:

java 复制代码
String result = new MyHystrixCommand("Fallback Value").execute();

通过调用 execute 方法,你可以执行Hystrix命令,如果发生熔断,将会执行降级逻辑,返回降级值。

这种方式允许你更细粒度地控制熔断和降级的行为,但需要手动配置Hystrix的属性,如超时时间、线程池大小等。你可以根据具体需求进行定制。 所以,根据上面的情况,我们就已经大概知道了如何基于hystrix实现一套熔断降级的逻辑了。

服务降级

那么接下来我们来编写具体的实现代码。 首先,我们需要在配置中心的配置中添加出来对hystrix的配置。

java 复制代码
"hystrixConfigs":[{
                "path":"/http-server/ping",
                "timeoutInMilliseconds":5000,
                "threadCoreSize":2,
                "fallbackResponse":"熔断超时"
            }]

之后,我们知道我们的具体执行逻辑是走过滤器的,所以我们需要在我们的路由过滤器这里添加额外的对hystrix的配置,来监测我们最后转发请求的时候,如果这个请求处理失败或者超时时,要让他进行熔断降级的逻辑。

java 复制代码
 @Override
    public void doFilter(GatewayContext gatewayContext) throws Exception {
        //首先获取熔断降级的配置
        Optional<Rule.HystrixConfig> hystrixConfig = getHystrixConfig(gatewayContext);
        //如果存在对应配置就走熔断降级的逻辑
        if (hystrixConfig.isPresent()) {
            routeWithHystrix(gatewayContext, hystrixConfig);
        } else {
            route(gatewayContext, hystrixConfig);
        }
    }
 /**
     * 获取hystrix的配置
     *
     * @param gatewayContext
     * @return
     */
    private static Optional<Rule.HystrixConfig> getHystrixConfig(GatewayContext gatewayContext) {
        Rule rule = gatewayContext.getRule();
        Optional<Rule.HystrixConfig> hystrixConfig =
                rule.getHystrixConfigs().stream().filter(c -> StringUtils.equals(c.getPath(),
                        gatewayContext.getRequest().getPath())).findFirst();
        return hystrixConfig;
    }

可以看到,我上面的代码就是从配置中心中获取到hystrix的配置,然后判断如果存在熔断降级的配置就走熔断降级的逻辑。 原先的没有熔断降级时候的route逻辑不用改变,我们需要额外创建一个方法,当存在熔断降级逻辑时走这个方法。 这里就按照我们上一节提到的代码的编写方式,进行代码的编写和配置即可。

java 复制代码
 /**
     * 根据提供的GatewayContext和Hystrix配置,执行路由操作,并在熔断时执行降级逻辑。
     * 熔断会发生在:
     * 当 Hystrix 命令的执行时间超过配置的超时时间。
     * 当 Hystrix 命令的执行出现异常或错误。
     * 当连续请求失败率达到配置的阈值。
     * @param gatewayContext
     * @param hystrixConfig
     */
    private void routeWithHystrix(GatewayContext gatewayContext, Optional<Rule.HystrixConfig> hystrixConfig) {

        HystrixCommand.Setter setter =  //进行分组
                HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(gatewayContext.getUniqueId()))
                        .andCommandKey(HystrixCommandKey.Factory.asKey(gatewayContext.getRequest().getPath()))
                        //线程池大小设置
                        .andThreadPoolPropertiesDefaults(HystrixThreadPoolProperties.Setter()
                                .withCoreSize(hystrixConfig.get().getThreadCoreSize()))
                        .andCommandPropertiesDefaults(HystrixCommandProperties.Setter()
                                //线程池
                                .withExecutionIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD)
                                //超时时间
                                .withExecutionTimeoutInMilliseconds(hystrixConfig.get().getTimeoutInMilliseconds())
                                .withExecutionIsolationThreadInterruptOnTimeout(true)
                                .withExecutionTimeoutEnabled(true));

        // 创建一个新的HystrixCommand对象,用于执行实际的路由操作。
        new HystrixCommand<Object>(setter) {
            @Override
            protected Object run() throws Exception {
                // 在Hystrix命令中执行路由操作,这是实际的业务逻辑。
                route(gatewayContext, hystrixConfig).get();
                return null;
            }

            @Override
            protected Object getFallback() {
                // 当熔断发生时,执行降级逻辑。
                // 设置网关上下文的响应信息,通常包括一个降级响应。
                gatewayContext.setResponse(hystrixConfig.get().getFallbackResponse());
                gatewayContext.written();
                return null;
            }
        }.execute(); // 执行Hystrix命令。
    }

效果演示

上面的代码编写完毕之后,我们就已经完成了熔断降级了。 接下来我们来看看具体的效果。 启动后端服务,并且让后端服务进行长时间的阻塞。 那么此时就会触发一个超时的异常,此时就会出现熔断降级,

相关推荐
舒一笑32 分钟前
为什么where=Version就是乐观锁了?
后端·mysql·程序员
GoGeekBaird36 分钟前
关于垂类AI应用落地行业的方法论思考
后端·github·agent
小宁爱Python1 小时前
Django 基础入门:命令、结构与核心配置全解析
后端·python·django
你的人类朋友1 小时前
认识一下Bcrypt哈希算法
后端·安全·程序员
tangweiguo030519872 小时前
基于 Django 与 Bootstrap 构建的现代化设备管理平台
后端·django·bootstrap
IT果果日记2 小时前
详解DataX开发达梦数据库插件
大数据·数据库·后端
dazhong20122 小时前
Spring Boot 项目新增 Module 完整指南
java·spring boot·后端
bobz9652 小时前
Cilium + Kubevirt 与 Kube-OVN + Kubevirt 在公有云场景下的对比与选择
后端
David爱编程3 小时前
深度解析:synchronized 性能演进史,从 JDK1.6 到 JDK17
java·后端
脑子慢且灵3 小时前
【JavaWeb】一个简单的Web浏览服务程序
java·前端·后端·servlet·tomcat·web·javaee