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.具体内容 所谓的熔断机制和日常生活中见到电路保险丝是非常相似的,当出现了问题之后,保险丝会自动烧断,以保护我们的电器, 那么如果换到了程序之中呢? 当现在服务的 ...
随机推荐
- python常见模块之time,datetime模块
一.time模块 time模块提供了一些用于管理时间和日期. time模块中时间的表现形式有三种: format_string 格式化的字符串 struct_time 结构化时间 times ...
- mysql cluster部署
一.mysql cluster的基本概念 1.mysql cluster的组成 管理(MGM)节点:这类节点的作用是管理MySQL Cluster内的其他节点,如提供配置数据.启 ...
- Vim PHP环境设置文章
可能有重复: 在ubuntu 上配置vim的PHP开发环境 http://blog.csdn.net/robertaqi/article/details/6117546 手把手教你把Vim改装成一个I ...
- Kotlin实践记录
Kotlin中网络请求和Json解析: Request(url).run()为Kotlin中的网络请求方式,Json解析是自己封装类的操作. Json.get().toObject(Request(u ...
- kaggle入门项目:Titanic存亡预测(四)模型拟合
原kaggle比赛地址:https://www.kaggle.com/c/titanic 原kernel地址:A Data Science Framework: To Achieve 99% Accu ...
- CSS 静态进度条效果
今天学习到了实现一个静态进度条的方法,固写一篇笔记稳固一下自己的知识. 最终的效果如下,进度条放在一个框里,水平宽自适应. 现在就开始,首先写一个进度条先. .progress-bar{ /* 进度条 ...
- Pygame常用方法
'''import pygame# 初始化pygame库,让计算机硬件准备pygame.init()# ----------窗口相关操作-----------# 创建窗口window = pygame ...
- Django入门三之urls.py重构及参数传递
1. 内部重构 2. 外部重构 website/blog/urls.py website/website/urls.py 3. 两种参数处理方式 -1. blog/index/?id=1234& ...
- Java IO流对象、多线程
Input(读) Output(写)操作 File类 import java.io.File; 将操作系统中的文件.目录(文件夹).路径.封装成File对象 提供方法,操作系统中的内容.File与系统 ...
- Git分支合并冲突解决
前2天群里发了张git历史图,如下: 根据提交历史,可以看出图中所有分支合并都采用merge的方式,具体merge是怎么操作的,可以阅读下边文章. 根据项目上的需求,如果要求git提交历史是比较简单的 ...