Hystrix简介

Hystrix

##

Command模式解决什么问题

What solution does the Command design pattern describe?

  • Define separate (command) objects that encapsulate a request.
  • A class delegates a request to a command object instead of implementing a particular request directly.

What problems can the Command design pattern solve?

  • Coupling the invoker of a request to a particular request should be avoided. That is, hard-wired requests should be avoided.
  • It should be possible to configure an object (that invokes a request) with a request.

Implementing (hard-wiring) a request directly into a class is inflexible because it couples the class to a particular request at compile-time, which makes it impossible to specify a request at run-time.

总结:Hystrix的command模式带来的好处是在运行时,可以动态切换对某个client的方法的实现。(fallback)

Hystrix的设计原则

  • 防止任何单个依赖项用尽所有容器(例如Tomcat)用户线程。
  • 甩负荷(Shedding load)并快速失败而不是排队。
  • 在可行的地方提供fallback以保护用户免于失败。
  • 使用隔离技术来限制任何一个依赖项的影响。
  • 通过近实时指标,监控和警报优化问题发现时间。

执行流程

hystrix-command-flow-chart

有4种方式可以执行一个command:

  • 同步执行

    execute()— 阻塞式调用,返回一个单个的response。当调用execute()实际上会调用queue().get()

  • 异步执行

    queue() — 返回一个Future,用这个Future可以获取一个单个的response。实际会调用toObservable().toBlocking().toFuture()

  • 响应式执行(hot)

    observe()— 返回一个Observable,并且立刻订阅。 实际会调用 toObservable().subscribe(subject)

  • 响应式执行 (cold)

    toObservable()— 返回一个Observable,当被订阅的时候,才开始执行指令。

1
2
3
4
K             value   = command.execute();
Future<K> fValue = command.queue();
Observable<K> ohValue = command.observe(); //hot observable
Observable<K> ocValue = command.toObservable(); //cold observable

注解方式

  • 同步执行
1
2
3
@HystrixCommand //execute()
public User getUserById(String id) {
}
  • 异步执行
1
2
3
@HystrixCommand //queue()
public Future<User> getUserByIdAsync(final String id) {
}
  • 响应式执行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@HystrixCommand(observableExecutionMode = EAGER)//observable()
//or
@HystrixCommand(observableExecutionMode = LAZY)//toObservable()
public Observable<User> getUserById(final String id) {
return Observable.create(new Observable.OnSubscribe<User>() {
@Override
public void call(Subscriber<? super User> observer) {
try {
if (!observer.isUnsubscribed()) {
observer.onNext(new User(id, name + id));
observer.onCompleted();
}
} catch (Exception e) {
observer.onError(e);
}
}
});
}

隔离

Thread pool

好处:安全,能够将client看作黑盒。

坏处:耗时增加,每一个command的执行都要经历queueing, scheduling和线程切换。

Semaphores

好处:没有额外的消耗

坏处:因为无法主动中断,必须完全相信client能够快速失败。

Sequence Diagram

@adrianb11 has kindly provided a sequence diagram demonstrating the above flows

Hystrix 参数调整

thread-configuration-1280

Timeout

  • 用接近99.5线的值来设置Thread Timeout。

  • 如果容许重试的话,Thread Timeout和NetworkTimeout要配合起来,留够一次retry的时间:

    ThreadTimeout >(NetworkTimeOut + retry的预估用时)
    
  • NetworkTimeout的一般被设置为在网络层可以拦截最耗时的1%的请求。

ThreadPool

  • 线程池大小 = 每秒请求数*99线的响应时间(以秒为单位)

queued + poolSize = 并发数

队列过长,会导致响应时间增加。

Hystrxi的treahdpool的配置和java的线程池一样。

Metrix

Metric

Metric

参考:

https://blog.csdn.net/xiaojia1100/article/details/65631778

https://en.wikipedia.org/wiki/Command_pattern

https://github.com/Netflix/Hystrix/wiki

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html