Feign是一种声明式、模板化的HTTP客户端。在Spring Cloud中使用Feign, 我们可以做到使用HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个HTTP请求。
Feign基于Netflix 实现,整合了spring cloud ribbon 和 spring cloud hystrix,除了两者的强大功能外还提供了一种声明式的web服务客户端定义方式。
spring cloud feign 具备可拔插的注解支持,包括feign注解、JAX-RS注解,也扩展spring MVC注解支持。
spring cloud feign代替dubbo进行服务直接的调用
快速入门:
1、pom.xml中引入spring-cloud-starter-eureka 和 spring-cloud-starter-feign依赖:
<?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>
<groupId>com.dome</groupId>
<artifactId>eureka-clean</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</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.SR1</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- feigen start -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<!-- feigen end -->
<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>
<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>
pom文件中要引入eureka依赖和feign依赖
2、在启动类中添加@EnableFeignClients 和 @EnableEurekaClient开启spring cloud feign功能:
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class EurekaDomeCleanApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaDomeCleanApplication.class, args);
}
3、application.yml 配置:
server:
port: 7777
eureka:
client:
register-with-eureka: false
serviceUrl:
defaultZone: http://localhost:1111/eureka
注意这里的配置没有feign特有的配置
4、创建接口:
@FeignClient("test-service")
public interface FeignService {
@RequestMapping("/hello")
String hello() ;
}
注意:这里的服务名不区分大小写,所以使用test-service和TEST-SERVICE都是可以的,在BRIXTON.SR5版本中,原有的serviceis属性已经被废弃,若要写属性名,可以使用name或者value
5、使用接口调用服务:
@Autowired
private FeignService fs;
public String test() {
return fs.hello();
}
这种方法开发是开发中最常用的方式,开发时provider会提供一个 provider-service-api 里面提供feign接口供consumer依赖使用
配置:
-
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds
:断路器的超时时间需要大于ribbon的超时时间,不然不会触发重试。 -
hello-service.ribbon.ConnectTimeout
:请求连接的超时时间 -
hello-service.ribbon.ReadTimeout
:请求处理的超时时间 -
hello-service.ribbon.OkToRetryOnAllOperations
:(true/false)对所有操作请求都进行重试 -
hello-service.ribbon.MaxAutoRetriesNextServer
:切换实例的重试次数 -
hello-service.ribbon.MaxAutoRetries
:对当前实例的重试次数
根据如上配置,当访问到故障请求的时候,它会再尝试访问一次当前实例(次数由MaxAutoRetries
配置),如果不行,就换一个实例进行访问,如果还是不行,再换一次实例访问(更换次数由MaxAutoRetriesNextServer
配置),如果依然不行,返回失败信息。
问题总结:
不加@feignclient注解回报bean找不到的错误:
Error creating bean with name 'srBusApplyController': Unsatisfied dependency expressed through field 'busApplyService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.sr.modules.biz.api.BusApplyService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
@feignclient注解不能传递,假如A接口有@feignclient注解,B接口继承A接口,这样B接口是无效的,会出现以上错误