前言
微服务中经常会用到熔断器来增强服务依赖的稳定性,他可以在网络连接缓慢,资源繁忙,暂时不可用,服务脱机等情况中进行服务的快速失败,并可自我恢复,以避免请求线程的堆积造成大量资源的浪费。
相信读者看这篇文章的目的都是解决实际问题,并不是来看我分析源码的,如果对源码感兴趣的我推荐《重新定义》,所以我们直接上干货,下面我们就简单的利用Feign中集成的Hystrix进行快速失败和请求降级处理。
正文
首先准备一个父项目,里面只有各个服务所需的依赖包,下面就是父项目的pom,可以看到我这次演练的项目有三个,分别是eureka-server,consumer-service,provider-service
一、父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch6-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>ch6-2-eureka-server</module>
<module>ch6-2-consumer-service</module>
<module>ch6-2-provider-service</module>
</modules>
<!-- 管理依赖 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!--注意: 这里必须要添加, 否者各种依赖有问题 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
二、下面创建eureka-server服务 下面依次是pom,yml,和启动类的代码,这里不做解释了,前几个博客已经介绍过类似的内容。
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch6-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch6-2-eureka-server</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
三、接下来创建一个被feign调用的服务:provider-service。 这里很简单,就是定一个请求地址,用来映射到feign接口上的URl。
下面代码依次是provider-service中的controller、启动类、pom、yml
这里其实重点就是利用了spring-cloud-starter-netflix-hystrix,别的都没什么可解释的。
@RestController
public class TestController {
@RequestMapping(value = "/getUser",method = RequestMethod.GET)
public String getUser(@RequestParam("username") String username){
return "This is real user";
}
------------------------------------------
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
------------------------------------------
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch6-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch6-2-provider-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
四、最后创建一个consumer-service工程
这里的代码相对上两个服务要多一些,不过我会按照一定的顺序给大家展示,
首先是controller、Feign接口,Feign的快速返回/降级方法、pom、yml,一共五块代码
@RestController
public class TestController {
@Autowired
private IUserService userService;
@RequestMapping(value = "/getUser",method = RequestMethod.GET)
public String getUser(@RequestParam("username") String username) throws Exception{
return userService.getUser(username);
}
@FeignClient(name = "sc-provider-service", fallback = UserServiceFallback.class)
public interface IUserService {
@RequestMapping(value = "/getUser",method = RequestMethod.GET)
String getUser(@RequestParam("username") String username);
}
@Component
public class UserServiceFallback implements IUserService{
/**
* 出错则调用该方法返回友好错误
* @param username
* @return
*/
public String getUser(String username){
return "The user does not exist in this system, please confirm username";
}
}
<parent>
<groupId>cn.springcloud.book</groupId>
<artifactId>ch6-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>ch6-2-consumer-service</artifactId>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
server:
port: 8888
spring:
application:
name: sc-consumer-service
eureka:
client:
serviceUrl:
defaultZone: http://${eureka.host:127.0.0.1}:${eureka.port:8761}/eureka/
instance:
prefer-ip-address: true
feign:
hystrix:
enabled: true
好了,五块代码粘贴完毕,下面是对上面代码的解释,
首先controller是我们对外暴露的请求入口,调用了当前服务的Feign接口,
重点是这句话
@FeignClient(name = "sc-provider-service", fallback = UserServiceFallback.class),
name参数代表请求映射的服务spring. application.name,
fallback参数指定的是一个类,这个类必须要实现当前的Feign接口才可以,用于feign调用sc-provider-service服务时失败的快速返回类。然后就是UserServiceFallback类一定注入spring容器。
同样,这个工程也需要spring-cloud-starter-netflix-hystrix 依赖,另外这里我用了openfeign你可以理解为feign的升级版。
还有一点需要注意的是高版本中feign的hystrix是默认关闭的,所有我们要手动打开
三个服务分别启动,首先eureka-service先启动。
我们可以看到消费者工程和生产者工程分别注册上了eureka,我们访问http://localhost:8888/getUser?username=1,当然是访问不到的了,但是返回
我们知道这句话是我fallback参数指定类的方法返回的,
这样一个简单的利用feign 集成的熔断器实现快速返回的例子。
注:对本文有异议或不明白的地方微信探讨,wx:15524579896