-
java代码的方式
- 写一个配置类
public class FeignConfig { /** * 将契约改为feign原生的默认契约。这样就可以使用feign自带的注解了。 * @return 默认的原生契约 */ @Bean public Contract feignContract(){ return new Contract.Default(); } }
- 在注解上添加该类
@FeignClient(name="user-provider",configuration = FeignConfig.class) public interface UserFeignClient { /** * 使用feign自带的注解@RequestLine * @param id * @return */ @RequestLine("GET /user/{id}") User getById(@Param("id") Integer id); }
-
配置文件中配置
feign: client: config: user-provider: # 写了这个就是对某个服务,若用default就是全局设置 connectTimeout: 5000 readTimeout: 5000 loggerLevel: full encoder: feign.form.spring.SpringFormEncoder requestInterceptors: - com.example.feign2.interceptor.RequestHeaderInterceptor
-
日志
-
Logger.Level的值有以下选择:
- NONE: 不记录任何日志(默认值)
- BASIC: 仅记录请求方法、URL、响应状态代码以及执行时间。
- HEADERS: 记录basic级别的基础上,记录请求和响应的header。
- FULL: 记录请求和响应的header、body和元数据。
-
-
性能调优
-
feign底层客户端实现默认使用的是URLConnection,这是jdk自带的发送http请求的包,不支持连接池;这样在发送http请求时,每次都要建立连接(三次握手),发送数据,断开连接(四次挥手),比较浪费性能、消耗时间
-
推荐使用另外两种底层实现(OKHttp,Apache HttpClient其中更推荐Apache HttpClient);
-
日志级别推荐设置basic和none,性能更好
-
引入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
- 添加配置
feign: client: config: default: # default全局的配置 loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息 httpclient: enabled: true # 开启feign对HttpClient的支持 max-connections: 200 # 最大的连接数 max-connections-per-route: 50 # 每个路径的最大连接数
-
-
最佳实践
-
方式一:继承与实现(不怎么推荐)
feign的客户端(服务消费者)和服务端(服务提供者)定义一个统一的父接口,这样统一管理,更加系统化
缺点:高耦合 -
方式二:抽取(推荐使用)
以前是客户端(服务消费者)写一套对服务端(服务提供者)的feign接口,这样当服务增多,每个服务都要写一套对该服务端的feign接口,且修改时也要一一修改;
现在反过来,由服务提供者自己抽取出一个feign的独立模块,其他服务中引入这个模块,即可调用这个服务了,缺点是消费者不能选择某个服务者中某个单一的服务进行消费 -
解释:userservice为服务提供者,orderservice为服务消费者,那我只需要新增(抽取)一个模块,对userservice所有的对外接口、实体类都写到这个模块(feign接口模块)里面来,那么其他所有的模块要使用userservice模块,向userservice发送请求,只需引入userservice的那个feign接口模块,即可使用,所有的服务消费者都使用userservice提供的这一套feign接口
-
创建一个module,命名为feign-api,然后引入feign的starter依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
-
在order-service中引入feign-api的依赖
-
修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包
-
当定义的FeignClient不在SpringBootApplication的扫描包范围时,这些FeignClient无法使用,有两种解决方案:
-
指定Feign应该扫描的包:
@EnableFeignClients(basePackages = "cn.itcast.feign.clients")
- 指定需要加载的Client接口:
@EnableFeignClients(clients = {UserClient.class})
-