System & Services 进阶 20m
认识 Swift 中的分布式 Actor
Meet distributed actors in Swift
2022年6月6日
一句话判断
Distributed Actors 把 Swift 的并发安全模型从单进程扩展到了多进程——Actor 隔离 + 位置透明性,让分布式系统的代码和本地代码一样安全。
这场 Session 讲了什么
Swift Actor 通过编译时检查防止数据竞争,但只限于同一进程内。Distributed Actors 将这个模型扩展到跨进程(多设备、集群、服务器)场景。
核心概念是”位置透明性”:无论 Distributed Actor 在本地还是远程,交互方式完全一样。这意味着你可以在本地测试完整的分布式逻辑,部署时不需要修改实现代码。
Session 用一个井字棋游戏(Tic Tac Fish)演示了从普通 Actor 迁移到 Distributed Actor 的过程。关键步骤包括:添加 distributed 关键字、指定 ActorSystem 类型、处理 ID 属性的自动生成、以及理解 distributed 方法的序列化要求。
Swift 5.7 引入了 Distributed 模块,包含 DistributedActor 协议和相关类型。目前提供了 LocalTestingDistributedActorSystem 用于本地开发和测试。
值得深挖的点
- 位置透明性的价值:同一个 Distributed Actor 可以在本地运行(测试),也可以在远程节点运行(生产)。调用方不需要知道也不需要关心。这大大简化了分布式系统的开发和测试。
- ActorSystem 的职责:ActorSystem 负责所有序列化和网络通信。你可以选择不同的实现(比如基于 gRPC 的系统)。Swift 提供了 LocalTesting 系统用于开发。
- Distributed 方法的限制:标有
distributed的方法参数和返回值必须可序列化(遵循 Codable)。编译器会检查这一点。非 distributed 方法不受此限制。 - ID 的自动管理:Distributed Actor 的 ID 由 ActorSystem 分配,全局唯一。不能手动定义 id 属性——编译器会报错。
代码片段
import Distributed
// 使用本地测试 Actor System
typealias DefaultDistributedActorSystem = LocalTestingDistributedActorSystem
// 将普通 Actor 转换为 Distributed Actor
distributed actor BotPlayer {
// 不需要手动定义 id,编译器自动生成
typealias ActorSystem = LocalTestingDistributedActorSystem
var moveCount: Int = 0
let team: Team
distributed func generateMove() -> GameMove {
moveCount += 1
return GameMove(
position: calculatePosition(),
emoji: team.emoji(for: moveCount)
)
}
distributed func opponentDidMove(_ move: GameMove) {
// 处理对手的移动
}
}
// 使用方式与普通 Actor 相同——无论本地还是远程
let bot = BotPlayer(system: actorSystem, team: .fish)
let move = try await bot.generateMove() // 远程调用看起来和本地一样
// 玩家 Actor 也可以是 Distributed 的
distributed actor HumanPlayer {
typealias ActorSystem = LocalTestingDistributedActorSystem
let team: Team
weak var gameModel: GameModel?
distributed func generateMove() -> GameMove {
// 等待人类玩家选择
}
}
最佳实践
- 先用 LocalTesting 系统开发和测试,确认逻辑正确后再接入真实的 ActorSystem
- 所有需要远程调用的方法标记
distributed,内部辅助方法不要标记 - Distributed Actor 的参数和返回值必须遵循 Codable
- ID 是全局唯一标识符,可以用于路由和查找 Actor
- 在同一进程内使用 Distributed Actor 的开销极低,不要因为担心性能而避免使用
还有什么值得关注
- “Protect mutable state with Swift actors”(WWDC 2021)是前置内容
- Swift Distributed Actors 是 Swift on Server 的关键技术
- ActorSystem 的具体实现可以基于不同的网络协议
- 这个功能目前是 Swift 5.7 的一部分,但标记为 experimental
- 社区已经有基于 gRPC 和其他协议的开源 ActorSystem 实现
WWDC 2022