hystrix服务降级(3)
Hystrix使用fallback机制很简单,继承HystrixCommand只需重写getFallback(),继承HystrixObservableCommand只需重写resumeWithFallback(),比如上篇文章的HelloWorldHystrixCommand加上下面代码片段:
@Override
protected String getFallback() {
return "fallback: " + name;
}
fallback实际流程是当run()/construct()被触发执行时或执行中发生错误时,将转向执行getFallback()/resumeWithFallback()。
结合下图,4种情况(出现异常,超时,熔断,线程池已满)将触发fallback:

①run()方法中出现异常(非HystrixBadRequestException异常)或者出现超时()触发fallback()
public class HystrixFallbackNomal extends HystrixCommand<String>{
private final String name;
public HystrixFallbackNomal(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
public String run() throws Exception {
/*---------------会触发fallback的case-------------------*/
// 无限循环,实际上属于超时
/* int j = 0;
while (true) {
j++;
}*/
Thread.sleep(1000);
// 除零异常
// int i = 1/0;
// 主动抛出异常
// throw new HystrixTimeoutException();
// throw new RuntimeException("this command will trigger fallback");
// throw new Exception("this command will trigger fallback");
// throw new HystrixRuntimeException(FailureType.BAD_REQUEST_EXCEPTION, commandClass, message, cause, fallbackException);
/*---------------不会触发fallback的case-------------------*/
// 被捕获的异常不会触发fallback
// try {
// throw new RuntimeException("this command never trigger fallback");
// } catch(Exception e) {
// e.printStackTrace();
// }
// HystrixBadRequestException异常由非法参数或非系统错误引起,不会触发fallback,也不会被计入熔断器
//throw new HystrixBadRequestException("HystrixBadRequestException is never trigger fallback");
//return name;
}
@Override
protected String getFallback() {
return "fallback: " + name;
}
}
}
②熔断触发fallback()
/**
* 熔断机制相当于电路的跳闸功能,例如:我们可以配置熔断策略为当请求错误比例在10s内>50%时,该服务将进入熔断状态,后续请求都会进入fallback
* CircuitBreakerRequestVolumeThreshold设置为3,意味着10s内请求超过3次就触发熔断器(10s这个时间暂时不可配置)
* run()中无限循环使命令超时进入fallback,10s内请求超过3次,将被熔断,进入降级,即不进入run()而直接进入fallback
* 如果未熔断,但是threadpool被打满,仍然会降级,即不进入run()而直接进入fallback
*/
public class HystrixFallbackCircuitBreaker extends HystrixCommand<String>{
private final String name; public HystrixFallbackCircuitBreaker(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("CircuitBreakerTestGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("CircuitBreakerTestKey"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("CircuitBreakerTest"))
.andThreadPoolPropertiesDefaults( // 配置线程池
HystrixThreadPoolProperties.Setter()
.withCoreSize(200) // 配置线程池里的线程数,设置足够多线程,以防未熔断却打满threadpool
)
.andCommandPropertiesDefaults( // 配置熔断器
HystrixCommandProperties.Setter()
.withCircuitBreakerEnabled(true)
.withCircuitBreakerRequestVolumeThreshold(3)
.withCircuitBreakerErrorThresholdPercentage(80)
// .withCircuitBreakerForceOpen(true) // 置为true时,所有请求都将被拒绝,直接到fallback
// .withCircuitBreakerForceClosed(true) // 置为true时,将忽略错误
// .withExecutionIsolationStrategy(ExecutionIsolationStrategy.SEMAPHORE) // 信号量隔离
// .withExecutionTimeoutInMilliseconds(5000)
)
);
this.name = name;
} @Override
protected String run() throws Exception {
System.out.println("running run():" + name);
int num = Integer.valueOf(name);
if(num < 10) { // 直接返回
return name;
} else { // 无限循环模拟超时
int j = 0;
while (true) {
j++;
}
}
// return name;
} @Override
protected String getFallback() {
return "CircuitBreaker fallback: " + name;
}
}
@Test
public void testFallbackCricuitBreaker() throws IOException {
for(int i = 0; i < 50; i++) {
try {
System.out.println("===========" + new HystrixFallbackCircuitBreaker(String.valueOf(i)).execute());
} catch(Exception e) {
System.out.println("run()抛出HystrixBadRequestException时,被捕获到这里" + e.getCause());
}
} System.out.println("------开始打印现有线程---------");
Map<Thread, StackTraceElement[]> map=Thread.getAllStackTraces();
for (Thread thread : map.keySet()) {
System.out.println(thread.getName());
}
System.out.println("thread num: " + map.size()); System.in.read();
}
③线程池已满,触发fallback()
public class HystrixThreadPoolFallback extends HystrixCommand<String>{
private final String name;
public HystrixThreadPoolFallback(String name) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("ThreadPoolTestGroup"))
.andCommandKey(HystrixCommandKey.Factory.asKey("testCommandKey"))
.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolTest"))
.andCommandPropertiesDefaults(
HystrixCommandProperties.Setter()
.withExecutionTimeoutInMilliseconds(5000)
)
.andThreadPoolPropertiesDefaults(
HystrixThreadPoolProperties.Setter()
.withCoreSize(3) // 配置线程池里的线程数
)
);
this.name = name;
}
@Override
protected String run() throws Exception {
System.out.println(name);
TimeUnit.MILLISECONDS.sleep(2000);
return name;
}
@Override
protected String getFallback() {
return "fallback: " + name;
}
}
@Test
public void testThreadPool() throws IOException {
for(int i = 0; i < 10; i++) {
try {
Future<String> future = new HystrixThreadPoolFallback("Hlx"+i).queue();
} catch(Exception e) {
System.out.println("run()抛出HystrixBadRequestException时,被捕获到这里" + e.getCause());
}
}
for(int i = 0; i < 20; i++) {
try {
System.out.println("===========" + new HystrixThreadPoolFallback("Hlx"+i).execute());
} catch(Exception e) {
System.out.println("run()抛出HystrixBadRequestException时,被捕获到这里" + e.getCause());
}
}
try {
TimeUnit.MILLISECONDS.sleep(2000);
}catch(Exception e) {}
System.out.println("------开始打印现有线程---------");
Map<Thread, StackTraceElement[]> map=Thread.getAllStackTraces();
for (Thread thread : map.keySet()) {
System.out.println(thread.getName());
}
System.out.println(map);
System.out.println("thread num: " + map.size()); System.in.read();
}
参考文献:http://www.jianshu.com/p/b9af028efebb
hystrix服务降级(3)的更多相关文章
- Spring Cloud (7) 服务容错保护-Hystrix服务降级
在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以互相调用,在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务通常会集群 ...
- SpringCloud之Hystrix服务降级(七)
Hystrix设计原则 1.防止单个服务的故障,耗尽整个系统服务的容器(比如tomcat)的线程资源,避免分布式环境里大量级联失败.通过第三方客户端访问(通常是通过网络)依赖服务出现失败.拒绝.超时或 ...
- SpringCloud之Hystrix服务降级入门全攻略
理论知识 Hystrix是什么? Hystrix是由Netflix开源的一个服务隔离组件,通过服务隔离来避免由于依赖延迟.异常,引起资源耗尽导致系统不可用的解决方案.这说的有点儿太官方了,它的功能主要 ...
- hystrix服务降级和服务熔断的区别
故事的背景是这样的:由于小强在工作中碰到一些问题,于是想请教一下业界大牛小壮.于是发生了下面的两个场景: 小强在拿起常用手机拨号时发现该手机没有能够拨通,所以就拿出了备用手机拨通了某A的电话,这个过程 ...
- Spring Cloud (5)hystrix 服务降级
一.是什么 二. 2.1 2.2 2.3 2.4 2.5 yml
- 五. SpringCloud服务降级和熔断
1. Hystrix断路器概述 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.这就造成有可能会发生服务雪崩.那么什么是服务雪崩呢 ...
- SpringCloud 2020.0.4 系列之服务降级的其他用法与熔断
1. 概述 老话说的好:控制好自己的情绪,才能控制好自己的人生.冲动是魔鬼,冷静才最重要. 言归正传,之前聊了在 Feign 调用时,如何给整个 Feign接口类 增加降级策略. 今天我们来聊一下 H ...
- SpringCloud实战-Hystrix请求熔断与服务降级
我们知道大量请求会阻塞在Tomcat服务器上,影响其它整个服务.在复杂的分布式架构的应用程序有很多的依赖,都会不可避免地在某些时候失败.高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险 ...
- SpringCloud系列七:Hystrix 熔断机制(Hystrix基本配置、服务降级、HystrixDashboard服务监控、Turbine聚合监控)
1.概念:Hystrix 熔断机制 2.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...
随机推荐
- 2017 Gartner数据科学魔力象限出炉,16位上榜公司花落谁家?
https://www.leiphone.com/news/201703/iZGuGfnER4Sv2zRe.html 2017年Gartner数据科学平台(在2016年被称作“高级分析平台”)的魔力象 ...
- 完整的WebRTC调用序列图
说在前面的话:此图出自Rea-Time Communication with WebRTC: https://book.douban.com/subject/25849712/ 的第五章.
- node八-核心模块、包
学会查API,远比会几个API更重要. 核心模块意义 -如果只是在服务器运行javascript代码,并没有多大意义,因为无法实现任何功能>读写文件.访问网络 -Node的用处在于它本身还提供可 ...
- Node笔记二
### 安装包的方式安装 - 安装包下载链接: + Mac OSX: [darwin](http://npm.taobao.org/mirrors/node/v5.7.0/node-v5.7.0.pk ...
- 分布式缓存管理平台XXL-CACHE
<分布式缓存管理平台XXL-CACHE> 一.简介 1.1 概述 XXL-CACHE是一个分布式缓存管理平台,其核心设计目标是"让分布式缓存的接入和管理的更加的简洁和高效&quo ...
- django优化和扩展(一)
mysql优化基础 进行django产品开发或上线之前,有必要了解一下mysql的基础知识,orm太过抽象,导致很多朋友对于mysql了解得太少,而且orm不像sqlalchemy那样可以跟mysql ...
- python 基础(四) 正则,递归 生成器
字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦, ...
- 微信小程序-获取地理位置
近期公司使用微信小程序开发一套应用,涉及到使用小程序的获取地理位置接口,但是在使用测试过程中发现获取的经纬度偏差较大, 之后进行了一番搜索,终于找到了, 原文地址:http://blog.csdn.n ...
- 3个简单CSS实现的动态效果
这里只是鼠标移入的时候出现的动态效果,并没有使用CSS的动画属性animation和变形属性transform.后面再补... HTML代码如下: <!DOCTYPE html><h ...
- js 遍历 each() 方法
1.例子: <html><head><script type="text/javascript" src="/jquery/jquery.j ...