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.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...
随机推荐
- JBOSS的启动和停止
本实例使用的JBOSS版本是jboss-4.2.3.GA 假设条件 1. 已设置好JAVA_HOME环境变量 2. 已下载JBoss并且安装目录为:D:\Java\jboss-4.2.3.GA 启 ...
- Python高阶函数之 - 装饰器
高阶函数: 1. 函数名可以作为参数传入 2. 函数名可以作为返回值. python装饰器是用于拓展原来函数功能的一种函数 , 这个函数的特殊之处在于它的返回值也是一个函数 , 使用pyth ...
- Android两级导航菜单栏的实现--FragmentTabHost结合ViewPager与Android 开源项目PagerSlidingTabStrip
http://www.cnblogs.com/aademeng/articles/6119737.html 转载注:简单总结一下,外层Tab用TabHost,类层Tab用Viepager+Framen ...
- pymongo "ServerSelectionTimeoutError: No servers found yet" 错误的解决
系统转移过程中,擅自把aptitude安装的mongoengine换成了pip安装,系统启动以后,报这个错误 报错提示: File "/usr/local/lib/python2.7/dis ...
- form表单序列化为Jquery对象
<form id="DailyFinancial" > @*class="form-inline"*@ <div class="fo ...
- 使用Android Studio Gradle实现友盟多渠道打包
最新项目中要求在友盟后台看到不同渠道的统计,Android大大小小的应用市场要几百个,要一个一个手工打包那一天也干不完,还好是有大牛的,弄出了好多解决方法,就Gradle做一下记录和分享,首先看一些理 ...
- servlet什么时候被实例化?【转】
如果没有设置loadOnStartup,则第一次请求的时候实例化 分三种情况:loadOnStartup < 0 即负数的情况下,web容器启动的时候不做实例化处理,servlet首次被调用时做 ...
- Nginx+uwsgi部署django
0. 登录远程服务器并准备 ssh 用户@IP -p 端口 回车后,要求输入服务器密码,再输入密码 更新软件源 sudo apt-get update sudo apt-get upgrade 1. ...
- 用ASP.NET Core 2.0 建立规范的 REST API -- 预备知识 (2) + 准备项目
上一部分预备知识在这 http://www.cnblogs.com/cgzl/p/9010978.html 如果您对ASP.NET Core很了解的话,可以不看本文, 本文基本都是官方文档的内容. A ...
- FastDfs上传图片
1.1. 上传步骤 1.加载配置文件,配置文件中的内容就是tracker服务的地址. 配置文件内容:tracker_server=192.168.25.133:22122 2.创建一个TrackerC ...