Hystrix框架2--超时
timeout
在调用第三方服务时有些情况需要对服务响应时间进行把控,当超时的情况下进行fallback的处理
下面来看下超时的案例
public class CommandTimeout extends HystrixCommand<String> {
private final String name;
public CommandTimeout(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
System.out.println("aaaa");
try {
//sleep10秒强制超时,默认超时时间是1s
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run end");
return "";
}
@Override
protected String getFallback() {
return "Hello Failure " + name + "!";
}
}
接下来是测试方法
@Test
public void testSynchronous() throws InterruptedException {
System.out.println(new CommandHelloWorld("World").execute());
}
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at hystrix.CommandHelloWorld.run(CommandHelloWorld.java:32)
at hystrix.CommandHelloWorld.run(CommandHelloWorld.java:1)
...
run end
Hello Failure World!
可以看到sleep被强制interrupted,并且调用的输出也变成了fallback方法的返回值
如何查看是哪里调用的interrupt方法
这里顺便说下如何看是哪个方法调用的interrupt
根据stackoverflow的一个答案,没有直接的方法来断点到interrupt的方法,只能通过在Thread的interrupt方法上打断点,再反向看栈信息得知哪里中断当前线程。
如何改变timeout设置
在HystrixCommand的够着方法中可以在第二个参数配置一个timeout的毫秒数
public CommandHelloWorld(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"),1000000000);
this.name = name;
}
这个构造方法是在调用AbastractCommand的构造方法时将毫秒数配置在CommandProperties中,如下:
super(group, null, null, null, null, HystrixCommandProperties.Setter().withExecutionTimeoutInMilliseconds(executionIsolationThreadTimeoutInMilliseconds), null, null, null, null, null, null);
Hystrix的timeout是怎么运行的
在运行对应的command时,Hystrix会通过HystrixObservableTimeoutOperator注册一个Timer到一个定时线程池中,当超时后会启用一个HystrixTimer线程来interruptCommand的执行
//创建一个TimerListener
public Reference<TimerListener> addTimerListener(final TimerListener listener) {
startThreadIfNeeded();
// add the listener
Runnable r = new Runnable() {
@Override
public void run() {
try {
listener.tick();
} catch (Exception e) {
logger.error("Failed while ticking TimerListener", e);
}
}
};
//通过ScheduledThreadPoolExecutor在到达超时时间时运行上面的listener.tick,而时间是从listener的getIntervalTimeInMilliseconds方法中获得的
ScheduledFuture<?> f = executor.get().getThreadPool().scheduleAtFixedRate(r, listener.getIntervalTimeInMilliseconds(), listener.getIntervalTimeInMilliseconds(), TimeUnit.MILLISECONDS);
//返回包含timer的Reference,在任务在规定时间内完成是用于cancel超时处理
return new TimerReference(listener, f);
}
//下面是上面listener的定义
TimerListener listener = new TimerListener() {
@Override
public void tick() {
// if we can go from NOT_EXECUTED to TIMED_OUT then we do the timeout codepath
// otherwise it means we lost a race and the run() execution completed or did not start
//这里使用CAS的操作将将状态设置为TIME_OUT,使用CAS的原因是如果运行成功而timeout没有被取消时不会标记任务超时
if (originalCommand.isCommandTimedOut.compareAndSet(TimedOutStatus.NOT_EXECUTED, TimedOutStatus.TIMED_OUT)) {
// report timeout failure
originalCommand.eventNotifier.markEvent(HystrixEventType.TIMEOUT, originalCommand.commandKey);
// shut down the original request
//内部会取消当前并调用fallback
s.unsubscribe();
timeoutRunnable.run();
//if it did not start, then we need to mark a command start for concurrency metrics, and then issue the timeout
}
}
@Override
public int getIntervalTimeInMilliseconds() {
//这里从command的配置中获得配置的超时时间
return originalCommand.properties.executionTimeoutInMilliseconds().get();
}
};
上面是Command超时后的处理操作,当Command在时间内完成时会调用TimeReference的clear方法,内部调用了future的cancel来取消timer的超时任务
private static class TimerReference extends SoftReference<TimerListener> {
private final ScheduledFuture<?> f;
//保存scheduledFuture
TimerReference(TimerListener referent, ScheduledFuture<?> f) {
super(referent);
this.f = f;
}
@Override
public void clear() {
super.clear();
// stop this ScheduledFuture from any further executions
//停止scheduledFuture
f.cancel(false);
}
}
Hystrix框架2--超时的更多相关文章
- Hystrix框架3--线程池
线程池 在Hystrix中Command默认是运行在一个单独的线程池中的,线程池的名称是根据设定的ThreadPoolKey定义的,如果没有设置那么会使用CommandGroupKey作为线程池. 这 ...
- Hystrix框架1--入门
介绍 在开发应用中或多或少会依赖各种外界的服务,利用各个服务来完成自己的业务需求,现在流行的微服务架构更是离不开各个服务之间的调用,这就导致整体应用的可用性依赖于各个依赖服务的可用性. 比如一个依赖3 ...
- Java并发框架——AQS超时机制
AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性 ...
- springcloud(五) Hystrix 降级,超时
分布式系统中一定会遇到的一个问题:服务雪崩效应或者叫级联效应什么是服务雪崩效应呢? 在一个高度服务化的系统中,我们实现的一个业务逻辑通常会依赖多个服务,比如:商品详情展示服务会依赖商品服务, 价格服务 ...
- Hystrix框架5--请求缓存和collapser
简介 在Hystrix中有个Request的概念,有一些操作需要在request中进行 缓存 在Hystrix调用服务时,如果只是查询接口,可以使用缓存进行优化,从而跳过真实访问请求. 应用 需要启用 ...
- Hystrix框架4--circuit
circuit 在Hystrix调用服务时,难免会遇到异常,如对方服务不可用,在这种情况下如果仍然不停地调用就是不必要的,在Hystrix中可以配置使用circuit,当达到一定程度错误,就会自动调用 ...
- Hystrix 框架
雪崩效应的产生原因:当一个服务突然受到高并发的请求,tomcat服务器承受不了的情况下会产生服务堆积,可能导致其他的服务也不可用. 服务保护:当服务产生堆积的时候,对服务实现保护功能. 服务隔离:每个 ...
- Spring Cloud之Hystrix服务保护框架
服务保护利器 微服务高可用技术 大型复杂的分布式系统中,高可用相关的技术架构非常重要. 高可用架构非常重要的一个环节,就是如何将分布式系统中的各个服务打造成高可用的服务,从而足以应对分布式系统环境中的 ...
- Hystrix多个线程池切换执行超时带来的问题(图解)
线程池切换带来的超时问题 上图有什么问题: Controller的Hystrx线程池已经到了超时时间,而FeignClient的Hystrx线程池还没到超时时间. 场景: Controller ...
随机推荐
- mysql优化
一.优化事项 1. 数据库(表)设计合理 (不合理设计导致内伤) 我们的表设计要符合3NF 3范式(规范的模式) , 有时我们需要适当的逆范式.2. sql语句的优化(索引,常用小技巧 ...
- c语言实现开灯问题
开灯问题: 有n盏灯,编号为1~n,第1个人把所有灯打开,第2个人按下所有编号为2 的倍数的开关(这些灯将被关掉),第3 个人按下所有编号为3的倍数的开关(其中关掉的灯将被打开,开着的灯将被关闭),依 ...
- 揭开Java IO流中的flush()的神秘面纱
大家在使用Java IO流中OutputStream.PrintWriter --时,会经常用到它的flush()方法. 与在网络硬件中缓存一样,流还可以在软件中得到缓存,即直接在Java代码中缓存. ...
- 一、PID控制原理
在模拟控制系统中,控制器最常用的控制规律是PID控制.模拟PID控制系统原理框图如下图.系统由模拟PID控制器和被控对象组成. PID控制器是一种线性控制器,它根据给定值Yd(t)与实际输出值Y(t) ...
- 【HDU】1599 find the mincost route
题意 \(n(1 \le n \le 100)\)个点\(m(1 \le m \le 1000)\)条加权边的无负环无向图,求一个最小环. 分析 加入有一个环,其编号最大的点为\(L\),那么这个环可 ...
- seajs学习一天后的总结归纳
公司项目最近需要将js文件迁移到seajs来进行模块化管理,由于我以前主要接触模块化开发是接触的AMD规范的requireJS,没有接触过CMD规范,而且在实际项目中还没有用过类似技术.于是,我非常兴 ...
- MarkDown笔记
MarkDown是一种轻量级的标记语言,可以比较简洁地格式化文本,所以比较方便地产生可读性良好的文档. 可以使用Markdown: 整理知识,学习笔记 发布日记,杂文,所见所想 撰写发布技术文稿(代码 ...
- 移动端Web页面问题(转载)
1.安卓浏览器看背景图片,有些设备会模糊. 用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢? 经过研究,是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率 ...
- JavaScript笔试必备语句【转】
1. document.write( " "); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document- >html- >(head,bod ...
- oracle导出一条二进制数据(二进制,long只能通过dmp导出)
exp jxfoc/JXFOC@ORCL file=d:\dd.dmp tables=(jxfoc.FLIGHT_PLAN_MAKE_LOG,jxfoc.METAR_CONTENT_FOR_MAIL) ...