SpringCloud 中使用 Hystrix 一般有两个形式:
- 在RestTemplate 和 Ribbon 上使用 Hystrix
- 在Feign 上使用 Hystrix
今天学习第一种方法。
一:创建 eureka-ribbon-hystrix-client 服务
1.1 在主Maven工程中创建一个新的 Module 工程,命名为eureka-ribbon-hystrix-client。采用Spring Initializr 的方式的方式创建。
1.2 eureka-ribbon-hystrix-client 的 pom.xml 的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-hx</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eureka-ribbon-hystrix-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-ribbon-hystrix-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</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-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.3 主Module 的 的 pom.xml 加上:
2.4 eureka-ribbon-hystrix-client 的 配置文件 application.yml 的内容如下:
server:
port: 8765
spring:
#配置程序名为eureka-ribbon-hystrix-client
application:
name: eureka-ribbon-hystrix-client
eureka:
client:
#服务注册地址
serviceUrl:
#注意: Eureka Server 的注册地址
#将服务提供者注册到三个Eureka Server中去
#defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/
#defaultZone: http://peer1:8001/eureka/
defaultZone: http://localhost:8761/eureka/
2.5 在启动类上加上 @EnableDiscoveryClient 开启服务注册于发现,加上@EnableHystrix 开启Hystrix 的熔断器功能,代码如下:
package com.example.eurekaribbonhystrixclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
@SpringBootApplication
//开启服务注册于发现
@EnableDiscoveryClient
//开启Hystrix 的熔断器功能
@EnableHystrix
public class EurekaRibbonHystrixClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaRibbonHystrixClientApplication.class, args);
}
}
2.6 设置RestTemplate 和 Ribbon 的负载均衡
我们先创建一个Ribbon 的 配置类 RibbonConfig ,代码如下:
package com.example.eurekaribbonhystrixclient.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 如何将RestTemplate 和 Ribbon 相结合进行负载均衡?
* 只需要在程序的IOC容器中注入一个 RestTemplate 的 Bean,并在这个 Bean 上加上 @LoadBalanced 注解(负载均衡注解)
* 此时 RestTemplate 就结合 Ribbon 开启了负载均衡功能
*
*/
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
2.7 写一个 RibbonService 类,在该类的 hi() 方法 用 restTemplate 调用 eureka-client 的 API 接口,此时Uri 上不需要 硬编码 (例如 IP地址),只需要写服务名eureka-client 即可 ,代码如下:
package com.example.eurekaribbonhystrixclient.service;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class RibbonService {
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "hiError")
public String helloRibbon(String name) {
return restTemplate.getForObject("http://eureka-client/HiController/hi/" + name, String.class);
}
public String hiError(String name){
return "hi,"+name+",sorry,error";
}
}
在hi() 方法上加上 @HystrixCommand(fallbackMethod = “hiError”) 注解。有了@HystrixCommand 注解,hi()方法就启用了Hystrix 熔断器的功能,其中fallbackMethod 为 处理回退,fallbackMethod里的值 hiError 表示在该方法调用服务失败后 回滚调用的方法。
2.8 接着写一个 RibbonController 类,代码如下:
package com.example.eurekaribbonhystrixclient.web;
import com.example.eurekaribbonhystrixclient.service.RibbonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/RibbonController")
public class RibbonController {
@Autowired
private RibbonService ribbonService;
@GetMapping("/hi/{name}")
public String helloRibbon(@PathVariable("name") String name) {
String result = ribbonService.helloRibbon(name);
return result;
}
}
2.9 分别启动 eureka-server , eureka-client 8762 端口, eureka-client 8763端口 ,eureka-ribbon-hystrix-client 服务。
浏览器访问 http://localhost:8761/
截止在浏览器上 输入 :http://localhost:8765/RibbonController/hi/java,得到结果如下:
关掉eureka-client 服务,效果如图:
可以看到在关掉eureka-client 服务,我们调用时方法时,页面并没有返回错误,而是调用了fallbackMethod 中的 hiError 方法。这就说明Hystrix已经起到了作用。