总结
大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。
麻烦帮忙转发一下这篇文章+关注我
public Order queryOrderById(Long orderId) {
//1. 查询订单
Order order = orderMapper.findById(orderId);
//2. 查询用户
User user = userClient.findById(order.getUserId());
order.setUser(user);
return order;
}
启动自行测试即可。
⏰自定义 Feign 配置
Feign可以支持很多的自定义配置,如下表所示:
类型 | 作用 | 说明 |
---|---|---|
feign.Logger.Level | 修改日志级别 | 包含四种不同的级别:NONE、BASIC、HEADERS、FULL |
feign.codec.Decoder | 响应结果的解析器 | http远程调用的结果做解析,例如解析json字符串为java对象 |
feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过http请求发送 |
feign. Contract | 支持的注解格式 | 默认是SpringMVC的注解 |
feign. Retryer | 失败重试机制 | 请求失败的重试机制,默认是没有,不过会使用Ribbon的重试 |
一般情况下,默认值就能满足我们使用,如果要自定义时,只需要创建自定义的**@Bean覆盖默认Bean即可。**
配置文件的方式配置
基于配置文件修改feign的日志级别可以针对单个服务:
feign:
client:
config:
userservice: # 针对某个微服务的配置
loggerLevel: FULL # 日志级别
针对所有服务
feign:
client:
config:
default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
loggerLevel: FULL # 日志级别
日志级别分为四种
- NONE:不记录任何日志信息,默认
- BASIC:仅记录请求的方法,URL以及响应状态和执行时间
- HEADERS:在BASIC的基础上,加上请求与响应头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、响应信息,元数据
通过代码的方式配置
基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class DefaultFeignConfiguration {
@Bean
public Logger.Level logLevel() {
return Logger.Level.BASIC;
}
}
如果想要 全局生效,将其放入 @EnableFeignClients 注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
局部生效,则放入 FeignClients 注解中,指定服务对其生效:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
四、Feign 使用 优化
Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:
- URLConnection:默认实现,不支持连接池
- Apache HttpClient :支持连接池
- OKHttp:支持连接池
因此提高Feign的性能主要手段就是使用连接池代替默认的URLConnection。
Feign的优化 小结
- 日志级别尽量用basic
- 使用HttpClient或OKHttp代替URLConnection
- 引入feign-httpClient依赖
- 配置文件开启httpClient功能,设置连接池参数
五、Feign 最佳实践方式
所谓最近实践,就是使用过程中总结的经验,最好的一种使用方式。
Feign的客户端与服务提供者的controller代码非常相似:
Feign的客户端
UserController
可以简化这样的重复代码吗,答案肯定可以,下面我们就来看看继承方式来优化代码!
✳️继承方式
一样的代码可以通过继承来共享:
1)定义一个API接口,利用定义方法,并基于SpringMVC注解做声明。
2)Feign客户端和Controller都继承该接口
优点:
- 简单,通俗易懂
- 实现了代码共享
缺点:
- 服务提供方、服务消费方紧耦合
- 参数列表中的注解映射并不会继承,因此controller中必须再次声明方法、参数列表、注解
♻️抽取分离方式
将Feign的Client抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用。
例如,将UserClient、User、Feign的默认配置都抽取到一个feign-api包中,所有微服务引用该依赖包,即可直接使用。
代码实现
新建一个Moudle
项目结构
pom引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
其次,将Clients、User、DefaultFeignConfiguration 都复制进 feign-api
项目中
项目搭建完成、可使用,引入依赖即可
引入依赖使用 feign-api 项目中的配置
在 order-service
项目中引入 feign-api
项目
<dependency>
<groupId>com.wang.demo</groupId>
<artifactId>feign-api</artifactId>
<version>1.0</version>
</dependency>
修改order-service中的所有与上述三个组件有关的导包部分,改成导入feign-api中的包
重启测试
重启测试后,发现报错了:
报错的具体原因是 无法注入该对象,原因是Spring在扫描注入对象的时候,未扫描到该包下的类,所以显示注入失败!
UserClient 在 com.chen.feign.clients
包下,而 order-service 的 @EnableFeignClients在 com.chen.order
下,所以无法扫描
解决问题
方式一
指定 Feign 应该扫描的包
@EnableFeignClients(basePackages = "com.chen.feign.clients")
方式二
指定需要加载的Client接口
最后
在面试前我整理归纳了一些面试学习资料,文中结合我的朋友同学面试美团滴滴这类大厂的资料及案例
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
大家看完有什么不懂的可以在下方留言讨论也可以关注。
觉得文章对你有帮助的话记得关注我点个赞支持一下!
)]
由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
大家看完有什么不懂的可以在下方留言讨论也可以关注。
觉得文章对你有帮助的话记得关注我点个赞支持一下!