Hystrx权威指南--Hystrix调用方法解析

之前所说Hystrix的he'llWord,今天看一下Hystrix的不同调用方法

这样就完成了一个Command。接下来调用这个Command

[java] view plain copy
 
  1. //需要继承HystrixCommand,还可以继承HystrixObservableCommand只是对应接口、调用方法不同  
  2. public class CommandHelloWorld extends HystrixCommand<String> {  
  3.   
  4.     private final String name;  
  5.   
  6.     public CommandHelloWorld(String name) {  
  7.         //父类构造方法,只需要传入一个GroupKey  
  8.         super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));  
  9.         this.name = name;  
  10.     }  
  11.     //真实的方法,在这调用服务等,并返回结果  
  12.     @Override  
  13.     protected String run()  {  
  14.         return "Hello " + name + "!";  
  15.     }  
  16. }  

这里直接新建一个实例并调用execute方法。就得到了想要的结果

[java] view plain copy
 
  1. @Test  
  2. public void testSynchronous() {  
  3.     assertEquals("Hello World!", new CommandHelloWorld("World").execute());  
  4.     assertEquals("Hello Bob!", new CommandHelloWorld("Bob").execute());  
  5. }  

这里直接新建一个实例并调用execute方法。就得到了想要的结果

调用方法

以上介绍了execute方法进行调用,这里execute是同步调用,会阻塞当前线程,Hystrix提供了许多异步的方法进行调用

[java] view plain copy
 
  1. //同步方法  
  2. @Test  
  3. public void testSynchronousSysOut() {  
  4.     System.out.println( new CommandHelloWorld("World").execute());  
  5.     System.out.println(  new CommandHelloWorld("Bob").execute());  
  6. }  
  7. //放入队列获得future异步调用  
  8. @Test  
  9. public void testAsynchronous2() throws Exception {  
  10.   
  11.     Future<String> fWorld = new CommandHelloWorld("World").queue();  
  12.     Future<String> fBob = new CommandHelloWorld("Bob").queue();  
  13.   
  14.     assertEquals("Hello World!", fWorld.get());  
  15.     assertEquals("Hello Bob!", fBob.get());  
  16. }  

其实以上的方法原理都一样,都是调用queue().get()方法,其中queue返回Future对象,之后对future阻塞进行取值。内部其实是调用toObservable().toBlocking().toFuture()来获得future对象的

还有一种是使用RxJava的observable接口来进行调用的,Hystrix内部底层也是使用RxJava来实现的

[java] view plain copy
 
  1. /使用RxJava的Observable  
  2. @Test  
  3. public void testObservable() throws Exception {  
  4.   
  5.     Observable<String> fWorld = new CommandHelloWorld("World").observe();  
  6.     Observable<String> fBob = new CommandHelloWorld("Bob").observe();  
  7.   
  8.     // 阻塞  
  9.     assertEquals("Hello World!", fWorld.toBlocking().single());  
  10.     assertEquals("Hello Bob!", fBob.toBlocking().single());  
  11.   
  12.     // 非阻塞   
  13.     // - this is a verbose anonymous inner-class approach and doesn't do assertions  
  14.     fWorld.subscribe(new Observer<String>() {  
  15.   
  16.         @Override  
  17.         public void onCompleted() {  
  18.             // nothing needed here  
  19.         }  
  20.   
  21.         @Override  
  22.         public void onError(Throwable e) {  
  23.             e.printStackTrace();  
  24.         }  
  25.   
  26.         @Override  
  27.         public void onNext(String v) {  
  28.             System.out.println("onNext: " + v);  
  29.         }  
  30.   
  31.     });  

fallback

以上只是简单封装了调用的接口,下面来看下Hystrix是如何应对调用的错误的
当在run方法中主动抛出异常,就会导致下面的错误信息

[java] view plain copy
 
  1. com.netflix.hystrix.exception.HystrixRuntimeException: CommandHelloWorld failed and no fallback available.  

我们在Command中添加fallback方法

[java] view plain copy
 
  1. @Override  
  2. protected String run()  {  
  3.     throw RuntimeException("error");  
  4.     //return "Hello " + name + "!";  
  5. }  
  6. @Override  
  7. protected String getFallback() {  
  8.     return "Failure " + name + "!";  
  9. }  

修改test方法

[java] view plain copy
 
  1. @Test  
  2. public void testSynchronous() {  
  3.     assertEquals("Failure World!", new CommandHelloWorld("World").execute());  
  4.     assertEquals("Failure Bob!", new CommandHelloWorld("Bob").execute());  
  5. }  

这样运行就没有问题了,可以看到当run运行出错时,将会调用fallback,返回值也由fallback提供,当然fallback也出错那就没有办法了,所以需要尽量保证fallback不会出现异常。
其中值得注意的一点是当手动抛出HystrixBadRequestException时,Hystrix是不会调用fallback的。

原文地址:https://www.cnblogs.com/mjzhang/p/8426024.html