微服务治理-服务调用
微服务拆分之后,服务之间不再是进程内方法调用,而是通过网络进行通信。服务调用(Service Communication)就是研究不同服务之间如何安全、高效、可靠地进行数据交换。
一、介绍
1.1 为什么需要服务调用?
在单体架构中:只掉调用方法,比如 $user = $this->userService->getUser(1);
只是一次普通的方法调用(Method Call)。
没有网络、没有序列化、没有超时、没有连接
而微服务以后:
已经变成:HTTP、TCP、gRPC
所有调用都变成:网络通信(Network Communication)
1.2 微服务调用有哪些方式?
主要有三种:
1. HTTP REST
优点:
- 简单
- 通用
- 调试方便
缺点:
- JSON 较大
- 序列化效率较低
2. RPC
看起来像:本地方法。
实际上走的是网络。
3. gRPC
底层:
HTTP/2。
Protobuf。
速度:非常快。
1.3 怎么选择调用方式?
| 场景 | 推荐 |
|---|---|
| 对外 API | HTTP REST |
| 内部服务调用 | gRPC |
| 旧系统兼容 | HTTP |
| 高频通信 | gRPC |
即: 外部使用 HTTP。 内部使用 gRPC。
二、原理
2.1 一次 HTTP 调用发生了什么?
业务代码
│
▼
DNS / 服务发现
│
▼
TCP 建立连接
│
▼
发送 HTTP 请求
│
▼
User Service
│
▼
返回 JSON
如果没有连接池。
每一次都会:TCP 三次握手、发送、四次挥手
效率很低。
2.2 RPC 为什么快?
HTTP:
- 返回JSON,比较大
RPC:
- 可能只有十几字节。
- 序列化更快。
- 网络更省。
- CPU占用更低。
2.3 HTTP vs gRPC
| 对比项 | HTTP REST | gRPC |
|---|---|---|
| 数据格式 | JSON | Protobuf |
| 协议 | HTTP/1.1 或 HTTP/2 | HTTP/2 |
| 性能 | 较低 | 较高 |
| 可读性 | 高 | 一般 |
| 浏览器支持 | 好 | 一般 |
| 企业内部 | 常用 | 更常用 |
三、最佳实践
1. 内部服务不要写死 IP
始终通过服务发现获取目标实例。
2. 统一封装 Client
不要在业务代码中到处调用 Http::get(),而是封装成 UserClient、OrderClient 等客户端。
3. 设置超时
所有网络调用都必须设置合理的超时时间,避免请求无限等待。
4. 配合重试与熔断
网络调用可能失败,应结合前面学习的:
- Retry(重试)
- Timeout(超时)
- Circuit Breaker(熔断)
提高系统稳定性。