1、简介
Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。
Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。
2、导入jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--由于feign整合了ribbon的负载均衡,所以需要引入ribbon的依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<!--需要从eureka拉取服务-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
3、启动类添加注解支持
@EnableFeignClients
4、客户端编写
//定义接口
package com.sun.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(value = "user-service") //声明这是feign的客户端
public interface UserFeignClient {
@GetMapping("user")
public String getUser();
}
注释:
这是一个接口,Feign会通过动态代理,帮我们生成实现类。这点跟mybatis的mapper很像
@FeignClient,声明这是一个Feign客户端,类似@Mapper注解。同时通过value属性指定服务名称
接口中的定义方法,完全采用SpringMVC的注解,Feign会根据注解帮我们生成URL,并访问获取结果
改造原来的调用逻辑,不再调用UserDao:
//实现调用
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("feign")
public Object feign(){
return userFeignClient.getUser();
}
5、feign自动实现负载均衡
6、feign的重试
#feign的重试与ribbon的配置相同,只要添加相应的配置即可。
client:
ribbon:
MaxAutoRetries: 1 #配置首台服务器重试1次
MaxAutoRetriesNextServer: 2#配置其他服务器重试两次
ConnectTimeout: 500 #链接超时时间
ReadTimeout: 2000 #请求处理时间
OkToRetryOnAllOperations: true #每个操作都开启重试机制
7、feign与hystrix的集成配置熔断机制
a、 添加熔断配置
feign:
hystrix:
enabled: true #允许熔断
b、添加熔断处理类
//实现 UserFeignClient接口
@Component
public class UserFeignClientImpl implements UserFeignClient {
@Override
public String getUser() {
return "访问人数过多";
}
}
c、实现调用
@FeignClient(value = "user-service",fallback = UserFeignClientImpl.class) //声明这是feign的客户端 fallback 哪个出现访问延迟 就调用哪个方法的实现返回处理结果
public interface UserFeignClient { //接口定义
@GetMapping("user")
public String getUser();
}
//调用
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("feign")
public Object feign(){
return userFeignClient.getUser();
}