一、什么是Spring Cloud Feign?
- Spring Cloud OpenFeign 是声明式的服务调用工具,它整合了Ribbon和Hystrix,拥有负载均衡和服务容错功能。
- Feign 使得我们只需创建一个接口并用注解的方式来配置它,就可以实现对某个服务接口的调用,简化了直接使用 RestTemplate 来调用服务接口的开发量。
- Feign 具备可插拔的注解支持,同时支持Feign注解、JAX-RS注解及SpringMvc注解。
- Feign 在使用时 Spring Cloud 集成了Ribbon和Eureka以提供负载均衡的服务调用及基于Hystrix的服务容错保护功能。
二、与Ribbon对比
- 使用 Ribbon + RestTemplate 时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。
- 使用 Feign 在此基础上做了进一步封装,由它来帮助我们定义和实现依赖服务接口的定义,在Feign的实现下,我们只需要创建一个接口并使用注解的方式来配置它,现在是一个微服务接口上面标注一个Feign注解即可完成对服务提供方的接口绑定。
- 利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并且通过轮询实现了客户端的负载均衡。
- 利用Feign只需要定义服务绑定接口且以声明式的方法,优雅而且简单的实现了服务调用。
三、执行原理
- 启动时,程序会进行包扫描,扫描所有包下所有@FeignClient注解的类,并将这些类注入到spring的IOC容器中。当定义的Feign中的接口被调用时,通过JDK的动态代理来生成RequestTemplate。
- RequestTemplate中包含请求的所有信息,如请求参数,请求URL等。
- RequestTemplate声场Request,然后将Request交给client处理,这个client默认是JDK的HTTPUrlConnection,也可以是OKhttp、Apache的HTTPClient等。
- 最后client封装成LoadBaLanceClient,结合ribbon负载均衡地发起调用。
四、案例演示
-
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.0.RELEASE</version> </dependency>
-
添加配置
启动类
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient @EnableFeignClients(basePackages = "com.jhy.feign.service") public class FeignClientApplication { public static void main(String[] args) { SpringApplication.run(FeignClientApplication.class, args); } }
自定义配置类
@Configuration public class FeignConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
application.yml配置文件
server.port=8080 server.servlet.context-path=/ spring.application.name=feign-client eureka.client.fetch-registry=true eureka.client.register-with-eureka=true eureka.client.service-url.defaultZone: http://localhost:8010/eureka/
-
添加服务
-
service
@Component @FeignClient(value = "feign-service") public interface UserService { @GetMapping("/get/{id}") Map<String, Object> getUserById(@PathVariable Long id); @PostMapping("/add") Map<String, Object> addUser(@RequestBody User user); }
-
controller
@RestController public class UserController { @Autowired private UserService userService; @GetMapping("/get/{id}") public Map<String, Object> getUser(@PathVariable Long id){ return userService.getUserById(id); } @GetMapping("/add") public Map<String, Object> addUser(User user){ return userService.addUser(user); } }
-
-
测试使用
多次访问:http://localhost:8080/get/1
可以看到Feign默认采用轮询算法依次在每一个服务方进行访问
五、服务降级示例
利用Feign我们只需要为Feign客户端定义的业务接口添加一个服务降级处理的实现类即可
-
修改配置
# 修改application.yml文件(添加如下内容) feign: hystrix: enabled: true
-
添加实现类
@Component public class UserFallbackService implements UserService { @Override public Map<String, Object> getUserById(Long id) { User user = new User(1L, "张三", "zhangsan"); Map<String, Object> result = new HashMap<>(); result.put("type", "ok"); result.put("msg", "查询成功(fallback-service)"); result.put("content", user); return result; } @Override public Map<String, Object> addUser(User user) { Map<String, Object> result = new HashMap<>(); result.put("type", "ok"); result.put("msg", "添加成功"); result.put("content", user); return result; } }
-
修改接口类
@Component @FeignClient(value = "feign-service", fallback = UserFallbackService.class) public interface UserService { @GetMapping("/get/{id}") Map<String, Object> getUserById(@PathVariable Long id); @PostMapping("/add") Map<String, Object> addUser(@RequestBody User user); }
-
测试使用
关闭所有feign-service服务
访问:http://localhost:8080/get/1
发现服务接口调用的是我们服务降级编写的实现类
六、开启日志打印
Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中HTTP请求的细节。
-
日志级别
NONE
:默认的,不显示任何日志BASIC
:仅记录请求方法、URL、响应状态码及执行时间HEADERS
:除了BASIC中定义的信息之外,还有请求和响应的头信息FULL
:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据
-
添加配置
配置类方式
@Configuration public class FeignConfig { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
配置文件方式
# 修改application.yml文件(添加如下内容) logging: level: com.jhy.feign.service.UserService: debug
-
测试使用
访问:http://localhost:8080/get/1
七、常用配置
feign:
hystrix:
#在Feign中开启Hystrix容错功能
enabled: true
compression:
request:
#是否对请求进行GZIP压缩
enabled: false
#指定压缩的请求数据类型
mime-types: text/xml,application/xml,application/json
#超过该大小的请求会被压缩
min-request-size: 2048
response:
#是否对响应进行GZIP压缩
enabled: false
#修改日志级别
logging:
level:
com.macro.cloud.service.UserService: debug
【源码地址】:GitHub