Hystrix-异常处理
异常的传播和捕获
传播:在HystrixCommand实现的run()方法中跑出异常时,除了HystrixBadRequestException之外,其他异常均会被Hystrix认为命令执行失败并处罚服务降级的处理逻辑。下面的例子通过@HystrixCommand注解的ignoreException参数来设置。
捕获:我们可以在降级方法中添加Throwable参数来捕获异常。
package org.hope.hystrix.example.exception; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import org.springframework.stereotype.Service; @Service public class HystrixHandleException { /** * 当设置ignoreExceptions参数时, * 抛出对应的异常就不会触发降级(也就是不会调用failMethod()方法). */ @HystrixCommand( ignoreExceptions = {NullPointerException.class, ArithmeticException.class}, fallbackMethod = "failMethod" ) public String getUserName(Long id) { Long re = id/0; //会抛ArithmeticException String param = null; param.trim(); // 此处会抛NullPointException return "张三"; } private String failMethod(Long id, Throwable e) { return e.getMessage(); } }
单元测试:
package org.hope.hystrix.example.exception; import org.hope.hystrix.example.HystrixApplication; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = HystrixApplication.class) public class HystrixHandleExceptionTest { @Autowired private HystrixHandleException hystrixHandleException; @Test public void test() { String name = hystrixHandleException.getUserName(10L); System.out.println("==================" + name); } }
运行结果
java.lang.ArithmeticException: / by zero
at org.hope.hystrix.example.exception.HystrixHandleException.getUserName(HystrixHandleException.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.execute(MethodExecutionAction.java:116)
at com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.executeWithArgs(MethodExecutionAction.java:93)
at com.netflix.hystrix.contrib.javanica.command.MethodExecutionAction.execute(MethodExecutionAction.java:78)
at com.netflix.hystrix.contrib.javanica.command.GenericCommand$1.execute(GenericCommand.java:48)
at com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand.process(AbstractHystrixCommand.java:145)
at com.netflix.hystrix.contrib.javanica.command.GenericCommand.run(GenericCommand.java:45)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)
at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46)
参考:
[1]Github,https://github.com/Netflix/Hystrix/wiki/How-it-Works
[2] 《SpringCloud微服务实战》,电子工业出版社,翟永超