微服务中关于feign整合hystrix的案例使用以及注意事项
微服务中关于feign整合hystrix的案例使用以及注意事项
2018年12月19日 22:23:06 uniquewdl 阅读数:134
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.****.net/uniqueweimeijun/article/details/85108794
What Is Hystrix?
在一个分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等,如何能够保证在一个依赖出问题的情况下,不会导致整体服务失败,这个就是Hystrix需要做的事情。Hystrix提供了熔断、隔离、Fallback、cache、监控等功能,能够在一个、或多个依赖同时出现问题时保证系统依然可用。知道它的,作用优点和好处了。那么下边就跟着我一起来操作一下feign整合Hystrix。
1.创建feign项目
1.pom文件
-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
<artifactId>feign-customizing</artifactId>
-
<packaging>jar</packaging>
-
<parent>
-
<groupId>com.itmuch.cloud</groupId>
-
<artifactId>microservice-spring-cloud</artifactId>
-
<version>0.0.1-SNAPSHOT</version>
-
</parent>
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
<java.version>1.8</java.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.boot</groupId>
-
<artifactId>spring-boot-starter-actuator</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-feign</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-hystrix</artifactId>
-
</dependency>
-
</dependencies>
-
</project>
---------------pom文件的注意点就是一定要注意springboot的版本,版本不能太高。否则会报错找不到方法的异常。具体分析在后续博客中会详细分析。
2.配置文件:
application.yml文件
-
spring:
-
application:
-
name: microservice-consumer-movie
-
server:
-
port: 2000
-
eureka:
-
client:
-
healthcheck:
-
enabled: true
-
serviceUrl:
-
defaultZone: http://47.xxx.6.xxx:1000/eureka
-
instance:
-
prefer-ip-address: true
-
logging:
-
level:
-
com.itmuch.cloud.feign.UserFeignClient: DEBUG
注意点:
#可以通过下边的配置设置超时时间,默认为一秒即为1000:
也可以通过下边的设置来更好的观察项目的效果
# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
# 或者:
# hystrix.command.default.execution.timeout.enabled: false
# 或者:
feign.hystrix.enabled: true ## 索性禁用feign的hystrix
# 超时的issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/768
# 超时的解决方案: http://stackoverflow.com/questions/27375557/hystrix-command-fails-with-timed-out-and-no-fallback-available
# hystrix配置: https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.thread.timeoutInMilliseconds
3,启动类
Applicatoin
-
import org.springframework.boot.SpringApplication;
-
import org.springframework.boot.autoconfigure.SpringBootApplication;
-
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
-
import org.springframework.cloud.netflix.feign.EnableFeignClients;
-
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
-
@SpringBootApplication
-
@EnableDiscoveryClient
-
@EnableFeignClients
-
@EnableHystrixDashboard
-
public class MyFeignApplication {
-
public static void main(String[] args) {
-
SpringApplication.run(MyFeignApplication.class, args);
-
}
-
}
注意点:四个注解缺一不可:
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrixDashboard
4.建立controller
-
package com.itmuch.cloud.controller;
-
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 com.itmuch.cloud.entity.User;
-
import com.itmuch.cloud.feign.FeignClient2;
-
import com.itmuch.cloud.feign.UserFeignClient;
-
@RestController
-
public class TestController {
-
@Autowired
-
private UserFeignClient userFeignClient;
-
@RequestMapping("/index")
-
public String index() {
-
String str = userFeignClient.getContext();
-
return str;
-
}
-
}
这里的controller是一个外部入口,通过请求index方法进而调用下边的feign方法,
5.feign的接口配置(重点)
-
import org.springframework.cloud.netflix.feign.FeignClient;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.annotation.RequestMethod;
-
@FeignClient(name = "feign-user", fallback = MyHystrix.class)
-
public interface UserFeignClient {
-
@RequestMapping(value="/getContext",method=RequestMethod.GET)
-
public String getContext();
-
}
注意点:@FeignClient(name = "feign-user", fallback = MyHystrix.class) 这里就是feign的核心配置,name属性是feign请求外部接口的服务名称(就是一同注册到注册中心的服务名称) fallback就是产生异常错误后的回退路径
要求fallback指向的类必须实现feign接口。然后再对应的接口的实现具体实现自定义 的异常处理(抛错,提示异常,回退等操作)。注意点2feign中 的方法注解不支持GetMapping 以及如果是@PathVariable一定要有值。
附加fallback的类
-
import org.springframework.stereotype.Component;
-
@Component
-
public class MyHystrix implements UserFeignClient {
-
@Override
-
public String getContext() {
-
System.err.println("=======报错");
-
return "报错了";
-
}
-
}
说明,如果是UserFeignClient的某个方法由于超时,异常等非正常操作都会进入对应Hystrix方法中,这样更好地捕获异常和进行处理。
6.新建一个项目作为feign的请求项目,要求该项目也能够注册到注册中心上(eureka等)
下边不做详细说明核心代码如下:
7.pom文件
-
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
<modelVersion>4.0.0</modelVersion>
-
<artifactId>movie-feign</artifactId>
-
<packaging>jar</packaging>
-
<parent>
-
<groupId>com.itmuch.cloud</groupId>
-
<artifactId>microservice-spring-cloud</artifactId>
-
<version>0.0.1-SNAPSHOT</version>
-
</parent>
-
<properties>
-
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-
<java.version>1.8</java.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.boot</groupId>
-
<artifactId>spring-boot-starter-actuator</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.cloud</groupId>
-
<artifactId>spring-cloud-starter-feign</artifactId>
-
</dependency>
-
</dependencies>
-
</project>
8.application.yml
-
spring:
-
application:
-
name: provider-user
-
server:
-
port: 2001
-
eureka:
-
client:
-
healthcheck:
-
enabled: true
-
serviceUrl:
-
defaultZone: http://47.xxx.6.xxx:1000/eureka
-
instance:
-
prefer-ip-address: true
9.请求端controller
-
package com.itmuch.cloud.controller;
-
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;
-
import com.itmuch.cloud.entity.User;
-
import com.itmuch.cloud.feign.UserFeignClient;
-
@RestController
-
public class MovieController {
-
/*
-
* @GetMapping("/test") public User testPost(User user) { return
-
* this.userFeignClient.postUser(); }
-
*
-
* @GetMapping("/test-get") public User testGet(User user) { return
-
* this.userFeignClient.getUser(user); }
-
*/
-
@RequestMapping("/getContext")
-
public String getContext() {
-
return "我是服务端的getContext方法";
-
}
-
}
10.最后来波效果图:
10-1eureka注册中心
1
10-2 失败结果
10-3成功