Spring Cloud(Dalston.SR5)--Hystrix 断路器
Spring Cloud 对 Hystrix 进行了封装,使用 Hystrix 是通过 @HystrixCommand 注解来使用的,被 @HystrixCommand 注解标注的方法,会使用 AspectJ 对其进行代理,Spring 会将相关的类转换为 Bean 放到容器中,在 @HystrixCommand 注解中,还可以通过 commandProperties、threadPoolProperties 属性来设置命令的配置。
Hystrix 示例如下:
- 创建项目
创建名称为 spring-cloud-hystrix-client 的 Spring Cloud 项目,因为项目示例使用到了 Ribbon 因此也增加了相关依赖,修改 POM.xml 中增加以下依赖项:
<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.lixue</groupId>
<artifactId>spring-cloud-hystrix-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-cloud-hystrix-client</name>
<description>DemoprojectforSpringBoot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/><!--lookupparentfromrepository-->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Dalston.SR5</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 创建服务调用
对于一些默认配置,例如命令组的 Key 等,可以使用 @DefaultProperties 注解标注到类,这样就减少了 @HystrixCommand 注解的配置代码量
package org.lixue;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@DefaultProperties(groupKey="hello-world")
@Component
public class HelloWorldClient{
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod="speakFallback",commandKey="hello-world",
threadPoolKey="hello-world",
commandProperties={
@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="500")
},
threadPoolProperties={
@HystrixProperty(name="coreSize",value="50")
}
)
public String speak(Stringname){
if(name==null ||"".equals(name)){
name="null";
}
return restTemplate.getForObject("http://HELLOWORLD-PROVIDER/speaks?names="+name,String.class);
}
private String speakFallback(String name){
return"call error,name is "+name;
}
}
- 创建 REST 服务
在服务调用类中声明 HelloWorldFeignClient 类的实例,并使用 @Autowired 注解标注,表示使用 Spring 的自动注入实例,在
package org.lixue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class InvokerController{
@Autowired
private HelloWorldClient helloWorldClient;
@RequestMapping(method=RequestMethod.GET,path="/speak")
public String speak(@RequestParam("name")Stringname){
return helloWorldClient.speak(name);
}
}
- 修改启动类
package org.lixue;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class SpringCloudHystrixClientApplication{
public static void main(String[]args){
SpringApplication.run(SpringCloudHystrixClientApplication.class,args);
}
@LoadBalanced
@Bean
publicRestTemplate restTemplate(){
return new RestTemplate();
}
}
- 增加配置
#配置应用名称
spring:
application:
name:spring-cloud-hystrix-client
#服务端口
server:
port:8077
#设置eureka服务注册中心的地址,如果多个以逗号分割
eureka:
client:
service-url:
defaultZone:http://eurekaserver01:9000/eureka/,http://eurekaserver02:9000/eureka/
- 测试验证
由于我们使用了 Ribbon 因此首先启动 eureka-server 和 service-provider 服务,然后启动该项目,访问 http://localhost:8077/speak?name=abc 可以看到能正常返回信息,如下:
{"abc":"Hello World abc Port=8002"}
这时关闭 service-provider 服务,再次访问这时返回的是我们 speakFallback 方法返回的信息,表示调用出错 Hystrix 进行和回退,如下:
call error,name is abc