Spring Cloud(Finchley版本)系列教程(三) 服务消费者(OpenFeign)
一、Feign和OpenFeign的对比
Feign
是Netflix
公司写的,是SpringCloud
组件中的一个轻量级RESTful
的HTTP
服务客户端,是SpringCloud
中的第一代负载均衡客户端。OpenFeign
是SpringCloud
自己研发的,在Feign
的基础上支持了Spring MVC
的注解,如@RequesMapping
等等。是SpringCloud
中的第二代负载均衡客户端。Feign
是在2019
就已经不再更新了,随之取代的是OpenFeign
,从名字上就可以知道,它是Feign
的升级版。
SpringCloud F 及F版本以上 SpringBoot 2.0 以上基本上使用OpenFeign,OpenFeign如果从框架结构上看就是2019年Feign停更后出现版本,也可以说大多数新项目都用OpenFeign,2018年以前的项目在使用Feign。笔者强烈建议使用OpenFeign,紧跟新技术时代潮流。
二、创建hepServiceOpenFeign项目
复制项目eurekaClient
,并重命名为hepServiceOpenFeign
。
修改pom
文件,下面三项改为hepServiceOpenFeign
,并增加OpenFeign
依赖。
<artifactId>hepServiceOpenFeign</artifactId>
<name>hepServiceOpenFeign</name>
<description>hepServiceOpenFeignhepServiceOpenFeign</description>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
修改pplication.yml
文件,端口改为8007,spring.application.name
为hepServiceOpenFeign
,hostname
也为hepServiceOpenFeign
。
server:
port: 8007 # 端口号
spring:
application:
name: hepServiceOpenFeign # Eureka名称
eureka:
instance:
prefer-ip-address: true
hostname: hepServiceOpenFeign
client:
healthcheck:
enabled: true
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka:eurekapwd@www.huerpu.cc:1678/eureka/
修改启动类名称为HepServiceOpenFeignApplication
,并加上@EnableFeignClients
注解开启Feign的功能。
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class HepServiceOpenFeignApplication {
public static void main(String[] args) {
SpringApplication.run(HepServiceOpenFeignApplication.class, args);
}
}
三、定义Feign接口
定义一个Feign
接口,通过@FeignClient("服务名")
,来指定调用哪个服务。比如在代码中调用了eurekaClient
服务的"/getUserById"
接口,代码如下
package cc.huerpu.eurekaserver.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "eurekaClient")
public interface UserService {
@RequestMapping(value = "/getUserById")
String getUserById();
}
创建一个UserController
,暴露接口"/getUserByIdFeign"
,通过上面定义的Feign
客户端UserService
来消费服务。
package cc.huerpu.eurekaserver.controller;
import cc.huerpu.eurekaserver.feign.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getUserByIdFeign")
public String getUserById(){
return "hepServiceOpenFeign UserController: " + userService.getUserById();
}
}
四、OpenFeign调用验证
启动程序,多次访问接口http://localhost:8007/getUserByIdFeign
,浏览器交替显示
hepServiceOpenFeign UserController: {id:1,name:jason,age:23} from server:eurekaServer:8008
hepServiceOpenFeign UserController: {id:1,name:jason,age:23} from server:eurekaServer:8009
五、OpenFeign配置日志
5.1 OpenFeignConfig配置日志
增加一个OpenFeignConfig
配置,设置日志级别为FULL
。
package cc.huerpu.eurekaclient.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenFeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
// OpenFeign的日志级别有四种分别为NONE、BASIC、HEADERS、FULL。这里输出日志级别FULL
return Logger.Level.FULL;
}
}
SpringBoot
的日志级别默认为info
,大于full
,导致feign
的日志配置不会输出,所以加以下配置
#SpringBoot的日志级别默认为info,大于full,导致feign的日志配置不会输出,所以加以下配置
logging.level.cc.huerpu.eurekaserver.feign: DEBUG
重启项目,并调用接口可得日志的信息
5.2 通过配置文件配置日志
对所有服务生效
# Feign日志全局配置
feign:
client:
config:
default:
loggerLevel: FULL
对单个服务有效
# Feign针对某个服务配置日志
feign:
client:
config:
#想要调用的微服务名称
EUREKACLIENT:
loggerLevel: FULL
六、OpenFeign自定义拦截器
OpenFeign
拦截器,无非就是和我们SpringMVC
中的拦截器一样,每次Feign
发起http
调用之前,会去执行拦截器中的逻辑,比如统一添加header
头信息,对body
体中的信息做修改或替换。Feign
提供了 feign.RequestInterceptor
接口,只需实现该接口,实现对应方法,并将实现类通过 @Configuration
交给spring
容器管理,即可加上我们自己的通用处理逻辑。
通常我们调用的接口都是有权限控制的,很多时候可能认证的值是通过参数去传递的,还有就是通过请求头 去传递认证信息,比如 Basic
认证方式。
创建一个FeignAuthRequestInterceptor
,并实现RequestInterceptor
接口。
package cc.huerpu.eurekaclient.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import java.util.UUID;
public class FeignAuthRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
String uuid = UUID.randomUUID().toString();
requestTemplate.header("Authorization",uuid);
}
}
OpenFeignConfig
中增加FeignAuthRequestInterceptor
配置。
package cc.huerpu.eurekaclient.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenFeignConfig {
@Bean
public Logger.Level feignLoggerLevel(){
// OpenFeign的日志级别有四种分别为NONE、BASIC、HEADERS、FULL。这里输出日志级别FULL
return Logger.Level.FULL;
}
@Bean
public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){
return new FeignAuthRequestInterceptor();
}
}
重启项目,并调用接口可以看到Authorization: 827232db-21fd-4880-aae8-04c974f75a7d
信息
七、超时时间配置
OpenFeign默认超时时间为1s,超过1s就会返回错误页面。如果我们的接口处理业务确实超过1s,就需要对接口进行超时配置
7.1 全局配置
在OpenFeignConfig中注入一个bean。
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
7.2 yml配置
feign:
client:
config:
gulimall-ware:
logger-level: FULL
# 连接超时时间
connectTimeout: 5000
# 请求处理超时时间
readTimeout: 10000
request-interceptors: cc.huerpu.eurekaclient.config.FeignAuthRequestInterceptor
本文参考SpringCloud OpenFeign链接:
https://docs.spring.io/spring-cloud-openfeign/docs/4.0.2/reference/html/