之前所说Hystrix的he'llWord,今天看一下Hystrix的不同调用方法
这样就完成了一个Command。接下来调用这个Command
- //需要继承HystrixCommand,还可以继承HystrixObservableCommand只是对应接口、调用方法不同
- public class CommandHelloWorld extends HystrixCommand<String> {
- private final String name;
- public CommandHelloWorld(String name) {
- //父类构造方法,只需要传入一个GroupKey
- super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
- this.name = name;
- }
- //真实的方法,在这调用服务等,并返回结果
- @Override
- protected String run() {
- return "Hello " + name + "!";
- }
- }
这里直接新建一个实例并调用execute方法。就得到了想要的结果
- @Test
- public void testSynchronous() {
- assertEquals("Hello World!", new CommandHelloWorld("World").execute());
- assertEquals("Hello Bob!", new CommandHelloWorld("Bob").execute());
- }
这里直接新建一个实例并调用execute方法。就得到了想要的结果
调用方法
以上介绍了execute方法进行调用,这里execute是同步调用,会阻塞当前线程,Hystrix提供了许多异步的方法进行调用
- //同步方法
- @Test
- public void testSynchronousSysOut() {
- System.out.println( new CommandHelloWorld("World").execute());
- System.out.println( new CommandHelloWorld("Bob").execute());
- }
- //放入队列获得future异步调用
- @Test
- public void testAsynchronous2() throws Exception {
- Future<String> fWorld = new CommandHelloWorld("World").queue();
- Future<String> fBob = new CommandHelloWorld("Bob").queue();
- assertEquals("Hello World!", fWorld.get());
- assertEquals("Hello Bob!", fBob.get());
- }
其实以上的方法原理都一样,都是调用queue().get()方法,其中queue返回Future对象,之后对future阻塞进行取值。内部其实是调用toObservable().toBlocking().toFuture()来获得future对象的
还有一种是使用RxJava的observable接口来进行调用的,Hystrix内部底层也是使用RxJava来实现的
- /使用RxJava的Observable
- @Test
- public void testObservable() throws Exception {
- Observable<String> fWorld = new CommandHelloWorld("World").observe();
- Observable<String> fBob = new CommandHelloWorld("Bob").observe();
- // 阻塞
- assertEquals("Hello World!", fWorld.toBlocking().single());
- assertEquals("Hello Bob!", fBob.toBlocking().single());
- // 非阻塞
- // - this is a verbose anonymous inner-class approach and doesn't do assertions
- fWorld.subscribe(new Observer<String>() {
- @Override
- public void onCompleted() {
- // nothing needed here
- }
- @Override
- public void onError(Throwable e) {
- e.printStackTrace();
- }
- @Override
- public void onNext(String v) {
- System.out.println("onNext: " + v);
- }
- });
fallback
以上只是简单封装了调用的接口,下面来看下Hystrix是如何应对调用的错误的
当在run方法中主动抛出异常,就会导致下面的错误信息
- com.netflix.hystrix.exception.HystrixRuntimeException: CommandHelloWorld failed and no fallback available.
我们在Command中添加fallback方法
- @Override
- protected String run() {
- throw RuntimeException("error");
- //return "Hello " + name + "!";
- }
- @Override
- protected String getFallback() {
- return "Failure " + name + "!";
- }
修改test方法
- @Test
- public void testSynchronous() {
- assertEquals("Failure World!", new CommandHelloWorld("World").execute());
- assertEquals("Failure Bob!", new CommandHelloWorld("Bob").execute());
- }
这样运行就没有问题了,可以看到当run运行出错时,将会调用fallback,返回值也由fallback提供,当然fallback也出错那就没有办法了,所以需要尽量保证fallback不会出现异常。
其中值得注意的一点是当手动抛出HystrixBadRequestException时,Hystrix是不会调用fallback的。