除了在主页上引述之外,我想不出更好的方式来描述Netflix Hystrix库的特定功能:
延迟和容错方式:
停止级联故障。 后备和正常降级。 无法快速快速恢复。 使用断路器隔离线程和信号量。
我看到了Josh Long( @starbuxman )演示的示例 ,该示例使用了与Spring集成的Hystrix-具体代码在这里 。 该示例利用注释使hystrix启用服务类。
我的目标是在较小的单元测试模式下重新创建类似的设置。 考虑到这一点,请考虑使用Hystrix库将使以下接口具有容错能力:
package hystrixtest;public interface RemoteCallService {String call(String request) throws Exception;}
还有一个虚拟的实现。 虚拟实现委托给一个模拟实现,该模拟实现在前两次被调用时失败,并在第三次调用时成功:
package hystrixtest;import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;import static org.mockito.Mockito.*;public class DummyRemoteCallService implements RemoteCallService {private RemoteCallService mockedDelegate;public DummyRemoteCallService() {try {mockedDelegate = mock(RemoteCallService.class);when(mockedDelegate.call(anyString())).thenThrow(new RuntimeException("Deliberately throwing an exception 1")).thenThrow(new RuntimeException("Deliberately throwing an exception 2")).thenAnswer(new Answer<String>() {@Overridepublic String answer(InvocationOnMock invocationOnMock) throws Throwable {return (String) invocationOnMock.getArguments()[0];}});}catch(Exception e) {throw new IllegalStateException(e);}}@Override@HystrixCommand(fallbackMethod = "fallBackCall")public String call(String request) throws Exception {return this.mockedDelegate.call(request);}public String fallBackCall(String request) {return "FALLBACK: " + request;}
}
远程调用已使用@Hystrixcommand批注进行了批注,并具有基本配置,以便在远程调用失败时退回到“ fallBackCall”方法。
现在,您可以想象,Hystrix库中必须有一些东西可以拦截用@HystrixCommand注释注释的调用,并使其具有容错能力。 这是一个有效的测试,将必要的基础结构包装在一起–本质上,Hystrix库提供了一个基于AOP的配套库,可拦截调用。 我在这里使用了Spring测试支持来引导AOP基础结构,将HystrixCommandAspect创建为bean,对于前两个失败的调用,该调用转到“ fallBackCall”,并在第三次成功进行:
package hystrixtest;import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class TestRemoteCallServiceHystrix {@Autowiredprivate RemoteCallService remoteCallService ;@Testpublic void testRemoteCall() throws Exception{assertThat(this.remoteCallService.call("test"), is("FALLBACK: test"));assertThat(this.remoteCallService.call("test"), is("FALLBACK: test"));assertThat(this.remoteCallService.call("test"), is("test"));}@Configuration@EnableAspectJAutoProxypublic static class SpringConfig {@Beanpublic HystrixCommandAspect hystrixCommandAspect() {return new HystrixCommandAspect();}@Beanpublic RemoteCallService remoteCallService() {return new DummyRemoteCallService();}}
}
Spring-Cloud为基于Spring-Boot的项目提供了一种配置Netflix库的简便方法,如果我要使用该库,则测试会转换为该库,现在借助Spring-Boot注释掉一堆配置:
package hystrixtest;import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration
public class TestRemoteCallServiceHystrix {@Autowiredprivate RemoteCallService remoteCallService;@Testpublic void testRemoteCall() throws Exception {assertThat(this.remoteCallService.call("test"), is("FALLBACK: test"));assertThat(this.remoteCallService.call("test"), is("FALLBACK: test"));assertThat(this.remoteCallService.call("test"), is("test"));}@Configuration@EnableAutoConfiguration
// @EnableAspectJAutoProxy@EnableHystrixpublic static class SpringConfig {// @Bean
// public HystrixCommandAspect hystrixCommandAspect() {
// return new HystrixCommandAspect();
// }@Beanpublic RemoteCallService remoteCallService() {return new DummyRemoteCallService();}}
}
如果您有兴趣进一步探索这个样本, 这里是GitHub库与工作的测试。
翻译自: https://www.javacodegeeks.com/2015/01/using-netflix-hystrix-annotations-with-spring.html