我之前讲解Hystrix时,都是使用原生的Netfilx Hystrix,但实践中我们一般不会直接使用。所以本章,我将讲解如何在Spring Cloud中使用Hystrix,Spring Cloud对Hystrix进行了封装,我之前已经讲解过了Eureka、Ribbon、Feign,事实上,Spring Cloud Netflix Hystrix既可以独立使用,也可以和Feign整合在一起,本章我会分别讲解这两种使用方式。
关于Spring Cloud Netflix Hystrix使用的更多介绍,可以参考官方文档:https://docs.spring.io/spring-cloud-netflix/docs/2.2.5.RELEASE/reference/html/#circuit-breaker-hystrix-clients。
一、独立使用
我们先来看下如何独立使用Spring Cloud Netflix Hystrix。首先需要引入spring-cloud-starter-netflix-hystrix
这个maven依赖。我这里继续沿用《透彻理解Spring Cloud(二七)——Feign基本使用》中的示例。
1.1 Maven依赖
首先,在ServiceB工程中添加Maven依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tpvlog</groupId>
<artifactId>serviceB</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>serviceB</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR8</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.tpvlog</groupId>
<artifactId>service-a-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
<version>2.2.5.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
1.2 启动类
启动类中需要加上@EnableCircuitBreaker
或@EnableHystrix
注解:
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableCircuitBreaker
public class ServiceBApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceBApplication.class, args);
}
}
@EnableHystrix注解仅仅是对@EnableCircuitBreaker注解的一个包装而已。
1.3 服务类
最后是服务类,这里用了一个@HystrixCommand
注解,Spring Cloud会为我们生成一个代理类,最终方法的执行会交给代理类,fallbackMethod
指定了降级逻辑:
@Service
public class SomeService {
@HystrixCommand(fallbackMethod = "defaultStores",commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
})
public Object getStores(Map<String, Object> parameters) {
//do stuff that might fail
}
// 降级方法
public Object defaultStores(Map<String, Object> parameters) {
return /* something useful */;
}
}
我们还可以通过注解中的commandProperties
属性配置HystrixCommand的参数,比如execution.isolation.strategy
表示配置资源隔离策略。
二、整合Feign
我们再来看下如何将Feign和Hystrix整合在一起。默认情况下,Hystrix的group name就是ServiceA这种服务名称,也就是说你要调用一个服务的话,那么针对每个服务就有一个线程池,然后针对服务的每个接口方法,对应有一个自动生成的HystrixCommand,CommandKey是接口类#方法名
。
2.1 配置文件
首先,需要在配置文件中开启Hystrix:
# To enbale Hystrix in Feign
feign:
hystrix:
enabled: true
# To set thread isolation to SEMAPHORE
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
然后可以通过hystrix.command.XXX
配置Hystrix的参数,我这里用了default,表示对所有HsystrixCommand生效。我们也可以用具体的服务名称替换,比如serviceA。
2.2 服务类
接着,需要在服务接口中添加fallback配置,表示降级逻辑:
@FeignClient(name = "ServiceA",fallback = ServiceAClientFallback.class)
public interface ServiceAClient extends ServiceAInterface {
}
static class ServiceAClientFallback implements ServiceAClient {
public String sayHello() {
// 降级机制
}
}
如果我们需要知道fallback异常的原因,可以使用fallbackFactory
:
@FeignClient(name = "ServiceA",fallbackFactory = ServiceAClientFallbackFactory.class)
public interface ServiceAClient extends ServiceAInterface {
}
static class ServiceAClientFallbackFactory implements FallbackFactory<ServiceAClient> {
@Override
public ServiceAClient create(Throwable cause) {
return new ServiceAClient() {
@Override
public String sayHello() {
return "fallback; reason was: " + cause.getMessage();
}
};
}
}
三、总结
本章,我讲解了Spring Cloud Netflix Hystrix的两种使用方式,事实上它们的底层原理是一样的,我后续分析源码时会详细讲解。另外,Hystrix在使用时,一般也会用它的统计仪表盘——Hystrix Dashboard和 Turbine,我这里就不再赘述了,它们的使用都很简单,读者可以参考Spring Cloud 官方文档。