分布式系统与中间件
一、中间件分类
| 类别 | 说明 | 典型产品 |
|---|---|---|
| 服务治理 | RPC 调用、限流熔断、链路追踪、分布式配置中心 | Dubbo、Spring Cloud(Nacos、Resilience4j、Micrometer Tracing) |
| 消息中间件 | 解耦、异步、削峰、分布式事务 | Kafka、RocketMQ、RabbitMQ |
| 存储中间件 | 缓存、消息队列等,涉及分布式时要求较高 | Redis、Memcached |
| 各种 Proxy | 数据库/缓存/存储的代理层,让应用透明使用集群 | MyCat、ShardingSphere、Twemproxy、Codis |
| 分布式协调 | 分布式锁、配置管理、服务注册发现 | ZooKeeper、etcd、Consul |
| 数据访问 | 数据拆分、扩容、迁移管理 | ShardingSphere、TDDL |
| 容器相关 | 容器编排与运行时 | Kubernetes、Docker |
Proxy 层的语言选择
Proxy 对性能要求高,Java 的长处(开发效率)在这里权重不大,通常会使用 Go、C++ 等性能更高的语言。
二、消息中间件
应用于解耦,在分布式环境下完成异步通信和事务协调。
分布式消息模型的核心需求
- 消息发送方和接收方都是集群
- 同一个消息的接收方可能有多个集群进行处理
- 不同集群对于同一消息的处理不能相互干扰
场景
用户下单后,订单服务发一条消息,库存集群消费它来扣库存,物流集群消费它来创建运单——两个集群各自独立处理,互不影响。
三大主流消息中间件对比
| Kafka | RocketMQ | RabbitMQ | |
|---|---|---|---|
| 出品方 | LinkedIn(2011 年开源) | 阿里/淘宝(后捐给 Apache) | Broadcom(原 Pivotal/VMware) |
| 开发语言 | Scala + Java | Java | Erlang |
| 协议 | 自定义协议 | 自定义协议 | AMQP(也支持 XMPP、SMTP、STOMP) |
| 消费模式 | Pull(消费者主动拉取) | Pull + 长轮询 | Push 为主 |
| 吞吐量 | 最高 | 高 | 中等 |
| 可靠性 | 0.8 版本开始支持复制,不支持事务,对消息重复、丢失、错误没有严格要求 | 定位于可靠消息传输,支持事务消息 | 对数据一致性、稳定性和可靠性要求最高 |
| 路由/负载均衡 | 简单 | 支持 | 很好的支持(Routing、Load Balance、数据持久化) |
| 适合场景 | 大数据量的日志收集、流处理、互联网服务数据采集 | 电商交易、金融等需要可靠传输的场景 | 企业系统内,对一致性和可靠性要求高的场景 |
性能排序
Kafka > RocketMQ > RabbitMQ
但性能不是唯一标准——RabbitMQ 的路由和可靠性最强,RocketMQ 在可靠性和性能之间取得平衡,Kafka 追求极致吞吐量但对消息严格性要求较低。
三、服务框架
远程调用和对象访问中间件,核心目的是对应用进行拆分,完成服务化。
单体应用 → 按业务拆分为多个服务 → 通过 RPC 框架远程调用
典型产品:Dubbo、gRPC、Spring Cloud OpenFeign
四、数据访问中间件
数据库减压三板斧
| 阶段 | 方式 |
|---|---|
| 1 | 优化应用(SQL 优化、索引、减少无效查询) |
| 2 | 引入缓存和搜索引擎(Redis 缓存热点数据,ES 处理复杂查询) |
| 3 | 数据和访问拆分(垂直拆分 / 水平拆分) |
分库分表后面临的问题
| 问题 | 解决思路 |
|---|---|
| 分布式事务 | 尽量避免;如果必须使用,考虑最终一致性,不要追求强一致 |
| 全局唯一 ID | 独立 ID 生成器(Snowflake 等),或把 ID 生成逻辑放入应用本身 |
| 跨库 Join | 把 Join 拆成多次数据库操作;对常用信息冗余形成单表查询;借助搜索引擎解决 |
| 外键约束 | 分库后要求每个单库的数据是内聚的(相关数据放同一个库) |
| 跨库查询 | 需要结果合并,尽量避免排序分页操作 |
五、分布式事务
为什么难?
分布式事务是指事务的参与者、服务器和资源分别位于不同节点上。
DTP 模型三组件
| 组件 | 全称 | 职责 |
|---|---|---|
| AP | Application Program | 应用程序,定义事务边界 |
| RM | Resource Manager | 资源管理器(如 DBMS),必须实现 XA 规范定义的接口 |
| TM | Transaction Manager | 事务管理器,协调和管理事务,控制全局事务生命周期 |
两阶段提交(2PC)
在提交之前增加了一个准备阶段:
阶段 1(Prepare):TM 询问所有 RM "你们准备好了吗?"
RM 执行事务但不提交,回复 Yes/No
阶段 2(Commit): 全部 Yes → TM 通知所有 RM 提交
任一 No → TM 通知所有 RM 回滚
CAP 理论
| 约束 | 含义 |
|---|---|
| Consistency | 一致性——所有节点看到的数据相同 |
| Availability | 可用性——每个请求都能得到响应 |
| Partition Tolerance | 分区容错——网络分区时系统仍能运作 |
CAP 定理
分布式系统中,C、A、P 三者最多只能同时满足两个。由于网络分区(P)在分布式环境中不可避免,实际上是在 CP(强一致,牺牲可用性) 和 AP(高可用,牺牲强一致) 之间选择。
Paxos
比两阶段提交更轻量的一致性协议,是很多分布式系统(ZooKeeper 的 ZAB、etcd 的 Raft 等)的理论基础。
工程实践建议
Tip
- 最好避免分布式事务
- 如果必须使用,考虑最终一致性方案(如消息队列 + 本地事务表),不要追求强一致
- Paxos/Raft 适合基础设施层面的一致性,业务层面更多用补偿事务、Saga 等模式