本章目录:
先来看我们之前服务通信使用的方法:
我们调用RestTemplate的getObject并手写url来完成服务调用,这样做的缺点是:
目前我们只有一个参数(UserID),日后参数复杂了,难道我们要拼接一个一长串的请求路径吗?
Feign可以帮我们轻松解决上述问题:
Feign是一个声明式的http客户端
官方地址:https://github.com/OpenFeign/feign
其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
使用feign后和我们平常的接口调用没什么区别,代码优雅简介。
在服务消费者的pom文件内引入feign依赖
org.springframework.cloud
spring-cloud-starter-openfeign
在springBoot启动类上添加依赖
新建一个client包,编写UserClient类
@FeignClient("userService")
public interface UserClient {
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
如下图,feignClient其实就是将硬编码的请求方式替换为了我们熟知的Rest风格的请求
把UserClient注入到service层,消费服务。
feign共有四个日志级别:
日志级别 | 打印内容 |
NONE(默认) | 不记录任何日志 |
FULL | 记录请求和响应的header、body和元数据。 |
HEADER | 记录基本信息以及请求和响应标头。 |
BASIC | 只记录请求方法和URL以及响应状态代码和执行时间。 |
feign日志有两种配置方式:
feign: client: # 配置 config: #default为全局配置,如需对指定服务记录日志,换成服务名即可 default: # 控制日志Level,默认:null即NONE # NONE 没有日志 # BASIC 只记录请求方法和URL以及响应状态码和执行时间 # HEADERS 记录基本信息以及请求和响应头 # FULL 记录请求和响应的头、正文和元数据 loggerLevel: FULL
这里要注意的是:
feign日志记录只响应debug级别,所以我们要对Feign客户端(client)的接口的完整类名指定日志级别为:DEBUG
yml配置如下:
新建一个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)
方式二:java代码配置Logger.Level这个Bean
Feign底层的客户端实现:
feign默认使用URLConnection,是没有连接池的
我们都了解过线程池、数据库连接池等;它的好处是避免了频繁的创建连接和销毁的步骤。首先我们知道HTTP连接需要经过三次握手,四次挥手的过程,这是很耗费性能的
而如果我们直接采用 http 连接池,节约了大量的 3 次握手 4 次分手;这样能大大提升吞吐率。
以下是具体实现:
io.github.openfeign feign-httpclient
feign: httpclient: enabled: true #开启feign对HttpClient的支持 max-connections: 200 #最大的连接数 max-connections-per-route: 50 #单个路径的最大连接数 onnections-per-route: 50 #单个路径的最大连接数
上述案例,当一个服务消费者 消费 一个服务提供者,我们需要编写服务提供者的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,不在当前的服务中了,我们需要在当前服务重新指定日志级别
这一步很重要,否则日志不会生效