Spring Cloud ( openFeign 服务发现配置公共client抽取 )
Posted 白日日白
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Cloud ( openFeign 服务发现配置公共client抽取 )相关的知识,希望对你有一定的参考价值。
本章目录:
- openFeign的引出
- 快速入门
- 引入依赖
- 添加@EnableFeignClients注解
- 编写FeignClient接口
- 使用FeignClient中定义的方法代替RestTemplate
- 日志配置
- 连接池配置
- 公共client抽取
一、openFeign的引出
先来看我们之前服务通信使用的方法:
我们调用RestTemplate的getObject并手写url来完成服务调用,这样做的缺点是:
- 代码可读性差,编程体验不统一
- 参数复杂URL难以维护
目前我们只有一个参数(UserID),日后参数复杂了,难道我们要拼接一个一长串的请求路径吗?
Feign可以帮我们轻松解决上述问题:
Feign是一个声明式的http客户端
官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
使用feign后和我们平常的接口调用没什么区别,代码优雅简介。
二、快速入门
2.1、引入依赖
在服务消费者的pom文件内引入feign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.2、 添加@EnableFeignClients注解
在springBoot启动类上添加依赖
2.3、 编写FeignClient接口
新建一个client包,编写UserClient类
@FeignClient("userService")
public interface UserClient
@GetMapping("/user/id")
User findById(@PathVariable("id") Long id);
如下图,feignClient其实就是将硬编码的请求方式替换为了我们熟知的Rest风格的请求
2.4、使用FeignClient中定义的方法代替RestTemplate
把UserClient注入到service层,消费服务。
三、日志配置
feign共有四个日志级别:
日志级别 | 打印内容 |
NONE(默认) | 不记录任何日志 |
FULL | 记录请求和响应的header、body和元数据。 |
HEADER | 记录基本信息以及请求和响应标头。 |
BASIC | 只记录请求方法和URL以及响应状态代码和执行时间。 |
feign日志有两种配置方式:
- 配置Logger.Level这个Bean
- yml文件配置
3.1、使用yml配置日志
feign: client: # 配置 config: #default为全局配置,如需对指定服务记录日志,换成服务名即可 default: # 控制日志Level,默认:null即NONE # NONE 没有日志 # BASIC 只记录请求方法和URL以及响应状态码和执行时间 # HEADERS 记录基本信息以及请求和响应头 # FULL 记录请求和响应的头、正文和元数据 loggerLevel: FULL
这里要注意的是:
feign日志记录只响应debug级别,所以我们要对Feign客户端(client)的接口的完整类名指定日志级别为:DEBUG
yml配置如下:
3.2、使用Logger.Level配置日志
新建一个config包,编写如下代码:
package cn.itcast.order.config;
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class FeignConfig
@Bean
public Logger.Level feignLogLevel()
return Logger.Level.FULL;
如果是全局配置,则把它放到@EnableFeignClients这个注解中
如果是对特定服务开启日志记录,则把它放到@FeignClient这个注解中
比如我要对userService服务开启日志
总结如下:
Feign的日志配置:
方式一:配置文件(feign.client.config.xxx.loggerLevel)
- 如果xxx是default则代表全局
- 如果xxx是服务名称,例如userservice则代表某服务
方式二:java代码配置Logger.Level这个Bean
- 如果在@EnableFeignClients注解声明则代表全局
- 如果在@FeignClient注解中声明则代表某服务
四、连接池配置
Feign底层的客户端实现:
- URLConnection:默认实现,
- 不支持连接池 Apache HttpClient
- 支持连接池 OKHttp:支持连接池
feign默认使用URLConnection,是没有连接池的
我们都了解过线程池、数据库连接池等;它的好处是避免了频繁的创建连接和销毁的步骤。首先我们知道HTTP连接需要经过三次握手,四次挥手的过程,这是很耗费性能的
而如果我们直接采用 http 连接池,节约了大量的 3 次握手 4 次分手;这样能大大提升吞吐率。
以下是具体实现:
4.1引入httpClient依赖
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
4.2、配置连接池
feign: httpclient: enabled: true #开启feign对HttpClient的支持 max-connections: 200 #最大的连接数 max-connections-per-route: 50 #单个路径的最大连接数 onnections-per-route: 50 #单个路径的最大连接数
五、公共client抽取
上述案例,当一个服务消费者 消费 一个服务提供者,我们需要编写服务提供者的client,client内接口返回的服务提供者的实体类对象,feign配置等等信息。
那么如果这个服务提供者 被多个服务消费者 消费,难道我们要在多个服务消费者内都编写服务提供者的client吗?显然这是不合理的
对于这种情况,我们可以抽取一个moudle,专门编写服务提供者的client,pojo,config等信息。
当某个消费者服务需要使用client,只需要在pom.xml内引入该moudle依赖,然后@Autowired对应client即可。
抽取一个feign-api
比如orderService需要使用UserClient
在orderService的pom.xml内引入feign-api
接着更改启动类@EnableFeignClients注解内的内容
然后把调用client的service层里导入的包都更改为被抽取模块(feign-api)的包
现在我们使用的userClient属于feign-api,不在当前的服务中了,我们需要在当前服务重新指定日志级别
这一步很重要,否则日志不会生效
总结:
- 首先创建一个module,命名为feign-api,
- 然后引入feign的starter依赖
- 将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中 在order-service中引入feign-api的依赖
- 修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
- 重启测试
以上是关于Spring Cloud ( openFeign 服务发现配置公共client抽取 )的主要内容,如果未能解决你的问题,请参考以下文章
spring cloud openFeign传参的一些总结(有错,待更新)