目录
[4.5 服务调用测试与问题排查 ------ 微服务开发中的真实调试](#4.5 服务调用测试与问题排查 —— 微服务开发中的真实调试)
[第1步:进入 Gateway](#第1步:进入 Gateway)
[第2步:Gateway找 blog-service](#第2步:Gateway找 blog-service)
[第3步:进入 blog-service](#第3步:进入 blog-service)
[第4步:Feign调用 user-service](#第4步:Feign调用 user-service)
[1. 看Nacos控制台](#1. 看Nacos控制台)
[四、第二类问题:Gateway 404](#四、第二类问题:Gateway 404)
[五、第三类问题:Feign 404](#五、第三类问题:Feign 404)
[1. 数据库慢](#1. 数据库慢)
[2. 服务阻塞](#2. 服务阻塞)
[3. Feign超时时间太短](#3. Feign超时时间太短)
Q2:Nacos显示服务存在,但是Feign调用失败怎么办?
[4.6 微服务项目整体复盘](#4.6 微服务项目整体复盘)
继续。
现在进入:
4.5 服务调用测试与问题排查 ------ 微服务开发中的真实调试
这一部分非常重要。
前面我们已经搭好了理论链路:
客户端
↓
Gateway
↓
blog-service
↓
Feign
↓
Nacos
↓
user-service
但是实际开发中,80%的时间不是写代码,而是在排查调用失败。
例如:
-
Feign调用失败
-
Nacos找不到服务
-
Gateway返回404
-
服务返回503
-
超时
-
注册了但是调用不到
这一节就是训练你的排错思维。
一、先建立完整调用链
假设请求:
GET /blog/detail/1
第1步:进入 Gateway
请求:
localhost:9000/blog/detail/1
Gateway匹配:
- id: blog-route
uri: lb://blog-service
predicates:
- Path=/blog/**
第2步:Gateway找 blog-service
Gateway问Nacos:
blog-service有哪些实例?
Nacos返回:
blog-service
192.168.1.20:8082
第3步:进入 blog-service
执行:
BlogController.detail()
第4步:Feign调用 user-service
代码:
userFeignClient.getUserById(userId);
第5步:Feign找服务
Feign:
我要调用 user-service
Nacos:
返回:
user-service
192.168.1.30:8081
第6步:
HTTP调用:
GET
192.168.1.30:8081/user/10001
任何一步失败:
都会报错。
二、第一类问题:Nacos没有服务实例
这是最常见。
例如:
Feign:
@FeignClient("user-service")
调用。
报错:
Load balancer does not contain an instance for the service user-service
意思:
负载均衡器:
没有找到实例。
排查步骤
1. 看Nacos控制台
进入:
localhost:8848/nacos
服务列表。
看:
user-service
有没有。
正常:
服务名 实例数量
user-service 1
blog-service 1
gateway-service 1
如果:
user-service 0
说明:
服务没有注册。
三、为什么服务没有注册?
原因1:没有开启服务发现
检查:
启动类。
需要:
@EnableDiscoveryClient
@SpringBootApplication
public class UserApplication {
}
原因2:缺少依赖
pom:
需要:
<dependency>
<groupId>
com.alibaba.cloud
</groupId>
<artifactId>
spring-cloud-starter-alibaba-nacos-discovery
</artifactId>
</dependency>
原因3:Nacos地址错误
例如:
配置:
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848
部署服务器后:
错误。
因为:
localhost不是Nacos服务器。
应该:
server-addr:
192.168.1.100:8848
四、第二类问题:Gateway 404
例如:
访问:
localhost:9000/blog/list
返回:
404 Not Found
排查:
第一步:看Route
访问:
/actuator/gateway/routes
你之前已经使用过。
检查:
有没有:
{
"id":"blog-route"
}
第二步:检查Path
配置:
predicates:
- Path=/blog/**
请求:
/blogs/list
不匹配。
所以404。
第三步:检查StripPrefix
例如:
Gateway:
收到:
/api/blog/list
配置:
filters:
- StripPrefix=1
发送:
/blog/list
如果服务Controller:
是:
@RequestMapping("/api/blog")
那么:
路径错。
这是非常常见的问题。
五、第三类问题:Feign 404
例如:
Feign调用:
userFeignClient.getUserById(1L)
结果:
404
说明:
服务找到了。
但是:
接口路径不存在。
例如:
Feign:
@GetMapping("/user/{id}")
UserDTO getUserById(
@PathVariable Long id
);
实际Controller:
@GetMapping("/users/{id}")
少了一个s。
结果:
404。
排查:
检查:
API接口
@GetMapping("/user/{id}")
服务实现
@GetMapping("/user/{id}")
必须一致。
六、第四类问题:Feign超时
错误:
Read timed out
含义:
请求发出去了。
但是:
服务迟迟没返回。
可能:
1. 数据库慢
例如:
SQL:
select *
from blog
where title like '%xxx%'
没有索引。
2. 服务阻塞
例如:
代码:
Thread.sleep(10000);
3. Feign超时时间太短
默认:
可能几秒。
修改:
spring:
cloud:
openfeign:
client:
config:
default:
connectTimeout:5000
readTimeout:5000
七、第五类问题:服务启动成功,但是调用失败
这个非常容易迷惑。
例如:
控制台:
Started UserApplication
但是:
调用:
失败。
为什么?
因为:
启动成功 ≠ 注册成功。
需要看:
Nacos。
完整状态:
应该:
Java启动成功
↓
连接Nacos
↓
注册实例
↓
Nacos显示服务
↓
才能调用
八、开启Feign日志
调试远程调用非常有用。
配置:
logging:
level:
com.xxx.feign:
DEBUG
然后:
看到:
Feign Request
GET /user/10001
Response:
200
九、微服务排错思维
以后遇到问题:
不要乱改。
按照链路排查:
第一步:入口
Gateway有没有收到?
看:
日志:
Gateway request /blog/list
第二步:路由
Gateway有没有转发?
检查:
Route。
第三步:服务发现
Nacos有没有实例?
第四步:业务服务
Controller有没有收到?
第五步:远程调用
Feign有没有发请求?
第六步:数据库
SQL是否正常。
形成:
请求
↓
Gateway
↓
服务发现
↓
服务调用
↓
业务逻辑
↓
数据库
逐层排查。
十、面试高频问题
Q1:Feign调用失败如何排查?
回答:
首先确认调用方服务是否正常启动,然后检查Nacos是否存在目标服务实例,再检查Feign接口路径和服务Controller映射是否一致,最后检查网络、超时以及业务异常。
Q2:Nacos显示服务存在,但是Feign调用失败怎么办?
回答:
检查:
-
服务实例IP是否正确
-
端口是否开放
-
健康状态
-
Controller路径
-
服务是否真正监听端口
Q3:Gateway返回404可能原因?
回答:
-
Route未匹配
-
Path配置错误
-
StripPrefix配置错误
-
下游接口不存在
十一、这一节的核心价值
你现在不是单纯学习:
Feign怎么写
而是在建立:
微服务故障定位能力
真实工作:
更多时候:
不是:
"怎么调用"。
而是:
"为什么调用失败"。
到这里,这个博客系统案例已经完成:
✅ 服务拆分
✅ common模块
✅ 用户服务
✅ 博客服务
✅ Gateway
✅ JWT认证
✅ Feign服务调用
✅ Nacos服务发现
✅ 调试排错
下一节建议进入:
4.6 微服务项目整体复盘
重点:
-
一次请求完整链路
-
各组件职责
-
项目架构图
-
面试如何介绍这个项目
-
如何回答"为什么这么设计"
这一部分非常适合你后面写简历项目描述。