-
Feign远程调用:
-
RestTemplate发起远程调用的代码:
存在下面的问题- 代码可读性差,编程体验不统一
- 参数复杂URL难以维护
-
Feign的介绍:Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign其作用就是帮助我们优雅的实现http请求的发送,解决上面提到的问题。
-
Feign替代RestTemplate:使用Feign的步骤如下
-
引入依赖:
<!--使用Feign的依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
在order-service的启动类添加注解开启Feign的功能:
-
编写Feign客户端:
-
用Feign客户端代替RestTemplate
-
-
自定义配置:Feign运行自定义配置来覆盖默认配置,可以修改的配置如下:
-
方式一:配置文件方式
-
全局生效:
feign: client: config: default: #这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置 loggerLevel: FULL #日志级别
-
局部生效:
feign: client: config: userservice: #这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置 loggerLevel: FULL #日志级别
-
-
方式二:Java代码方式,需要先声明一个Bean:
public class FeignClientConfiguration { @Bean public Logger.Level feignLogLevel(){ return Logger.Level.FULL; } }
-
全局配置,则把它放到@EnableFeignClients这个注解中:
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
-
如果是局部配置,则把它放到@FeignClient这个注解中:
@FeignClient(value = "userservice",configuration = FeignClientConfiguration.class)
-
-
-
Feign使用优化
Feign底层的客户端实现:
- URLConnection:默认实现,不支持连接池
- ApacheHttpClient:支持连接池
- OKHttp:支持连接池
因此优化Feign的性能主要包括:
- 使用连接池代替默认的URLConnection
- 日志级别,最好用basic或none
Feign的性能优化-连接池配置
Feign添加HttpClient的支持:
引入依赖:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
配置连接池:
feign: httpclient: enabled: true #开启feign对HttpClient的支持 max-connections: 200 #最大的连接数 max-connections-per-route: 50 #每个路径的最大连接数
-
Feign最佳实践
-
方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准
-
方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO,默认的Feign配置都放到这个模块中,提供给所有消费者使用
-
-
实现最佳实践方式二的步骤如下:
- 首先创建一个module,命名为feign-api,然后引入feign的starter依赖
- 将order-service中的编写的UserClient,User,DefaultFeignConfiguration都复制到feign-api项目中
- 在order-service中引入feign-api的依赖
- 修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
当定义的FeignClient不在SpringBootApplication的扫描范围时,这些FeignClient无法使用。有两种方式解决:
-
方式一:指定FeignClient所在包
@EnableFeignClients(basePackages = "com.cdcas.feign")
-
方式二:指定FeignClient字节码
@EnableFeignClients(clients = {UserClient.class})
-