OpenFeign远程调用组件的使用教程
使用的springcolud版本是
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
1.OpenFeign介绍
- OpenFeign是个声明式WebService客户端,使用OpenFeign让编写WebService客户端更简单
- 它的使用方法是定义一个服务接口然后在上面添加注解
- OpenFeign也支持可拔插式的编码器和解码器
- SpringCloud对OpenFeign进行了封装使其支持了SpringMVC标准注解和HttpMessageConverters
- OpenFeign可以与Eureka和Ribbon组合使用以支持负载均衡
Feign
- Feign是SpringCloud组件中的一个轻量级RESTful的HTTP服务客户端
- Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务
- Feign的使用方式是:使用Feign的注解定义接口,调用服务注册中心的服务
- Feign支持的注解和用法请参考官方文档
- Feign本身不支持SpringMVC的注解,它有一套自己的注解
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-feign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
Open Feign
- OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequesMapping等等。
- OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口
- OpenFeign通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.OpenFeign应用实例
使用OpenFeign远程调用服务提供方
-
导入依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
在主程序使用注解"@EnableFeignClients"开启OpenFeign客户端功能
package anyi.space.memberConsumer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @ProjectName: distributedSystemLearn * @FileName: MemberConsumerApplication * @Author: 杨逸 * @Data:2025/4/13 20:05 * @Description: */ //开启Feign客户端 @EnableFeignClients @EnableDiscoveryClient @EnableEurekaClient @SpringBootApplication(exclude= DataSourceAutoConfiguration.class) public class MemberConsumerApplication { public static void main(String[] args) { SpringApplication.run(MemberConsumerApplication.class,args); } }
-
根据远程服务API定义Feign接口类
- 使用注解"@FeignClient"标注这是一个OpenFeign客户端,注解参数value是注册到服务注册中心的服务提供方的名称
- 根据远程API定义接口中的方法,然后使用SpringMC中的注解标注远程调用API的地址和需要传输的参数,接口方法的返回类型与接口API返回的类型保持一致,OpenFeign将通过动态代理的方式实现这个接口的方法,并封装返回的对象
package anyi.space.memberConsumer.service; import anyi.sapce.common.entity.Member; import anyi.sapce.common.entity.ResponseResult; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; /** * @ProjectName: distributedSystemLearn * @FileName: MemberService * @Author: 杨逸 * @Data:2025/4/13 20:10 * @Description: */ //注入到IOC容器中 @Component //声明这是一个Feign客户端,value的值为服务提供方注册到服务注册中心的名称 @FeignClient(value = "member-service-provider") public interface MemberService { /** * 根据id查询会员信息 * @param id * @return 会员信息 * 使用SpringMVC的注解来声明远程调用接口和接口的参数 */ @GetMapping("/member-provider/member") ResponseResult<Member> getById(@RequestParam("id") Long id); /** * 新增会员信息 * @param member * @return 成功ture,失败false */ @PostMapping("/member-provider/member") ResponseResult<Boolean> save(@RequestBody Member member); }
-
在服务消费方Controller使用Feign接口进行远程调用
package anyi.space.memberConsumer.controller; import anyi.sapce.common.entity.Member; import anyi.sapce.common.entity.ResponseResult; import anyi.space.memberConsumer.service.MemberService; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.util.DigestUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.nio.charset.StandardCharsets; import java.util.List; /** * @ProjectName: distributedSystemLearn * @FileName: MemberConsumerController * @Author: 杨逸 * @Data:2025/4/13 20:07 * @Description: */ @Slf4j @RequiredArgsConstructor @RestController @RequestMapping("/member") public class MemberConsumerController { private final MemberService memberService; private final DiscoveryClient discoveryClient; private final ObjectMapper objectMapper; @GetMapping public ResponseResult<Member> getMemberById(Long id){ return memberService.getById(id); } @PostMapping public ResponseResult addMember(Member member){ String hex = DigestUtils.md5DigestAsHex(member.getPwd().getBytes(StandardCharsets.UTF_8)); member.setPwd(hex); return memberService.save(member); } }
-
验证
调用接口验证,经两次调用,验证成功访问到服务提供方,并且是轮询的负载均衡算法
3.OpenFeign设置日志级别
-
在配置类中注入Openfeign日志配置bean
注入一个feign.Logger配置类
package anyi.space.memberConsumer.config; import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @ProjectName: distributedSystemLearn * @FileName: OpenFeignConfig * @Author: 杨逸 * @Data:2025/5/16 20:23 * @Description: 设置OpenFeign的日志级别 */ @Configuration public class OpenFeignConfig { @Bean public Logger.Level loggerLevel(){ return Logger.Level.FULL; } }
-
在application.yaml配置文件中设置OpenFeign接口的日志级别
logging: level: #配置Feign客户端的日志级别 anyi.space.memberConsumer.service.MemberService: trace
- 日志级别的分类
日志级别 说明 error 错误日志,指比较严重的错误,对正常业务有影响,需要运维配置监控的 warn 警告日志,一般的错误,对业务影响不大,但是需要开发关注 info 信息日志,记录排查问题的关键信息,如调用时间、出参入参等等 debug 用于开发DEBUG的,关键逻辑里面的运行时数据 trace 最详细的信息,一般这些信息只记录到日志文件中 -
验证配置的日志级别
4.OpenFeign超时设置
OpenFeign远程调用接口默认的超时时间是一秒,正常的接口一般都能满足这个要求
但也存在耗时的接口或者网络阻塞等情况,我们需要对超时时间间隔进行调整
- 在application.yaml中配置超时时间
feign:
client:
#config是一个map
config:
#服务提供方名称,可以针对不同的服务提供方进行隔离的配置
member-service-provider:
#日志级别
loggerLevel: full
#设置为默认的契约(还原成原生注解),使用OpenFeign的注解
# contract: feign.Contract.Default
#读取资源超时时间
readTimeout: 6000
#建立连接超时时间
connectTimeout: 1000