一 OpenFeign介绍
OpenFeign是一种基于Spring Cloud的声明式REST客户端,它简化了与HTTP服务交互的过程。它将REST客户端的定义转化为Java接口,并且可以通过注解的方式来声明请求参数、请求方式、请求头等信息,从而使得客户端的使用更加方便和简洁。同时,它还提供了负载均衡和服务发现等功能,可以与Eureka、Consul等注册中心集成使用。
参考文档:官方文档
二 调用组件Spring Cloud OpenFeign示例
1. 引入OpenFeign依赖
在父模块或服务模块引入依赖
<!-- OpenFeign服务调用--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- 负载均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>2. 在启动类开启@EnableFeignClients注解
// 开启feign 功能@EnableFeignClients@EnableDiscoveryClient@SpringBootApplicationpublicclassOrderServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(OrderServiceApplication.class,args);}}3.编写OpenFeign客户端
// 调用自有服务@FeignClient(value="user-service")publicinterfaceUserFeignClient{@GetMapping("/user/{id}")UserEntitygetUserById(@PathVariable("id")Longid);}//调用第三方应用服务,可以设置调用接口url@FeignClient(value="xxxxx-service",url="https://xxxxx")publicinterfaceXxxxFeignClient{@GetMapping("/xxxx/{id}")XxxxEntitygetXxxxById(@PathVariable("id")Longid);}4.像调用本地方式一样调用远程微服务提供者
@RequestMapping("/api/order")@RestControllerpublicclassOrderController{@AutowiredUserFeignClientuserFeignClient;@GetMapping("/orderUser/{id}")publicUserEntitygetUSerById(@PathVariable("id")Longid){returnuserFeignClient.getUserById(id);}}5.OpenFeign调用流程
三 OpenFeign其他功能支持
1. 日志配置
每个创建的 Feign 客户端都会创建一个logger。在调试程序时,配置Feign的日志了,打印出Feign的请求信息来。
NONE, 没日志(默认)。
BASIC, 只记录请求方法和URL以及响应状态代码和执行时间。
HEADERS, 记录基本信息以及请求和响应头。
FULL, 记录请求和响应的header、正文和元数据。
配置javaBean
@ConfigurationpublicclassOrderConfig{@BeanLogger.LevelfeignLoggerLevel(){returnLogger.Level.FULL;}}添加yml 配置
spring:cloud:openfeign:client:config:#全局default:logger-level:full#对应feign服务名user-service:logger-level:full2. 超时时间设置
open Feign使用两个超时参数:
- connect Timeout 连接超时,可以防止由于较长的服务器处理时间而阻塞调用者。
- readTimeout 请求处理超时,从连接建立时开始应用,当返回响应花费太长时间时触发。
添加yml 配置
spring:cloud:openfeign:client:config:#全局default:logger-level:fullconnect-timeout:3000read-timeout:3000#对应feign服务名user-service:logger-level:fullconnect-timeout:3000read-timeout:50003. 客户端组件配置
Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,没有连接池,可以集成别的组件来替换掉 URLConnection,比如 Apache HttpClient5,OkHttp。
父pom 引入依赖
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-hc5</artifactId></dependency>添加yml 配置
spring:cloud:openfeign:#使用 Apache HttpClient 5httpclient:hc5:enable:trueclient:config:#全局default:logger-level:fullconnect-timeout:3000read-timeout:3000#对应feign服务名user-service:logger-level:fullconnect-timeout:3000read-timeout:50004.拦截器配置
通常我们调用的接口都是有权限控制的,很多时候可能认证的值是通过参数传递的,还有就是通过请求头去传递认证信息。设置feign拦截器,每次 feign 发起http调用之前,会去执行拦截器中的逻辑。
使用场景:统一添加 header 信息;对 body 中的信息做修改或替换;
packageorg.example.interceptor;importfeign.RequestInterceptor;importfeign.RequestTemplate;importjakarta.servlet.http.HttpServletRequest;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Component;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.ServletRequestAttributes;importjava.util.UUID;@Slf4j@ComponentpublicclassXTokenRequestInterceptorimplementsRequestInterceptor{/** * feign请求拦截器,将共享数据传到下游 * @param template */@Overridepublicvoidapply(RequestTemplatetemplate){// 业务逻辑 模拟认证逻辑ServletRequestAttributesattributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if(null!=attributes){HttpServletRequestrequest=attributes.getRequest();Stringaccess_token=request.getHeader("Authorization");//设置tokentemplate.header("Authorization",access_token);}}/** * 自定义拦截器 * @return */@BeanpublicXTokenRequestInterceptorfeignAuthRequestInterceptor(){returnnewXTokenRequestInterceptor();}}