微服务治理-服务调用

微服务拆分之后,服务之间不再是进程内方法调用,而是通过网络进行通信。服务调用(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 怎么选择调用方式?

场景推荐
对外 APIHTTP 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 RESTgRPC
数据格式JSONProtobuf
协议HTTP/1.1 或 HTTP/2HTTP/2
性能较低较高
可读性一般
浏览器支持一般
企业内部常用更常用

三、最佳实践

1. 内部服务不要写死 IP

始终通过服务发现获取目标实例。

2. 统一封装 Client

不要在业务代码中到处调用 Http::get(),而是封装成 UserClient、OrderClient 等客户端。

3. 设置超时

所有网络调用都必须设置合理的超时时间,避免请求无限等待。

4. 配合重试与熔断

网络调用可能失败,应结合前面学习的:

  • Retry(重试)
  • Timeout(超时)
  • Circuit Breaker(熔断)

提高系统稳定性。