1) 【一句话结论】
采用业务能力边界驱动微服务拆分,通过服务注册中心实现服务发现,结合消息队列(异步)和gRPC(同步)实现服务间通信,并利用容器编排(如K8s)实现弹性伸缩,确保系统可扩展、高可用。
2) 【原理/概念讲解】
老师口吻解释关键概念:
- 微服务拆分原则:以“单一职责”和“业务能力边界”为依据,类比“公司部门”,每个服务聚焦一个业务能力(如订单服务只处理订单逻辑,不涉及交易或用户数据),便于独立开发、部署和扩展。
- 服务间通信:
- 同步通信:用gRPC(基于HTTP/2二进制协议),传输效率高,支持流式传输,适合强交互场景(如交易服务实时查询订单状态);
- 异步通信:用消息队列(如RabbitMQ/Kafka),解耦系统,适合事件驱动场景(如交易完成后通过队列通知用户服务更新记录)。
- 服务发现:通过服务注册中心(如Nacos),服务启动时注册自身地址,其他服务查询注册中心获取目标服务地址,避免硬编码依赖。
- 弹性伸缩:容器化部署(Docker),利用K8s根据负载(CPU/内存)自动扩缩容器实例(如订单服务CPU使用率超80%时自动增加实例),保证系统高可用。
3) 【对比与适用场景】
以**同步通信(REST vs gRPC)**为例的对比表:
| 对比项 | REST | gRPC |
|---|
| 定义 | 基于HTTP协议,资源操作(GET/POST等) | 基于HTTP/2,二进制协议,高效 |
| 特性 | 轻量,跨语言支持,但性能一般 | 传输效率高(二进制),支持流式传输,性能优 |
| 场景 | 对性能要求不高的场景(如API网关) | 对性能要求高的场景(如实时交易) |
| 注意点 | 需处理HTTP状态码,可能阻塞 | 需处理gRPC错误码,配置复杂 |
4) 【示例】
假设交易系统拆分为三个服务:
- 订单服务(处理订单创建、修改);
- 交易服务(处理交易执行,调用订单服务查询订单状态);
- 用户服务(处理用户信息,交易服务通过RabbitMQ异步通知用户服务更新交易记录)。
部署在K8s集群,服务注册到Nacos。交易服务调用订单服务用gRPC同步通信(实时响应),交易完成后通过RabbitMQ发送消息给用户服务(异步解耦)。K8s根据CPU负载自动扩缩容器实例(如订单服务负载高时增加实例)。
5) 【面试口播版答案】
(约80秒)
“面试官您好,针对上交所业务系统迁移至云原生,我的微服务拆分方案核心是基于业务能力边界,将系统拆分为订单、交易、用户等独立服务。首先,服务间通信采用同步(gRPC)和异步(消息队列)结合:比如交易服务调用订单服务查询订单状态用gRPC实时响应,交易完成后通过RabbitMQ发送交易结果给用户服务,解耦系统。服务发现通过Nacos实现,服务启动时注册地址,其他服务查询Nacos获取目标服务地址。弹性伸缩利用K8s,根据CPU负载自动扩缩容器实例(如订单服务负载高时自动增加实例),保证系统高可用。这样既能保证业务解耦,又能通过云原生技术实现弹性伸缩和高可用。”
6) 【追问清单】
- 问题:为什么选择按业务能力拆分,而非按模块拆分?
回答:按业务能力拆分符合“单一职责”原则,每个服务聚焦单一业务,便于独立开发、部署和扩展,避免模块间强耦合。
- 问题:如何保证服务间通信的可靠性?
回答:同步通信用gRPC的可靠传输,异步用消息队列的持久化存储,并设置重试机制,确保消息不丢失。
- 问题:数据一致性如何处理?
回答:采用最终一致性,交易服务更新订单状态后通过消息队列通知用户服务,用户服务异步消费更新,避免强一致性带来的性能问题。
- 问题:服务发现延迟如何解决?
回答:Nacos支持本地缓存,减少查询延迟,同时设置健康检查,剔除故障服务,避免服务雪崩。
7) 【常见坑/雷区】
- 拆分过细:服务数量过多导致管理复杂,难以维护。
- 通信方式选择不当:同步通信导致服务阻塞,影响系统性能。
- 服务发现机制不健壮:注册中心故障导致服务不可用。
- 弹性伸缩配置不合理:自动扩缩阈值设置不当,导致资源浪费或系统过载。
- 忽略数据一致性:强一致性要求导致系统性能下降。