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

Spring Cloud Netflix Hystrix

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

收录于:15天前

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 xml中的权限配置

访问登记属性 android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限 获取错略位置 android.permission.ACCESS_COARSE_LOCATION,

额外说明

mysql发现重复数据

  https://blog.51cto.com/13689359/2401599?source=dra   MySQL里查询表里的重复数据记录: 先查看重复的原始数据: 场景一:列出username字段有重读的数据 1 2 3 select usern

额外说明

漏洞复现-YXcms

YXcms 前台XSS 参考手册:https://www.kancloud.cn/yongheng/yxcms/308086 前台XSS <svg/onload=alert(1)> https://xz.aliyun.com/t/11008

额外说明

es通过mapping创建索引出错

问题描述: 最近,我在es中创建索引的时候报出奇怪的错误,问题描述大致如下,这个错误后来验证后发现不少同学也遇到过,主要是es版本的差异造成的, Caused by: ElasticsearchException[Elasticsearch except

额外说明

newstyles项目实战(十九)redis概念以及安装,以及集群环境的模拟建立

redis的背景了解:        Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。(来源于网络

额外说明

Java中,split()方法,在jdk1.6与之后版本的区别

split()方法在jdk1.6的描述:  split()方法在jdk1.9的描述: 两者区别是 当在此字符串的开始处存在正宽度匹配时,在结果数组的开始处包含空的前导子字符串。 开始时的零宽度匹配不会产生这样的空的前导子串。 区别是jdk为1.6的时候,

额外说明

安卓案例:View动画——弹球碰壁

安卓案例:View动画——弹球碰壁 一、运行效果

额外说明

人生做的第一个项目

这是我毕业以来做的第一个项目,是某公司的某个具体的项目,那么,就针对这个项目的原型图,理出我自己的思路来。 当我们看到原型图时,会想到要见哪几张表,这几张表的外键关系如何,怎么取舍这些外键(当然,这一般情况下,是技术总监做的事,虽然,我们是初级程序员,但

额外说明

React(四)React生命周期、发送网络请求、跨域处理

目录 一、react 生命周期 二、发送网络请求 一、react 生命周期         组件的生命周期是指组件从创建到最终的销毁的整个过程,在这个过程中有一些重要的、关键的时间点可以触发对应的函数,这些函数被称为钩子函数。         通用的组件

额外说明

如何使用Adsanity插件在WordPress中管理广告

广告是许多博主的主要收入来源。将 Google Adsense 或其他广告代码添加到 WordPress 并不容易。更不用说,管理不同的广告源可能会更加混乱。在本文中,我们将向您展示如何使用 Adsanity 插件在 WordPress 中管理广告。 广

ads via 小工具