Spring Cloud(Kilburn 2022.0.2版本)系列教程(三) 服务消费者(OpenFeign)
为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000
一、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,紧跟新技术时代潮流。
二、OpenFeign使用
复制项目eurekaClientConsumer
,并修改为openfeignClientConsumer
,修改artifactId
、name
、description
为openfeignClientConsumer
。
<artifactId>openfeignClientConsumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>openfeignClientConsumer</name>
<description>openfeignClientConsumer</description>
增加openfeign
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cc.huerpu</groupId>
<artifactId>openfeignClientConsumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>openfeignClientConsumer</name>
<description>openfeignClientConsumer</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</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>2022.0.2</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>
<repositories>
<repository>
<id>netflix-candidates</id>
<name>Netflix Candidates</name>
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
修改application.yml
文件,修改端口为8003
,还有eurekaClientConsumer
替换成openfeignClientConsumer
。
server:
port: 8003 # 端口号
spring:
application:
name: openfeignClientConsumer # Eureka名称
info:
app:
name: openfeignClientConsumer
encoding: "UTF-8"
java:
source: "17"
target: "17"
company:
name: www.huerpu.cc
management:
info:
env:
enabled: true
endpoints:
web:
exposure:
include: "*"
enabled-by-default: true
eureka:
instance:
prefer-ip-address: false
hostname: openfeignClientConsumer
lease-renewal-interval-in-seconds: 5
lease-expiration-duration-in-seconds: 10
client:
healthcheck:
enabled: true
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://eureka:eurekapwd@eurekaServer:8761/eureka/,http://eureka:eurekapwd@eurekaServerHA:8762/eureka/
registry-fetch-interval-seconds: 5
在启动类上增加@EnableFeignClients
注解
package cc.huerpu.eurekaclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class OpenFeignConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(OpenFeignConsumerApplication.class, args);
}
}
在service
包下创建一个UserService
接口,并增加@FeignClient(value = "EUREKACLIENT")
注解,value
值标识要调用的服务名,也就是在我们的eurekaClient
和eurekaClientProvicer
中定义的应用名,由spring.application.name
指定。
package cc.huerpu.eurekaclient.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
@Component
@FeignClient(value = "EUREKACLIENT") //指定调用哪个微服务
public interface UserService {
@RequestMapping("/getUserById")
public String getUserById();
}
创建一个OpenFeignController
,并把UserService
注入进去,然后定义了一个getUserById
,并去调用userService.getUserById();
package cc.huerpu.eurekaclient.controller;
import cc.huerpu.eurekaclient.service.UserService;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class OpenFeignController {
@Autowired
private UserService userService;
@RequestMapping("/getUserById")
public String getUserById(){
String res = userService.getUserById();
return "OpenFeignController:" + res;
}
}
三、OpenFeign测试
启动项目openfeignClientConsumer
,这时候可以看到已经注册到eureka
上了。
在浏览器调用http://localhost:8003/getUserById
,可以看到正确返回了结果。
四、OpenFeign配置日志
4.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.eurekaclient.service: DEBUG
重启项目,并调用接口可得日志的信息
4.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: e716dece-2d30-42d6-93e3-9dc34bf09103
信息
六、超时时间配置
OpenFeign默认超时时间为1s,超过1s就会返回错误页面。如果我们的接口处理业务确实超过1s,就需要对接口进行超时配置
6.1 全局配置
@Bean
public Request.Options options(){
return new Request.Options(5000,10000);
}
6.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/