部分内容摘自 Spring Cloud 官方文档中文版
本文源码地址:https://github.com/Wyxwx/SpringCloudDemo2
目录
为什么要使用断路器
当同一级联下的服务出现故障时,若不及时解决,可能会导致整片服务的整体故障,所以有了断路器的出现。
官方文档解释:断路器计算何时打开和关闭电路,以及在发生故障时应该做什么
Hystrix 基本使用
根据 服务发现:Eureka (一) 注册和运行 创建一个服务注册中心(eureka_server)和两个功能相同的 Eureka 客户端(eureka_client_1、eureka_client_2)
两个客户端的配置文件分别改为:
server.port=8762
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=ribbonClient
server.port=8763
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=ribbonClient
两个客户端的 spring.application.name 相同,代表提供了同一种服务,分配不同的端口模拟在不同服务器的场景
在两个客户端模块中分别创建一个相同的 HelloController
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@Value("${server.port}")
private String port;
@RequestMapping(value = "/hello")
public String hello(){
return "my port is " + port;
}
}
接下来,按照创建 Eureka 客户端的步骤创建一个新的 Module: hystrix
在创建之后的 pom.xml 里加入以下依赖(断路器的使用需要用到负载均衡)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
接下来,编写配置文件 application.properties
server.port=8766
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
spring.application.name=hystrixClient
修改启动类,为其添加 @EnableEurekaClient 、@EnableCircuitBreaker 注解
注入名为 RestTemplate 的类
@LoadBalanced 表明开启负载均衡
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableCircuitBreaker
@EnableEurekaClient
@SpringBootApplication
public class HystrixApplication {
public static void main(String[] args) {
SpringApplication.run(HystrixApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate(){
return new RestTemplate();
}
}
创建一个 HelloService
@HystrixCommand 为该方法创建了断路器功能,并用 fallbackMethod 指定了出错后调用的方法
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@Service
public class HelloService {
@Resource
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "defaultHello")
public String hello(){
return restTemplate.getForObject("http://ribbonClient/hello", String.class) + ": success";
}
public String defaultHello(){
return "fail";
}
}
还可以在 @HystrixCommand 中使用 commandProperties 绑定属性
例如:
@HystrixCommand(fallbackMethod = "stubMyService",
commandProperties = {
@HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
}
)
接下来创建一个 HelloController 在其中调用 HelloService 的方法
import com.example.demo.service.HelloService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class HelloController {
@Resource
private HelloService helloService;
@GetMapping(value = "/hello")
public String hello(){
return helloService.hello();
}
}
依次启动 eureka_server、eureka_client_1、eureka_client_2、hystrix
访问 http://localhost:8761/ 可以看到在服务中心注册了两个分别为 hystrixClient 和 ribbonClient 的 Application
其中,ribbonClient 有两个实例
接下来多次访问 http://localhost:8766/hello 可以看到 port 8762 和 port 8763 交替出现,实现了负载均衡
接下来,关闭 eureka_client_1(或eureka_client_2)
继续访问 http://localhost:8766/hello
会发现 success 页面与 fail 页面交替出现,即断路器成功设置,实际项目中可以根据需要设置 fallbackMethod