小工具      在线工具  汉语词典  css  js  c++  java

Spring Cloud Netflix Hystrix

# Spring Cloud,微服务,java,spring cloud,hystrix 额外说明

收录于:152天前

Hystrix简介

在微服务架构中,每个服务都是独立部署的,服务之间存在相互依赖关系。与单体系统相比,微服务架构中服务访问失败的原因和场景非常复杂,这需要我们从服务可靠性的角度来设计服务本身以及服务之间的交互流程。服务可靠性是微服务架构的关键要素之一。

服务可靠性问题同时涉及服务的提供者和消费者 对于服务提供者而言,要做的事情比简单,一旦自身服务发生错误,那么应该快速返回合理的处理结果,也就是要做到快速反馈。而对于服务消费者而言, 事情就比较复杂了,一方面可以采用超时( Timeout)
和重试( Retry 常见方法),另一方面也有一些模式对服务提供者发生失败的场景。
在这里插入图片描述
负载均衡是提高系统的性能,而服务熔断是提高服务消费者的容错机制则防止服务故障而导致的系统问题。这些机制包括服务隔离,服务熔断,服务回退,服务限流

  • 服务断路器

熔断器的概念来源于电子工程中的保险丝。在互联网系统中,当下游服务因访问压力过大而响应缓慢或失败时,上游可以暂时切断对下游服务的调用,以保障系统整体可用性。这种牺牲部分、保留整体的措施称为断路器。

在这里插入图片描述

  • 服务降级

服务降级是指当某个服务断开后,服务器将不再被调用。这时,客户端可以准备一个本地的Fallback回调来返回一些数据。

  • 服务限流

业务限流是限制系统的输入输出流量,以保护系统。一般来说,系统的吞吐量是可以预测的。为了保障系统的稳定运行,一旦达到需要限流的阈值,就需要进行限流,并采取少量的措施来达到限流的目的。

  • 服务隔离

服务隔离就是按照一定的原则将系统划分为若干个模块。各模块之间相对对立,没有很强的依赖性。当出现故障时,可以将问题隔离在某个模块内,使风险不扩散,不影响整体系统服务。

  • 服务回滚

服务回滚是处理服务依赖引起的异常时有效的容错机制。当远程调用发生异常时,服务回滚并不直接抛出异常,而是生成另一种机制来处理异常,相当于执行另一条路径上的代码返回的处理结果。

Hystrix组件对Web Service的支持

支持 RestTemplate

  1. 引入hystrix依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.2.RELEASE</version>
        </dependency>
  1. @EnableHystrix启动类激活Hystrix

在这里插入图片描述
@EnableCircuitBreaker在3.0.1版本中已经移除了,2点多版本显示过时。改用@EnableHystrix实现了前者全部功能。

@SpringBootApplication
@EnableDiscoveryClient
//hystrix熔断处理
//@EnableCircuitBreaker 已过时
@EnableHystrix

public class ProviderServiceApplication {
    

    public static void main(String[] args) {
    
        SpringApplication.run(ProviderServiceApplication.class, args);
    }

}
  1. 配置断路器触发降级逻辑
    /** * 服务降级策略,要求参数和返回值一致 */
    BillMessage default_billMessage(Integer id){
    
        BillMessage billMessage = new BillMessage();
        billMessage.setStatus(500);
        billMessage.setMessage("服务器繁忙,请稍后再试!");
        billMessage.setBill(null);
        return billMessage;
    }

//降级处理当服务未响应时配置本地的返回数据
  1. @HystrixCommand注解声明接口保护
//声明式熔断保护,参数配置降级策略
@HystrixCommand(fallbackMethod = "default_billMessage")
@GetMapping(value = "/hystrix/{id}")
BillMessage method1(@Autowired RestTemplate restTemplate, @PathVariable("id") Integer id){
    
    BillMessage forObject = restTemplate.getForObject("http://localhost:8081/bill/" + id, BillMessage.class);
    return forObject;
}

各模块完整代码

控制器

@RestController
@RequestMapping(value = "/provider")


public class ProviderController {
    
    @Autowired
    ProviderService providerService;

    @Autowired RestTemplate restTemplate;

    @GetMapping(value = "/{id}")
    ProviderMessage getById(@PathVariable int id){
    
        ProviderMessage byId = providerService.getById(id);
        return byId;
    }


    //声明式熔断保护,参数配置降级策略
    @HystrixCommand(fallbackMethod = "default_billMessage")
    @GetMapping(value = "/hystrix/{id}")
    BillMessage method1(@PathVariable("id") Integer id){
    
        BillMessage forObject = restTemplate.getForObject("http://localhost:8081/bill/" + id, BillMessage.class);
        return forObject;
    }

	/** * 服务降级策略,要求参数和返回值一致 */
    BillMessage default_billMessage(Integer id){
    
        BillMessage billMessage = new BillMessage();
        billMessage.setStatus(500);
        billMessage.setMessage("服务器繁忙,请稍后再试!");
        billMessage.setBill(null);
        return billMessage;
    }
}

假客户端

@FeignClient(name = "bill-service")
public interface BillClient {
    
    @GetMapping(value = "/bill/{id}")
    BillMessage method1(@PathVariable("id") Integer id);
}

启动服务:
在这里插入图片描述
服务之间的调用关系
在这里插入图片描述
启动熔断处理后访问接口:
在这里插入图片描述
关闭BillService服务模拟服务未响应的错误,再次访问接口:

在这里插入图片描述

在这里插入图片描述
返回本地数据数据熔断处理及服务降级生效。

如果所有接口的返回值类型是一样的就可以配置公共的降级处理方法@DefaultProperties参数配置为某个方法时,无需在单个接口处再次配置方法。

对假装的支持

  1. feign组件的配置和启动

Spring Cloud Netflix Feign 配置配置完成后访问接口:

/** * feign代理api接口 * */
@Autowired private BillClient billClient;

@GetMapping(value = "/feign/{id}")
BillMessage method2(@PathVariable("id") Integer id){
    
    BillMessage billMessage = billClient.method1(id);
    return billMessage;
}

在这里插入图片描述

首先配置feign的代理。如果你不知道怎么做,可以看我之前的文章。访问成功。

  1. 配置hystrix组件
  • 导入依赖项
 <dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
     <version>2.2.2.RELEASE</version>
 </dependency>
  • 配置文件启用feign对hystrix的支持
feign.hystrix.enabled=true
  • feign代理作为降级方法的实现类

在这里插入图片描述

@FeignClient(name = "bill-service", fallback = BillClientImpl.class)
public interface BillClient {
    
    @GetMapping(value = "/bill/{id}")
    BillMessage method1(@PathVariable("id") Integer id);
}
public class BillClientImpl implements BillClient {
    
    @Override
    public BillMessage method1(Integer id) {
    
        BillMessage billMessage = new BillMessage();
        billMessage.setBill(null);
        billMessage.setMessage("feign配置hystrix返回服务器繁忙!");
        billMessage.setStatus(500);
        return billMessage;
    }
}
  1. 启动类配置hystrix的启动注解@EnableHystrix
@SpringBootApplication
@EnableDiscoveryClient
//hystrix熔断处理
//@EnableCircuitBreaker 已过时
@EnableHystrix

//feign的配置
@EnableFeignClients
public class ProviderServiceApplication {
    

    @Bean
    public RestTemplate getRestTemplate(){
    
        return new RestTemplate();
    }

    public static void main(String[] args) {
    
        SpringApplication.run(ProviderServiceApplication.class, args);
    }

}

启动服务

在这里插入图片描述
访问消费者接口
在这里插入图片描述
停掉hystrix管理的服务模拟服务繁忙
在这里插入图片描述

启动后访问hystrix管理的feign接口发现500错误。检查原因后发现hystrix没有生效。

解决feign.hystrix.enabled:=true配置不生效的原因

原因是:feign.hystrix.enabled=true是springcloud2020以前的版本,而之后的版本是:feign.circuitbreaker.enabled=true

修改配置后,重启服务,访问hystrix管理的界面:

在这里插入图片描述

Hystrix服务断路器和降级处理方法,使用feign和RestTemplate的区别主要在于服务降级:

    //声明式熔断保护,参数配置降级策略
    @HystrixCommand(fallbackMethod = "default_billMessage")
    @GetMapping(value = "/hystrix/{id}")
    BillMessage method1(@PathVariable("id") Integer id){
    
        BillMessage forObject = restTemplate.getForObject("http://localhost:8081/bill/" + id, BillMessage.class);
        return forObject;
    }
    /** * 服务降级策略,要求参数和返回值一致 */
    BillMessage default_billMessage(Integer id){
    
        BillMessage billMessage = new BillMessage();
        billMessage.setStatus(500);
        billMessage.setMessage("服务器繁忙,请稍后再试!");
        billMessage.setBill(null);
        return billMessage;
    }

RestTemplate服务降级在controller层定义降级方法,并通过熔断保护注解的fallbackMethod参数配置

feign代理使用feign代理接口的接口实现类作为降级方法:

在这里插入图片描述

@FeignClient(name = "bill-service", fallback = BillClientImpl.class)
public interface BillClient {
    
    @GetMapping(value = "/bill/{id}")
    BillMessage method1(@PathVariable("id") Integer id);
}
@Component
public class BillClientImpl implements BillClient {
    
    @Override
    public BillMessage method1(Integer id) {
    
        BillMessage billMessage = new BillMessage();
        billMessage.setBill(null);
        billMessage.setMessage("feign配置hystrix返回服务器繁忙!");
        billMessage.setStatus(500);
        return billMessage;
    }
}

接口实现类要注入到spring 容器中,并在父接口中通过fallback参数声明降级方法类

两种实现方法的完整代码如下,包括controller层的feign代理接口:

controller

@RestController
@RequestMapping(value = "/provider")


public class ProviderController {
    
    @Autowired
    ProviderService providerService;

    @Autowired RestTemplate restTemplate;

    @GetMapping(value = "/{id}")
    ProviderMessage getById(@PathVariable int id){
    
        ProviderMessage byId = providerService.getById(id);
        return byId;
    }


    //声明式熔断保护,参数配置降级策略
    @HystrixCommand(fallbackMethod = "default_billMessage")
    @GetMapping(value = "/hystrix/{id}")
    BillMessage method1(@PathVariable("id") Integer id){
    
        BillMessage forObject = restTemplate.getForObject("http://localhost:8081/bill/" + id, BillMessage.class);
        return forObject;
    }
    /** * 服务降级策略,要求参数和返回值一致 */
    BillMessage default_billMessage(Integer id){
    
        BillMessage billMessage = new BillMessage();
        billMessage.setStatus(500);
        billMessage.setMessage("服务器繁忙,请稍后再试!");
        billMessage.setBill(null);
        return billMessage;
    }


    /** * feign代理api接口 * */

    @Resource
    private BillClient billClient;

    @HystrixCommand
    @GetMapping(value = "/feign/{id}")
    BillMessage method2(@PathVariable("id") Integer id){
    
        BillMessage billMessage = billClient.method1(id);
        return billMessage;
    }

}

feignclient

@FeignClient(name = "bill-service", fallback = BillClientImpl.class)
public interface BillClient {
    
    @GetMapping(value = "/bill/{id}")
    BillMessage method1(@PathVariable("id") Integer id);
}


feignclientimpl


@Component
public class BillClientImpl implements BillClient {
    
    @Override
    public BillMessage method1(Integer id) {
    
        BillMessage billMessage = new BillMessage();
        billMessage.setBill(null);
        billMessage.setMessage("feign配置hystrix返回服务器繁忙!");
        billMessage.setStatus(500);
        return billMessage;
    }
}

总结

使用feign作为服务调用方的hystrix集成分为四步:

  • 引入hystrix依赖:
<dependency>
   <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>
  • feign 开启对 hystrix 的支持
feign.circuitbreaker.enabled=true
  • 定义fein代理接口的实现类作为服务降级触发的降级逻辑,并在接口注解使用fallback声明该类
//接口
@FeignClient(name = "bill-service", fallback = BillClientImpl.class)


//实现类
/* 实现类要注入到spring容器中 */
@Component
public class BillClientImpl implements BillClient {
    
    @Override
    public BillMessage method1(Integer id) {
    
        BillMessage billMessage = new BillMessage();
        billMessage.setBill(null);
        billMessage.setMessage("feign配置hystrix返回服务器繁忙!");
        billMessage.setStatus(500);
        return billMessage;
    }
}

  • 接口开启hystrix熔断保护@HystrixCommand
    @HystrixCommand
    @GetMapping(value = "/feign/{id}")
    BillMessage method2(@PathVariable("id") Integer id){
    
        BillMessage billMessage = billClient.method1(id);
        return billMessage;
    }

Hystrix监控平台

除了实现容错功能外,Hystrix还提供了近乎实时的监控HystrixCommand和HystrixObservableCommand在执行时会生成执行结果和运行指标。这些状态会暴露在Actuator提供的health端点中。只需为项目添加spring-boot-actuator依赖重启项目即可,访问地址http://localhost:9000/actuator/hystrix.stream可看到监控数据(端口是启用hystrix熔断保护的端口)。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

在这里插入图片描述

发现没有找到hystrix服务,检查执行器暴露的接口:

在这里插入图片描述
需要通过配置暴露接口:

management.endpoints.web.exposure.include=*

重启项目会不断ping回hystrix熔断保护信息:

在这里插入图片描述
这时只要访问一个由hystrix熔断保护的接口,监控系统就会返回该接口的监控信息:

在这里插入图片描述

在这里插入图片描述
可以看到上面文本式的监控信息很不直观,spring cloud提供了DashBoard的图像化监控。Hystrix仪表盘可以显示每个熔断保护的接口及注解了@HystrixCommand的接口。

要使用hystrix仪表板,您需要导入另一个依赖项:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

再启动类上添加@EnableHystrixDashboard

在这里插入图片描述
重启服务,输入http://localhost:8082/hystrix端口是开启熔断保护的端口。

在这里插入图片描述
仪表盘有很多功能,如果要实现对hystrix熔断保护的实时监控,需要输入url地址即http://localhost:9000/actuator/hystrix.stream,点击Monitor Stream就会跳转到熔断保护的接口信息:

在这里插入图片描述
该接口服务在未访问的情况下是没有任何信息的,访问一下熔断保护的接口:
在这里插入图片描述

在这里插入图片描述
相关信息含义
在这里插入图片描述

上述仪表板可以监控某个端口下的业务熔断情况。对于其他接口,需要不断切换来监控其他接口。这显然是非常麻烦的。 Hystrix还提供了Turbine方法来帮助全局监控整个系统。

在这里插入图片描述

使用涡轮机也非常简单,只需两步即可完成。

  • 导入依赖项:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
    <version>2.2.2.RELEASE</version>
</dependency>

  • 配置涡轮机
# turbine

# 如果监控多个微服务用逗号隔开
turbine.app-config=provider-service


turbine.cluster-name-expression=default

turbine会自动从注册中心自动获取需要监控的微服务,并聚合所有的微服务到/hystrix.stream接口。

Hystrix基本原理

服务隔离

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Hystrix使用命令模式的实现类 HystrixCommand 包装依赖调用逻辑,将每个类型的业务类型请求封装成对应的命令,每个命令在单独线程中执行 创建好的线程池被放入到
ConcurrentHashMap 中,当第二次查询请求过来时,可以直接从 Map中获取该线程池。

在这里插入图片描述
在这里插入图片描述
HystrixCommand 在执行过程中,执行业务代码的线程与请求线程(比如 Tomcat 线程)分离,请求线程可以自由控制离开的时间,这也就是通常所说的异步编程, Hystrix 是结合RxJava 来实现的异步编程,内部大量使用了 RxJava。RxJava 是一个响应式编程框架 ,可以参考其官方网站做进一步了解 Hystrix 通过设置线程池大小来控制并发访问 ,当线程饱和时可以拒绝服务,防止依赖问题扩散。Hystrix 使用线程池存储当前请求以及对请求做出处理 通过设置任务处理超时时间,并将堆积的请求放入线程池队列,可以应对突发流量。 当流量洪峰来临时,处理不完的请求可将数据存储到线程池中慢慢处理,当使用信号 Hystrix 使用原子计数器来记录当前运行线程数,新的请求到来时先判断计数器的数值,若超过设 定的最大线程数则丢弃该类型的新请求,若不超过则执行计数器+ l,请求返回时执行计数器一 1。信 号量隔离无法应对突发流量。

在这里插入图片描述
隔离策略的修改配置
在这里插入图片描述

服务断路器

在这里插入图片描述
在这里插入图片描述
结合服务隔离与服务熔断Hystrix的运行流程:

在这里插入图片描述

hystrix配置项

参考

部分图片和内容取自微服务架构实际实践 |郑天民 撰

Sentinel,Hystrix 的替代方案,用于解决服务中断问题。

在这里插入图片描述

在这里插入图片描述
学习视频

. . .

相关推荐

额外说明

Android开发-蓝牙配对自动设置PIN

注册广播 针对指定广播形式,对指定的广播做捕获操作。 <!-- 增加一个配对码广播监听 --> <receiver android:name="com.winstar.minid.bletest.BluetoothReceiver">

额外说明

在 CentOS 8 上安装 Nginx

Nginx是一款高性能的开源Web服务器和反向代理服务器,以其轻量级和高效能而广受欢迎。在本教程中,我们将学习在 CentOS 8 操作系统上安装和配置 Nginx。 步骤 1:更新系统 在安装任何软件之前,让我们先更新系统的软件包列表和已安装的软件包。

额外说明

监控某个表的insert,update,delete的操作

今天遇到个问题,不知道那部操作在一张表中insert,把项目翻了个低产田也无法找到,最后没有办法,只好用触发器来监控某个表的insert,update,delete的操作,具体方法如下,供大家参考参考! 第一步,使用sys授权 如在orcl用户下监控其表

额外说明

java实现对url解析

  /**    * 对经过escape函数加密的url中的字符串进行解密    * @return 解密后的正常字符串    * @param src    * 参数说明 例如:%u5339%u914D%u8BBE%u5907或者/u5339/u914

额外说明

Python 第三节 第十一课

[toc] 元组 tuple 列表属于可变序列, 可以任意改变列表中的元素. 元组属于不可改变序列, 不能修改元组中的元素. 因此, 元组没有增加元素, 修改元素, 删除元素相关的方法.      因此, 我们只需要学习元组的创建和删除, 元组中元素的访

额外说明

27.Python数据库操作(一)【内置数据库SQLite和ORM框架SQLAlchemy】

目录: 每篇前言: Python数据库操作(一) 1.1 SQLite 1.2 ORM框架SQLAlchemy 每篇前言: --作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者

额外说明

40.上下文处理器&&如何自定义上下文处理器并使用

引言——   在前面我们知道在模板中想要使用的变量是从视图函数中的context这个上下文的参数中传递进来的,每个视图函数需要什么参数就传什么参数。   但是,假设我们现在有这么多问题,我需要给多个不同的模板传递几个相同的变量使用,难道我要给每个模板对应

额外说明

使用Clumsy和Process Explorer定位软件高CPU占用问题

目录   1、问题描述 2、使用Process Explorer初步找到CPU占用高的原因 3、使用Clumsy工具在公司内网环境复现了问题

额外说明

Jwt简单使用

在分布式项目中,经常需要处理session共享的问题,解决的方式有很多,比如采用session或者cookie,或者redis进行存储都是解决方案,今天给大家介绍另一种比较轻量级的解决方式,就是使用jwt生成token,服务端进行加解密来处理; 首先要了

额外说明

在SpringBoot中如何整合消息服务组件?

在开发中,消息服务组件在系统架构中扮演着举足轻重的角色。本文将介绍消息服务组件的基本概念,以及如何在SpringBoot中整合常见的消息服务组件,如ActiveMQ、RabbitMQ和Kafka。最后,我们将探讨整合消息服务组件在实际应用场景中的优势。

ads via 小工具