Actor 模型怎么并发
Actor 模型把并发单元从线程换成 Actor:每个 Actor 拥有私有状态和自己的邮箱,消息按到达顺序串行处理,Actor 之间只通过异步消息交互。由于状态不共享,模型层面消除了数据竞争,并发控制收敛到消息顺序上。故障处理靠监督树:父 Actor 按策略决定重启、停止还是上报子 Actor 的失败,从而把故障限制在局部。
基本信息
| 核心约束 | 状态不共享,消息异步传递,单 Actor 内串行处理 |
|---|---|
| 故障处理 | 监督策略:重启、停止、上报 |
| 实现 | Akka、Erlang/OTP、Orleans 等 |
| 邮箱语义 | 多数实现保证至少一次投递,跨节点不保证顺序,业务侧需幂等 |
典型使用场景
- 高并发有状态服务:会话、设备连接与在线状态管理
- 实时计算:事件流按实体分发到对应 Actor 串行处理
- 电信与游戏后端:单实体高并发、低延迟且需局部故障隔离
- 消息驱动的网关:把协议解析与业务处理拆成不同 Actor 层级
- 长生命周期状态:Actor 常驻内存并在故障后由监督者重建
消息处理示意(伪代码)
消息处理示意(伪代码)
actor Counter {
state n = 0 // 私有状态
on Inc(delta) { n += delta; reply n }
on Snapshot() { save(n) }
}
// 消息按到达顺序处理;跨 Actor 只发消息,不直接读其状态与其他并发模型对照
| 模型 | 并发控制手段 | 主要风险 |
|---|---|---|
| Actor | 消息顺序 + 监督树 | 邮箱积压、消息协议不兼容 |
| 共享内存加锁 | 互斥锁与原子操作 | 死锁、竞态、锁粒度难调 |
| CSP/通道 | 通道传递数据,协程阻塞等待 | 通道阻塞与泄漏 |
| 事件循环 | 单线程串行 + 回调 | 阻塞调用拖垮整个循环 |
使用要点
- Actor 内部不要阻塞等待外部调用,否则邮箱迅速积压;改为异步消息加未来的回复路径
- 消息协议要带版本,升级期间新旧 Actor 可能同时存在
- 监督策略要分层设计:不同重要级别的 Actor 走不同的重启与升级策略
- 按实体键路由消息,保证同一实体的处理落在同一个 Actor 上以维持顺序
Actor 模型把并发控制收敛到消息顺序上,避免了共享内存锁,但需要设计好消息协议与监督层级,这两件事的工作量常被低估。
跨节点消息通常只保证至少一次投递:重复消息、乱序与丢失都要在业务侧用幂等与对账兜底,不要假设传输层会替你保证。