news 2026/6/25 4:19:49

服务之间咋说话?OpenFeign远程调用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
服务之间咋说话?OpenFeign远程调用

一、先白话白话

昨天咱把user-serviceorder-service都登记到Nacos了,就像俩人都在社区服务中心登了记。但是光登记不中啊,得能互相找人互相帮忙

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

实际场景:

order-service(订单服务)想知道是哪个用户下单了,得问user-service(用户服务):

  • 以前:order-service得知道user-service住哪(IP:端口),自己写HTTP请求
  • 现在:order-service直接喊一声“user-service!”,Nacos负责找地址,OpenFeign负责传话

OpenFeign就是个翻译官+跑腿的

  1. 你写个接口,说想调user-service的某个方法
  2. OpenFeign帮你生成具体实现
  3. 帮你找到user-service在哪
  4. 帮你发请求、收响应
  5. 出问题了还帮你重试

二、为啥不用原生的RestTemplate?

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

RestTemplate也能调用,但是:

// RestTemplate方式(老式写法)Stringurl="http://localhost:8081/user/"+userId;Useruser=restTemplate.getForObject(url,User.class);

问题

  1. 得自己拼URL,麻烦!
  2. 得自己处理异常,麻烦!
  3. 负载均衡得自己写,麻烦!
  4. 改个地址得到处找,麻烦!

OpenFeign写法:

// Feign方式(新式写法)Useruser=userClient.getUserById(userId);

优点

  1. 跟调本地方法一样简单
  2. 自动负载均衡
  3. 自动重试
  4. 配置统一管理

三、开整!让order-service调user-service

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

准备工作

1. 先完善user-service

user-service里加个正经接口:

// User.java(先简单点,明天连数据库)publicclassUser{privateIntegerid;privateStringname;privateStringaddress;privateStringfavoriteFood;// 构造方法、getter、setter省略...}// UserController.java@RestController@RequestMapping("/user")publicclassUserController{// 模拟数据库privateMap<Integer,User>userMap=newHashMap<>();publicUserController(){// 初始化几个用户userMap.put(1,newUser(1,"张三","郑州","烩面"));userMap.put(2,newUser(2,"李四","洛阳","水席"));userMap.put(3,newUser(3,"王五","开封","灌汤包"));}@GetMapping("/{id}")publicUsergetUserById(@PathVariableIntegerid){Useruser=userMap.get(id);if(user==null){thrownewRuntimeException("用户不存在!");}returnuser;}@GetMapping("/test")publicStringtest(){return"user-service正常工作中...";}}

启动user-service,访问http://localhost:8081/user/1看看:

{"id":1,"name":"张三","address":"郑州","favoriteFood":"烩面"}

中了!

步骤1:给order-service加OpenFeign依赖

order-servicepom.xml里加:

<!-- 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:启动类加注解

@SpringBootApplication@EnableDiscoveryClient@EnableFeignClients// 这个注解是重点!开启FeignpublicclassOrderServiceApplication{publicstaticvoidmain(String[]args){SpringApplication.run(OrderServiceApplication.class,args);}}

步骤3:创建Feign客户端接口

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

新建feign包,里面创建UserClient.java

@FeignClient(name="user-service")// 指定要调用的服务名publicinterfaceUserClient{/** * 调用user-service的GET /user/{id}接口 * 跟写本地Controller一样,只是注解变@GetMapping */@GetMapping("/user/{id}")UsergetUserById(@PathVariable("id")Integerid);/** * 调用user-service的GET /user/test接口 */@GetMapping("/user/test")Stringtest();}

注意

  1. @FeignClient(name = "user-service")里的name必须跟Nacos里注册的服务名一致
  2. 方法上的注解(@GetMapping)要跟被调用方一致
  3. 方法签名(参数、返回值)也要一致

步骤4:写个Controller测试

order-service里:

@RestController@RequestMapping("/order")publicclassOrderController{@AutowiredprivateUserClientuserClient;// 注入Feign客户端/** * 根据订单ID获取订单信息,顺便获取用户信息 */@GetMapping("/{orderId}")publicMap<String,Object>getOrderWithUser(@PathVariableIntegerorderId){Map<String,Object>result=newHashMap<>();// 1. 模拟订单信息result.put("orderId",orderId);result.put("orderName","河南特产大礼包");result.put("status","已发货");result.put("address","河南省郑州市金水区");// 2. 调用user-service获取用户信息(关键!)// 假设订单1对应用户1,订单2对应用户2...IntegeruserId=orderId;try{Useruser=userClient.getUserById(userId);result.put("user",user);}catch(Exceptione){result.put("user","获取用户信息失败:"+e.getMessage());}returnresult;}/** * 测试user-service是否正常 */@GetMapping("/test/user")publicStringtestUserService(){returnuserClient.test();}}

步骤5:测试一下

  1. 启动所有服务:

    • Nacos(8848端口)
    • user-service(8081端口)
    • order-service(8082端口)
  2. 访问http://localhost:8082/order/test/user
    应该返回:user-service正常工作中...

  3. 访问http://localhost:8082/order/1
    应该返回:

{"orderId":1,"orderName":"河南特产大礼包","status":"已发货","address":"河南省郑州市金水区","user":{"id":1,"name":"张三","address":"郑州","favoriteFood":"烩面"}}

得劲!order-service成功调用了user-service!

四、Feign高级配置(稍微了解一下)

1. 超时配置(默认等1秒,太短)

order-serviceapplication.yml里:

feign:client:config:default:# 全局配置connect-timeout:5000# 连接超时5秒read-timeout:5000# 读取超时5秒user-service:# 针对user-service的配置connect-timeout:3000read-timeout:3000# 或者用ribbon(Feign底层用ribbon)ribbon:ConnectTimeout:5000ReadTimeout:5000

2. 开启日志(调试时用)

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

logging:level:com.example.order.feign.UserClient:DEBUG# 你的Feign客户端包名

在配置类里:

@ConfigurationpublicclassFeignConfig{@BeanpublicLogger.LevelfeignLoggerLevel(){returnLogger.Level.FULL;// 详细日志}}

日志会显示:

[UserClient#getUserById] ---> GET http://user-service/user/1 HTTP/1.1 [UserClient#getUserById] <--- HTTP/1.1 200 OK (15ms)

3. 失败重试

spring:cloud:loadbalancer:retry:enabled:true# 开启重试

五、负载均衡(Load Balancing)

啥是负载均衡?

假设user-service有3个实例:

  • 实例1:8081端口
  • 实例2:8083端口
  • 实例3:8084端口

OpenFeign会自动把请求均匀分配给这三个实例,不会让一个实例累死。

测试负载均衡

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

  1. 启动多个user-service实例:

    • 改端口号启动就行
    • IDEA里复制配置,改server.port
    • 启动8081、8083、8084三个实例
  2. 在Nacos里能看到3个实例

  3. 多次访问http://localhost:8082/order/test/user

    • 看每个实例的控制台日志
    • 请求会被均匀分配

得劲!不用改代码,自动负载均衡!

六、实际开发中的最佳实践

1. 统一返回结果

// 通用的返回类publicclassResult<T>{privateIntegercode;privateStringmessage;privateTdata;// ...}// Feign客户端返回Result@FeignClient(name="user-service")publicinterfaceUserClient{@GetMapping("/user/{id}")Result<User>getUserById(@PathVariableIntegerid);}

2. 统一异常处理

// 创建Fallback类(服务降级)@ComponentpublicclassUserClientFallbackimplementsUserClient{@OverridepublicUsergetUserById(Integerid){// user-service挂了,返回兜底数据returnnewUser(id,"默认用户","河南","胡辣汤");}@OverridepublicStringtest(){return"user-service暂时不可用";}}// Feign客户端指定Fallback@FeignClient(name="user-service",fallback=UserClientFallback.class)publicinterfaceUserClient{// ...}

3. 放在公共模块

把Feign客户端接口放到一个公共模块,谁想用谁引用。

七、今儿个总结

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

学会了啥?

  1. ✅ OpenFeign是干啥的(翻译官+跑腿的)
  2. ✅ 创建Feign客户端接口(@FeignClient
  3. ✅ 调用远程服务(跟调本地方法一样)
  4. ✅ 配置超时、日志
  5. ✅ 负载均衡(自动的!)

关键点

  1. 服务名要对@FeignClient(name = "user-service")里的name必须跟Nacos里一样
  2. 注解要一致:方法上的注解要跟被调用方一致
  3. 依赖要全:OpenFeign + LoadBalancer
  4. 启动类要加注解@EnableFeignClients

八、常见问题

1. 报错:UnknownHostException: user-service

  • 检查Nacos里user-service注册上了没
  • 检查@FeignClient的name写对没
  • 检查order-service连上Nacos没

2. 报错:Connection refused

  • 检查user-service启动了没
  • 检查端口号对不
  • 等一会儿再试(服务刚启动可能需要时间)

3. 调用返回null

  • 检查返回值类型对不
  • 检查被调用方接口路径对不
  • 开日志看看具体请求和响应

4. 超时问题

  • 默认1秒太短,调大点
  • 网络不好也会超时

九、明儿个学啥?

零基础全栈开发Java微服务版本实战-后端-前端-运维-实战企业级三个实战项目

资源获取:关注公众号: 小坏说Java ,获取本文所有示例代码、配置模板及导出工具。

明天咱学服务熔断降级

  • user-service挂了咋办?
  • order-service一直等,等到天荒地老?
  • Sentinel做熔断降级
  • 跟电路保险丝一样,过载就跳闸!

明天咱让服务更坚强,一个挂了不影响别的!🚀

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/20 12:36:59

三月七小助手:崩坏星穹铁道自动化辅助工具终极指南

三月七小助手&#xff1a;崩坏星穹铁道自动化辅助工具终极指南 【免费下载链接】March7thAssistant &#x1f389; 崩坏&#xff1a;星穹铁道全自动 Honkai Star Rail &#x1f389; 项目地址: https://gitcode.com/gh_mirrors/ma/March7thAssistant 你是否曾经因为重复…

作者头像 李华
网站建设 2026/6/13 0:14:21

三月七小助手:解放双手的星穹铁道自动化神器

还在为《崩坏&#xff1a;星穹铁道》的重复刷本感到厌倦吗&#xff1f;三月七小助手这款完全免费的开源工具&#xff0c;通过智能图像识别技术&#xff0c;让你彻底告别繁琐的手动操作。无论你是时间紧张的上班族还是追求效率的资深玩家&#xff0c;这款工具都能在五分钟内帮你…

作者头像 李华
网站建设 2026/6/22 15:43:01

探索无限音乐[特殊字符]——Nuclear播放器

Nuclear&#xff1a;一款免费的音乐流媒体播放器 什么是Nuclear&#xff1f; Nuclear是一款专注于从各种免费音乐源流媒体播放音乐的程序。它利用互联网中的免费内容&#xff0c;旨在为用户提供丰富的音乐体验。如果你曾经使用过mps-youtube&#xff0c;那你会发现Nuclear是一…

作者头像 李华
网站建设 2026/6/23 19:10:45

深蓝词库转换:彻底告别输入法数据迁移困扰的终极解决方案

你是否曾经因为更换输入法而不得不放弃多年积累的个人词库&#xff1f;是否因为不同平台间的词库无法同步而感到困扰&#xff1f;深蓝词库转换工具正是为这些痛点而生的完美解决方案。这款开源免费的程序专门处理各类输入法之间的词库转换问题&#xff0c;让您的输入体验实现无…

作者头像 李华
网站建设 2026/6/21 8:58:39

PCL2-CE社区版:5大核心功能打造完美Minecraft启动体验

PCL2-CE社区版&#xff1a;5大核心功能打造完美Minecraft启动体验 【免费下载链接】PCL2-CE PCL2 社区版&#xff0c;可体验上游暂未合并的功能 项目地址: https://gitcode.com/gh_mirrors/pc/PCL2-CE 还在为Minecraft启动器的各种限制而烦恼吗&#xff1f;PCL2-CE社区版…

作者头像 李华