当前位置: 首页 > news >正文

微服务间的远程接口调用:OpenFeign 的使用

前言:OpenFeign 能做什么?

OpenFeign是一种声明式、模板化的 HTTP 客户端。在 Spring Cloud 中使用 OpenFeign ,可以做到使用 HTTP 请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问 HTTP 请求。

其用法就是编写一个接口,在接口上添加注解。如此就能轻而易举的调用远程服务。

有如此强大的东西,我们肯定不能放过使用的机会,就像有时你有特殊的要求必须拉别的女孩的手,而此时有个中间人能帮你实现这个愿望,你拉别的女孩子的手就像拉自己女朋友的手一样方便!

OpenFeign在微服务中的作用就像中间方一样,当你需要调用另一个微服务的接口时,使用OpenFeign就像调用本服务的接口一样丝滑。

操练:欲善其事,先利其器

本章代码仓库:https://github.com/iweidujiang/spring-cloud-alibaba-lab

示例模块:07-open-feign,包含feign-provideropen-feign-service

既然是远程调用,那肯定至少得有 2 个微服务。本章在07-open-feign下新建open-feign-service子模块,调用同目录feign-provider(注册到 Nacos 的服务名为nacos-provider)。

open-feign-service引入spring-cloud-starter-loadbalancerspring-cloud-starter-openfeign两个依赖:

<parent><groupId>io.github.iweidujiang</groupId><artifactId>07-open-feign</artifactId><version>1.0.0</version></parent><artifactId>open-feign-service</artifactId><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency></dependencies>

07-open-feign/pom.xml子模块定义:

<modules><module>feign-provider</module><module>open-feign-service</module></modules>

如何在open-feign-service服务中调用nacos-provider服务的接口呢?前面第 2 章nacos-consumer使用了LoadBalancerRestTemplate进行调用,现在我们在open-feign-service使用OpenFeign来进行调用。

创建 FeignClient 接口

要将 Feign 引入到到项目中:

1.首先需要在启动类上添加@EnableFeignClients注解:

packageio.github.iweidujiang.lab07.consumer;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.client.discovery.EnableDiscoveryClient;importorg.springframework.cloud.openfeign.EnableFeignClients;/** * OpenFeign 服务消费者启动类。 * * @author 苏渡苇 */@SpringBootApplication@EnableDiscoveryClient@EnableFeignClientspublicclassOpenFeignServiceApplication{/** * 应用入口。 * * @param args 启动参数 */publicstaticvoidmain(String[]args){SpringApplication.run(OpenFeignServiceApplication.class,args);}}

2.创建一个 Feign 客户端接口,添加@FeignClient注解(无需再加@Service):

packageio.github.iweidujiang.lab07.consumer.client;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;/** * 远程调用 nacos-provider 服务的 Feign 客户端。 * * @author 苏渡苇 */@FeignClient(name="nacos-provider")publicinterfaceProductService{/** * 调用远程服务 nacos-provider 的 /product/{id} 接口。 * * @param id 商品 ID * @return 商品信息 */@GetMapping("/product/{id}")StringgetProductById(@PathVariable("id")Longid);}

关于FeignClient注解,需要知道:

  • name: 是一个任意的客户端名称,用于创 Spring Cloud LoadBalancer 客户端;
  • url:url一般用于调试,可以手动指定@FeignClient调用的地址;
  • configuration:Feigin 配置类,可自定义 Feign 的 Encode,Decode,LogLevel,Contract;
  • fallback:定义容错的类,当远程调用的接口失败或者超时的时候,会调用对应接口的容错逻辑,fallback 执行的类必须实现@FeignClient标记的接口;
  • fallbackFactory:工厂类,用于生成 fallback 类实例,通过此属性可以实现每个接口通用的容错逻辑,以达到减少重复的代码;
  • path:定义当前 FeignClient 的统一前缀。

本案例只是用name属性指定调用的服务名称,容错属性后续可与 Sentinel 整合再说。

3.控制层通过FeignClient远程调用

packageio.github.iweidujiang.lab07.consumer.controller;importio.github.iweidujiang.lab07.consumer.client.ProductService;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;importorg.springframework.web.bind.annotation.RestController;/** * OpenFeign 调用测试接口。 * * @author 苏渡苇 */@RestControllerpublicclassProductController{privatefinalProductServiceproductService;publicProductController(ProductServiceproductService){this.productService=productService;}/** * 通过 OpenFeign 远程查询商品。 * * @param id 商品 ID * @return 远程调用结果 */@GetMapping("/product/{id}")publicStringgetProduct(@PathVariable("id")Longid){returnproductService.getProductById(id);}}

控制层引入被@FeignClient标记的接口ProductService,直接调用getProductById方法即可远程调用nacos-provider/product/{id}。远程服务feign-provider的处理逻辑如下:

packageio.github.iweidujiang.lab07.provider.controller;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.Map;importjava.util.concurrent.TimeUnit;/** * 商品查询接口,供 OpenFeign 远程调用。 * * @author 苏渡苇 */@RestControllerpublicclassProductController{privatestaticfinalMap<Long,String>PRODUCT_MAP=newHashMap<>();static{PRODUCT_MAP.put(1L,"香飘飘奶茶");PRODUCT_MAP.put(2L,"雀巢咖啡");PRODUCT_MAP.put(3L,"百事可乐");}@Value("${server.port}")privateStringserverPort;/** * 根据 ID 查询商品。 * * @param id 商品 ID * @param delaySeconds 模拟慢调用延迟秒数 * @return 商品信息 */@GetMapping("/product/{id}")publicStringgetProduct(@PathVariableLongid,@RequestParam(value="delay",defaultValue="0")intdelaySeconds){if(delaySeconds>0){try{TimeUnit.SECONDS.sleep(delaySeconds);}catch(InterruptedExceptione){Thread.currentThread().interrupt();}}returnserverPort+":"+PRODUCT_MAP.getOrDefault(id,"未知商品");}}

验证

直接访问本服务:http://localhost:6061/product/3 ,可以看到调用了远程服务nacos-provider的接口:

从结果看,还实现了访问服务的负载均衡!

优化:事无巨细,极致体验

日志

OpenFeign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解OpenFeign中 Http 请求的细节。
通过设置日志,可以对 Feign 接口的调用情况进行监控和输出。

OpenFeign的日志级别主要有以下几种:

  • NONE:默认的,不显示任何日志;

  • BASIC:仅记录请求方法、URL、响应状态码及执行时间;

  • HEADERS:除了 BASIC 中定义的信息之外,还有请求和响应的头信息;

  • FULL:除了 HEADERS 中定义的信息之外,还有请求和响应的正文及元数据。

使用步骤:

1.设置 Feign Logger Level(FeignConfig配置类):

packageio.github.iweidujiang.lab07.consumer.config;importfeign.Logger;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/** * OpenFeign 全局配置。 * * @author 苏渡苇 */@ConfigurationpublicclassFeignConfig{/** * 开启 Feign 详细日志。 * * @return Feign 日志级别 */@BeanLogger.LevelfeignLoggerLevel(){returnLogger.Level.FULL;}}

2.在配置文件中给指定的 FeignClient 接口加指定的日志级别

logging:level:io.github.iweidujiang.lab07.consumer.client.ProductService:debug

使用效果:

请求的详细情况就以日志的形式打印出来了。

关于超时时间

spring-cloud-starter-openfeign支持spring-cloud-starter-loadbalancer。我们在项目中已经添加了spring-cloud-starter-loadbalancer依赖:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

这样在@FeignClient注解中,当设定了name = "nacos-provider"客户端名称后,便默认使用了Spring Cloud LoadBalancer进行负载均衡访问nacos-provider,在老版本中,集成的是Ribbon,它默认的响应时间是 1 s,可以通过ribbon.ReadTimeoutribbon.ConnectTimeout来设置客户端超时时间。

Spring Cloud Loadbalancer 默认没有超时时间的限制。

但是我们依然可以在默认客户端(default)和命名客户端上(注解 FeignClient 设置的 name,比如本demo中的 nacos-provider)配置超时。

OpenFeign 使用两个超时参数:

  • connectTimeout防止由于服务器处理时间长而阻塞调用者。
  • readTimeout从连接建立时开始,在返回响应时间过长时触发。

具体设置方式:

feign:client:config:# 默认的超时时间设置default:connectTimeout:5000readTimeout:5000# 在指定的 FeignClient 设置超时时间,覆盖默认的设置nacos-provider:connectTimeout:1000readTimeout:1000loggerLevel:full

假如设置nacos-provider的超时时间为 1s,可通过请求参数delay=3模拟慢调用超时:

curl"http://localhost:6061/product/1?delay=3"

或在feign-provider中直接访问:

curl"http://localhost:8080/product/1?delay=3"

调用效果:

本系列文章代码仓库:https://github.com/iweidujiang/spring-cloud-alibaba-lab


以上就是本文的全部内容了,本次导航结束。

先赞后看,养成习惯。

举手之劳,赞有余香。


本文创作于 2022-08-18 。

代码仓库已更新:https://github.com/iweidujiang/spring-cloud-alibaba-lab

http://www.jsqmd.com/news/908369/

相关文章:

  • GAMP程序太老了?手把手教你修改源码,让北斗三号PPP定位精度起飞
  • 华硕笔记本终极优化指南:5个G-Helper核心功能让电脑重获新生
  • 量化投资基石:10大机器学习股票数据集选型与实战指南
  • ESPI协议详解:单线、双线、四线模式怎么选?服务器BMC带外管理实战
  • 鸿蒙数学 108 篇 第二十八篇:计数体系完整推演
  • ArcSWAT建模新手避坑指南:你的土壤参数SOL_AWC算对了吗?从SPAW计算到模型验证
  • 别再瞎猜了!用SystemView透视你的FreeRTOS任务调度,解决实际卡顿问题
  • 2026年|知网AIGC查重原理与降AI实用技巧 - 降AI实验室
  • 3分钟快速上手:手机号码定位工具location-to-phone-number完全指南
  • 2025-2026年一起装修网电话查询。装修前请核实资质与合同条款 - 品牌推荐
  • 告别MPU6050磁干扰漂移:手把手教你用STM32CubeMX HAL库驱动IM948陀螺仪(附完整源码)
  • 别再只调sklearn的KMeans了!手把手教你用NumPy从零实现K-means聚类(附鸢尾花数据集实战代码)
  • 告别Cloud Sync!用Docker版aliyundrive-webdav为群晖打造更稳定的阿里云盘备份方案
  • 从零搭建自动化天文台:圆顶同步、PLC控制与远程观测实践
  • RoboTron-Sim:自动驾驶长尾场景模拟数据解决方案
  • 低预算先跑测试:投流公司常用小步快跑打法
  • JavaScript中Emoji长度计算的陷阱与精准解决方案
  • FineReport连接TDengine 3.x踩坑实录:驱动版本、时区问题与客户端安装的终极解决方案
  • 别再死磕Q-learning了!用Sarsa算法搞定你的第一个强化学习智能体(附Python代码)
  • 2025-2026年北京京云律师事务所电话查询:委托前请核实资质与合同条款 - 品牌推荐
  • MATLAB配电网状态估计算法包:最小二乘+解耦双模型,改参数就能跑不同拓扑
  • 如何用tcc-g15实现戴尔G15散热控制的终极开源替代方案
  • 别再瞎调了!用IxChariot测工业网关吞吐量,这5个坑我帮你踩过了
  • Hermes Agent框架连接Taotoken自定义模型提供商详细步骤
  • Django+OpenCV人脸采集与比对Web系统(含数据库、媒体资源和完整迁移文件)
  • 2026专业的杭州酒店花园设计施工公司口碑排行榜 - 品牌排行榜
  • 2025-2026年北京恒瑞宏晟机电设备有限公司电话查询:联系前建议先核实业务范围 - 品牌推荐
  • DownKyi终极指南:3步掌握B站视频下载,打造个人媒体库
  • 2025-2026年维克顿数字能源电话查询:使用前请核实资质与产品适配性 - 品牌推荐
  • 2026年杭州住家月嫂服务公司性价比排名 - myqiye