Hystrix 旨在经过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具有拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。java
Dubbo是Alibaba开源的,目前国内最流行的java rpc框架。spring
本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用。缓存
spring boot官方提供了对hystrix的集成,直接在pom.xml里加入依赖:架构
1
2
3
4
5
|
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>
1.4
.
4
.RELEASE</version>
</dependency>
|
而后在Application类上增长@EnableHystrix
来启用hystrix starter:框架
1
2
3
|
@SpringBootApplication
@EnableHystrix
public
class
ProviderApplication {
|
在Dubbo的Provider上增长@HystrixCommand
配置,这样子调用就会通过Hystrix代理。async
1
2
3
4
5
6
7
8
9
10
11
12
|
@Service
(version =
"1.0.0"
)
public
class
HelloServiceImpl
implements
HelloService {
@HystrixCommand
(commandProperties = {
@HystrixProperty
(name =
"circuitBreaker.requestVolumeThreshold"
, value =
"10"
),
@HystrixProperty
(name =
"execution.isolation.thread.timeoutInMilliseconds"
, value =
"2000"
) })
@Override
public
String sayHello(String name) {
// System.out.println("async provider received: " + name);
// return "annotation: hello, " + name;
throw
new
RuntimeException(
"Exception to show hystrix enabled."
);
}
}
|
对于Consumer端,则能够增长一层method调用,并在method上配置@HystrixCommand
。当调用出错时,会走到fallbackMethod = "reliable"
的调用里。分布式
1
2
3
4
5
6
7
8
9
10
|
@Reference
(version =
"1.0.0"
)
private
HelloService demoService;
@HystrixCommand
(fallbackMethod =
"reliable"
)
public
String doSayHello(String name) {
return
demoService.sayHello(name);
}
public
String reliable(String name) {
return
"hystrix fallback value"
;
}
|
经过上面的配置,很简单地就完成了Spring Boot里Dubbo + Hystrix的集成。ide
传统spring annotation应用的配置其实也很简单,和spring boot应用不一样的是:函数
@EnableAspectJAutoProxy
@Configuration
配置HystrixCommandAspect
Bean。
1
2
3
4
5
6
7
8
9
10
11
12
|
@Configuration
@EnableDubbo
(scanBasePackages =
"com.alibaba.dubbo.samples.annotation.action"
)
@PropertySource
(
"classpath:/spring/dubbo-consumer.properties"
)
@ComponentScan
(value = {
"com.alibaba.dubbo.samples.annotation.action"
})
@EnableAspectJAutoProxy
static
public
class
ConsumerConfiguration {
@Bean
public
HystrixCommandAspect hystrixCommandAspect() {
return
new
HystrixCommandAspect();
}
}
|
在上面的例子里能够看到,Hystrix对Spring的集成是经过Spring AOP来实现的。下面简单分析下实现。源码分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
@Aspect
public
class
HystrixCommandAspect {
@Pointcut
(
"@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)"
)
public
void
hystrixCommandAnnotationPointcut() {
}
@Pointcut
(
"@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)"
)
public
void
hystrixCollapserAnnotationPointcut() {
}
@Around
(
"hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()"
)
public
Object methodsAnnotatedWithHystrixCommand(
final
ProceedingJoinPoint joinPoint)
throws
Throwable {
Method method = getMethodFromTarget(joinPoint);
Validate.notNull(method,
"failed to get method from joinPoint: %s"
, joinPoint);
if
(method.isAnnotationPresent(HystrixCommand.
class
) && method.isAnnotationPresent(HystrixCollapser.
class
)) {
throw
new
IllegalStateException(
"method cannot be annotated with HystrixCommand and HystrixCollapser "
+
"annotations at the same time"
);
}
MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));
MetaHolder metaHolder = metaHolderFactory.create(joinPoint);
HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);
ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?
metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();
Object result;
try
{
if
(!metaHolder.isObservable()) {
result = CommandExecutor.execute(invokable, executionType, metaHolder);
}
else
{
result = executeObservable(invokable, executionType, metaHolder);
}
}
catch
(HystrixBadRequestException e) {
throw
e.getCause() !=
null
? e.getCause() : e;
}
catch
(HystrixRuntimeException e) {
throw
hystrixRuntimeExceptionToThrowable(metaHolder, e);
}
return
result;
}
|
HystrixCommandAspect
里定义了两个注解的AspectJ Pointcut:@HystrixCommand
, @HystrixCollapser
。全部带这两个注解的spring bean都会通过AOP处理@Around
AOP处理函数里,能够看到Hystrix会建立出HystrixInvokable
,再经过CommandExecutor
来执行@EnableHystrix
引入了@EnableCircuitBreaker
,@EnableCircuitBreaker
引入了EnableCircuitBreakerImportSelector
1
2
3
4
5
6
7
|
@EnableCircuitBreaker
public
@interface
EnableHystrix {
}
@Import
(EnableCircuitBreakerImportSelector.
class
)
public
@interface
EnableCircuitBreaker {
}
|
EnableCircuitBreakerImportSelector
继承了SpringFactoryImportSelector<EnableCircuitBreaker>
,使spring加载META-INF/spring.factories
里的EnableCircuitBreaker
声明的配置在META-INF/spring.factories
里能够找到下面的配置,也就是引入了HystrixCircuitBreakerConfiguration
。
1
2
|
org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration
|
HystrixCircuitBreakerConfiguration
里能够发现建立了HystrixCommandAspect
1
2
3
4
5
6
7
|
@Configuration
public
class
HystrixCircuitBreakerConfiguration {
@Bean
public
HystrixCommandAspect hystrixCommandAspect() {
return
new
HystrixCommandAspect();
}
|
可见spring-cloud-starter-netflix-hystrix
实际上也是建立了HystrixCommandAspect
来集成Hystrix。
另外spring-cloud-starter-netflix-hystrix
里还有metrics, health, dashboard等集成。
@Service
是一个spring bean,直接在上面配置@HystrixCommand
便可@Reference
,能够经过加一层简单的spring method包装,配置@HystrixCommand
便可HystrixCommandAspect
来集成Spring AOP,配置了@HystrixCommand
和@HystrixCollapser
的spring method都会被Hystrix处理欢迎学Java和大数据的朋友们加入java架构交流: 855835163
加群连接:jq.qq.com/?_wv=1027&a…
群内提供免费的架构资料还有:Java工程化、高性能及分布式、高性能、深刻浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的免费直播讲解 能够进来一块儿学习交流哦
直播课堂地址:ke.qq.com/course/2602…