SpringCloud - Spring Cloud Netflix 之 Hystrix熔断器(七)
阅读本文前可先参考
SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客
在微服务架构中,一个应用往往由多个服务组成,这些服务之间相互依赖,依赖关系错综复杂。
如下图所示,我们有3个微服务 订单服务,库存服务,用户服务形成一个微服务系统
请求1需要调用 订单服务,库存服务,用户服务 3个服务才能完成
一、熔断器
熔断器(Circuit Breaker)一词来源物理学中的电路知识,它的作用是当线路出现故障时,迅速切断电源以保护电路的安全。
二、Hystrix
1、服务降级
Hystrix 提供了服务降级功能,能够保证当前服务不受其他服务故障的影响,提高服务的健壮性。
1、新建一个springboot Module(springcloud-6-service-eureka-hystrix-consumer),设置父项目 (服务消费者)
2、添加 hystrix 依赖,spring-cloud-starter-netflix-hystrix
<!-- spring-cloud-starter-netflix-hystrix --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>
<!--继承统一的父项目--><parent><groupId>com.company</groupId><artifactId>springcloud-demo</artifactId><version>1.0.0</version>
<!-- <relativePath/> <!– lookup parent from repository –>--></parent><groupId>com.company</groupId><artifactId>springcloud-6-service-eureka-hystrix-consumer</artifactId><version>1.0.0</version><name>springcloud-6-service-eureka-hystrix-consumer</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><!--spring web 起步依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--依赖统一的springcloud-service-commons项目--><dependency><groupId>com.company</groupId><artifactId>springcloud-2-service-common</artifactId><version>1.0.0</version></dependency><!-- springboot 开发自动热部署 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!--spring-cloud-starter-netflix-eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- spring-cloud-starter-netflix-hystrix --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
3、application.prperties配置文件中配置访问端口8081,以及配置超时时间
#hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器
#链接超时时长(建立连接后从服务端读取到可用资源所用的时间)
ribbon.ReadTimeout=6000
#feign.client.config.default.read-timeout=6000
#读取超时时长(建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间)
ribbon.ConnectTimeout=3000
#feign.client.config.default.connect-timeout=3000#如果hystrix.command.default.execution.timeout.enabled为true,则会有两个执行方法超时的配置,一个就是ribbon的ReadTimeout,一个就是熔断器hystrix的timeoutInMilliseconds, 此时谁的值小谁生效;
#如果hystrix.command.default.execution.timeout.enabled为false,则熔断器不进行超时熔断,而是根据ribbon的ReadTimeout抛出的异常而熔断,也就是取决于ribbon的ConnectTimeout,配置的是请求服务的超时时间,除非服务找不到,或者网络原因,这个时间才会生效;
#设置HystrixCommand.run()的执行是否有超时限制
#hystrix.command.default.execution.timeout.enabled=false
#设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,并执行回退逻辑
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
server.port=8081#设置应用名称,对应Eureka控制台下 DS Replicas 的 Application
spring.application.name=springcloud-6-service-eureka-hystrix-consumer#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=30
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=60
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false#注册服务实例ID,,服务ID必须唯一
eureka.instance.instance-id=springcloud-6-service-eureka-hystrix-consumer
#注册中心的链接地址 http://localhost:8761/eureka
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka#hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器
#链接超时时长(建立连接后从服务端读取到可用资源所用的时间)
ribbon.ReadTimeout=6000
#feign.client.config.default.read-timeout=6000
#读取超时时长(建立连接所用的时间,适用于网络状况正常的情况下,两端连接所需要的时间)
ribbon.ConnectTimeout=3000
#feign.client.config.default.connect-timeout=3000#如果hystrix.command.default.execution.timeout.enabled为true,则会有两个执行方法超时的配置,一个就是ribbon的ReadTimeout,一个就是熔断器hystrix的timeoutInMilliseconds, 此时谁的值小谁生效;
#如果hystrix.command.default.execution.timeout.enabled为false,则熔断器不进行超时熔断,而是根据ribbon的ReadTimeout抛出的异常而熔断,也就是取决于ribbon的ConnectTimeout,配置的是请求服务的超时时间,除非服务找不到,或者网络原因,这个时间才会生效;
#设置HystrixCommand.run()的执行是否有超时限制
#hystrix.command.default.execution.timeout.enabled=false
#设置调用者等待命令执行的超时限制,超过此时间,HystrixCommand被标记为TIMEOUT,并执行回退逻辑
#hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
@EnableHystrix //开启Hystrix的服务熔断降级支持
@EnableFeignClients //表示开启 Spring Cloud OpenFeign的支持功能
@EnableEurekaClient //开启 Eureka client服务
@SpringBootApplication
public class EurekaHystrix6ConsumerApplication {public static void main(String[] args) {SpringApplication.run(EurekaHystrix6ConsumerApplication.class, args);}
}
5、使用 springcloud-2-service-common 项目中的 ProviderGoodsRemoteClient 服务接口
@Component
@FeignClient("springcloud-6-service-eureka-hystrix-provider")
//@FeignClient("springcloud-5-service-eureka-openfeign-provider")
public interface ProviderGoodsRemoteClient {/*** 声明一个feign的接口,它的实现是服务提供者的controller实现*/@GetMapping(value = "/eureka/hystrix/service/goodList")
// @GetMapping(value = "/eureka/openfeign/service/goodList")public List<Goods> goods();
}
server.port=9001#设置应用名称,对应Eureka控制台下 DS Replicas 的 Application(集群部署服务提供者,Application一致,对应多个eureka.instance.instance-id)
spring.application.name=springcloud-6-service-eureka-hystrix-provider#设置mysql数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=admin123456#每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
eureka.instance.lease-renewal-interval-in-seconds=5
#告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
eureka.instance.lease-expiration-duration-in-seconds=10
#告诉服务端,服务实例以IP作为链接,不是取机器名
eureka.instance.prefer-ip-address=false#注册服务实例ID,,服务ID必须唯一
eureka.instance.instance-id=springcloud-6-service-eureka-hystrix-provider
#注册中心的链接地址 http://localhost:8761/eureka
eureka.client.service-url.defaultZone=http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
@RestController
public class GoodsController {@Autowiredprivate GoodsService goodsService;@GetMapping(value = "/eureka/hystrix/service/goodList")public List<Goods> goodList(){List<Goods> goodsList = goodsService.getAllGoods();System.out.println("查询商品列表成功:");for (Goods good:goodsList) {System.out.println("查询商品:"+ good);}return goodsList;}
}
注:hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器
//1、服务超时,会降级try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}//2、服务异常,会降级/*String str = null;if (str == null) {throw new RuntimeException("服务异常了.");}*/
hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器
1、使用application.properties配置文件中的配置
ribbon.ReadTimeout=6000
ribbon.ConnectTimeout=3000hystrix.command.default.execution.timeout.enabled=true hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=5000
hystrix.command.default.execution.timeout.enabled=true;
application.properties配置文件可以不写 1 中配置
@HystrixProperty(name = "execution.timeout.enabled",value = "true"), @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")
commandProperties:hystrix属性设置,包括超时设置
threadPoolkey:线程池唯一标识threadPoolProperties:线程池属性设置,包括核心线程树和队列大小,可以做限流
@RestController
public class GoodsController {//产品服务的接口地址(直连)
// private final String GOODS_SERVICE_URL = "http://localhost:9001/service/goodList";//产品服务的接口地址 (注册中心服务名)
// private final String GOODS_SERVICE_EUREKA_HYSTRIX_URL = "http://springcloud-6-service-eureka-hystrix-provider/eureka/hystrix/service/goodList";@Autowiredprivate ProviderGoodsRemoteClient providerGoodsRemoteClient;@Autowiredprivate RestTemplate restTemplate;@GetMapping(value = "/springcloud/eureka/hystrix/goodList")@HystrixCommand(fallbackMethod = "fallback",commandProperties = {/*hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器1、使用application.properties配置文件中的ribbon.ReadTimeout=6000ribbon.ConnectTimeout=3000hystrix.command.default.execution.timeout.enabled=truehystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=50002、或者此处的 hystrix.command.default.execution.timeout.enabled=true;application.properties配置文件可以不写 1 中配置@HystrixProperty(name = "execution.timeout.enabled",value = "true"),@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")如果hystrix.command.default.execution.timeout.enabled为false,则熔断器不进行超时熔断,而是根据ribbon的ReadTimeout抛出的异常而熔断,也就是取决于ribbon的ConnectTimeout,配置的是请求服务的超时时间,除非服务找不到,或者网络原因,这个时间才会生效;* */
// @HystrixProperty(name = "execution.timeout.enabled",value = "false"),
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},ignoreExceptions = Throwable.class)public @ResponseBody Object getGoodList(){//hystrix 默认超时时间是 1000 毫秒,如果你后端的响应超过此时间,就会触发断路器//1、服务超时,会降级try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}//2、服务异常,会降级/*String str = null;if (str == null) {throw new RuntimeException("服务异常了.");}*/// 调用远程的一个controller, restful的调用,通过openfeign这种声明式的远程调用,providerGoodsRemoteClient就像dubbo里面的接口层一样return providerGoodsRemoteClient.goods();//调用远程的一个controller(Restful风格调用)
// ResponseEntity<Object> responseEntity = restTemplate.getForEntity(GOODS_SERVICE_EUREKA_HYSTRIX_URL, Object.class);
// return responseEntity.getBody();}public @ResponseBody Object fallback(Throwable throwable){throwable.printStackTrace();System.out.println(throwable.getMessage());return "/springcloud/eureka/hystrix/goodList 服务降级了";}
}
Hystrix异常处理
1、我们在调用服务提供者时,服务提供者可能抛出异常,我们自己也可能抛异常,默认情况下方法抛了异常会自动进行服务降级,交给服务降级中的方法去处理;
当我们自己发生异常后,只需要在服务降级方法中添加一个 Throwable 类型的参数就能够获取到抛出的异常的类型
public @ResponseBody Object fallback(Throwable throwable){throwable.printStackTrace();System.out.println(throwable.getMessage());return "/springcloud/eureka/hystrix/goodList 服务降级了";}
2、 如果远程服务有一个异常抛出后我们不希望进入到服务降级方法中去处理,而是直接将异常抛给用户,那么我们可以在@HystrixCommand 注解中添加忽略异常
@HystrixCommand(fallbackMethod = "fallback", ignoreExceptions=Throwable.class)
2、请求限流
Hystrix限流就是限制你某个微服务的使用量(可用线程数、信号量)
Hystrix通过线程池的方式来管理微服务的调用,它默认是一个线程池(大小10个) 管理你的所有微服务,可以给某个微服务开辟新的线程池
@HystrixCommand(fallbackMethod = "fallback",//threadPoolKey 是线程池唯一标识, hystrix 会使用该标识来计数,看线程占用是否超过了, 超过了就会直接降级该次调用threadPoolKey = "goodsService",threadPoolProperties = {//coreSize,线程池核心线程数,默认为10;值为2 那么假设你这个方法调用时间是1s执行完, 那么在1s内如果有超过2个请求进来的话,剩下的请求则全部降级@HystrixProperty(name = "coreSize", value = "2"),//maxQueueSize,线程队列,如果maxQueueSize=-1的话,则该选项不起作用;里面只能放一个请求线程,本来线程数有2个,队列里面允许放一个,那么总共只能有3个请求线程执行,如果超过了就会限流@HystrixProperty(name = "maxQueueSize", value = "1")})@GetMapping(value = "/springcloud/eureka/hystrix/goodLimitList")public @ResponseBody Object getGoodLimitList(){ResponseEntity<Object> responseEntity = restTemplate.getForEntity(GOODS_SERVICE_EUREKA_HYSTRIX_URL, Object.class);return responseEntity.getBody();}
SpringCloud - Spring Cloud Netflix 之 Hystrix熔断器(七)相关推荐
- SpringCloud - Spring Cloud Netflix 之 Hystrix ;turbine(十)
阅读本文前可先参考 SpringCloud - Spring Cloud根/父项目,开发准备(二) https://blog.csdn.net/MinggeQingchun/article/detai ...
- SpringCloud - Spring Cloud Netflix 之 Zuul网关;路由(十一)
阅读本文前可先参考 SpringCloud - Spring Cloud根/父项目,开发准备(二)_MinggeQingchun的博客-CSDN博客 一.API网关 引自百度百科 API网关,软件术语 ...
- Spring cloud微服务 Hystrix熔断器
以下demo代码:https://github.com/wades2/HystrixtDemo 官网定义:Hystrix是一个延迟容错库.在分布式环境中,许多服务依赖项中的一些不可避免地会失败.Hys ...
- SpringCloud学习笔记(1)- Spring Cloud Netflix
文章目录 SpringCloud学习笔记(1)- Spring Cloud Netflix 单体应用存在的问题 Spring Cloud Eureka Eureka Server代码实现 Eureka ...
- SpringCloud学习笔记3:Spring Cloud Netflix 组件(五大神兽)
一.Spring Cloud Netflix有哪些组件? eureka (提供服务注册与发现功能) ribbon(提供负载均衡功能) Feign(整合了ribbon和Hystrix,具有负载均衡和熔断 ...
- Spring Cloud Netflix Hystrix
目录 一. Hystrix 简介 1 什么是灾难性雪崩效应 2 什么是 Hystrix 二. 服务降级 1 修改 application service 代码 2 application client ...
- SpringCloud学习笔记(6)----Spring Cloud Netflix之负载均衡-Ribbon的使用
1. 什么是负载均衡? 负载均衡,就是分发请求流量到不同的服务器. 负载均衡一般分为两种 1. 服务器端负载均衡(nginx) 2. 客户端负载均衡(Ribbon) 2. 服务提供者(spring-c ...
- SpringCloud 入门教程(十):和RabbitMQ的整合 -- 消息总线Spring Cloud Netflix Bus
在本教程第三讲Spring Cloud 入门教程(三): 配置自动刷新中,通过POST方式向客户端发送/refresh请求, 可以让客户端获取到配置的最新变化.但试想一下, 在分布式系统中,如果存在很 ...
- spring cloud NetFlix 学习笔记
spring cloud 1.前言 1.1. 概括 1.2 .常见面试题 2. 微服务概述 2.1 什么是微服务? 2.2 微服务与微服务架构 2.3 微服务优缺点 2.4 微服务技术栈有那些? 2. ...
最新文章
- 用Spark和DBSCAN对地理定位数据进行聚类
- String : string的长度?string的子串?
- MyEclipse使用总结——MyEclipse文件查找技巧
- 某些书籍翻译的太屎了,误导人!
- Spring 入门学习二之IOC
- HttpClient的性能隐患
- mysql isolation_mysqltx_isolation
- qt 如何 指针 自动 释放内存_要是面试官再问你智能指针的问题,就拿这篇文章“盘他”!!!...
- linux cam软件,基于Linux图形交互式线切割CAM软件实现技术研究
- FRM-10102错误解决
- 初探数据湖(Data Lake),到底有什么用?让我们来一窥究竟...
- 中国人民银行 中国银行业监督管理委员会关于印发农村信用社改革试点专项中央银行票据兑付考核办法的通知(银发[2004]253号)
- 青云很忙 QingCloud Insight 2017开幕倒计时
- 功能测试_测试用例设计方法
- Airflow2.2.5任务调度工具
- win7 安装超级终端
- Q for Mortals2笔记 -- 原子数据类型
- 最新学习通JS逆向分析
- OGC的WebGIS相关标准
- 是否可以将频谱分析仪当做网络分析仪使用?