Skip to content

Skynet 对比

Shield 参考 Skynet 的服务模型,但目标不是复制 Skynet,也不是扩展成通用分布式框架。

完整运行时语义见 运行时语义决策稿

相同点

  • 服务是基本运行单元。
  • Lua 承载主要业务逻辑。
  • send 表示异步消息。
  • call 表示请求-响应。
  • 定时器和轻量服务生命周期是核心能力。

不同点

维度SkynetShield 重构目标
运行时语言C + LuaC++20 + Lua
Actor 基础自研CAF 内部实现
用户 APIskynet.*shield.*
配置Lua 配置YAML 声明式配置
平台以 Unix-like 为主Windows / macOS / Linux
当前范围单进程 + 集群能力单节点优先,集群作为官方可选模块

API 映射

lua
-- Skynet
skynet.send(address, "lua", msg_type, ...)
local response = skynet.call(address, "lua", msg_type, ...)

-- Shield target
shield.send("service_name", method, data)
local ok, response = shield.call_timeout(timeout_ms, "service_name", method, data)
lua
-- Skynet
skynet.timeout(100, function() ... end)

-- Shield target
shield.timer_once(100, function() ... end)

CAF 与 Skynet 语义的关系

Shield 的目标不是重新实现 Skynet 的底层 actor runtime,而是用 CAF 承接机制层,再补齐 Skynet-like 服务语义。

层级SkynetCAFShield 决策
actor 调度Skynet 自研CAF scheduler使用 CAF
actor/messageSkynet service/messageCAF actor/message使用 CAF,隐藏 handle
async sendskynet.sendsend / anon_send封装成 shield.send
sync callskynet.call + Lua coroutine yieldrequest + continuation封装成 coroutine-aware shield.call
timerskynet.timeoutschedule / delayed send封装成 shield.timer_once / shield.timer
service namehandle/name serviceactor handle / registry 机制Shield 自己维护 service registry
Lua serviceLua script serviceCAF 不负责 Luashield_lua 实现
remote actorharbor/clustermiddleman publish/connect不进 core,归入 shield_cluster

ID 与集群地址差异

Skynet 的 actor address 可以采用高位 cluster/harbor id、低位本地 handle 的紧凑模型。Shield 保留这个思想,但不把 bit layout 作为 public ServiceId 契约。

Shield 决策:

cpp
using ServiceId = uint64_t; // 本地 service id
using NodeId = uint32_t;    // 节点 id

struct ServiceAddress {
  NodeId node;
  ServiceId id;
};

不同节点允许出现相同的本地 ServiceId,全局路由身份由 {node_id, node_epoch, service_id} 确定。这样可以避免 public API 被固定 bit layout 绑死,也能处理节点重启后的旧消息误投递问题。

关键差异

CAF 覆盖的是机制,不覆盖 Skynet 的 Lua 服务体验。

最关键的差异是 call

text
Skynet call:
  发送请求 → session 绑定当前 Lua coroutine → yield → response 到达 → resume

CAF request:
  发送请求 → continuation / await / receive → C++ actor 处理 response

Shield call:
  使用 CAF request 机制
  但对 Lua 暴露 Skynet-like coroutine 挂起语义

因此 shield.call 不能直接暴露 CAF request,也不能在 Lua 里做线程阻塞式等待。正确设计是挂起当前 Lua coroutine,同时保持 actor runtime 可继续调度其他消息。

Shield 不覆盖

  • Skynet harbor 集群模型不直接进入 core;多节点能力归入 shield_cluster
  • snax 框架。
  • sharedata / stm 等共享数据机制。
  • 内置服务发现框架。
  • Prometheus / health check / plugin system 作为 core。

当前重构优先把单节点服务、消息、网络、Lua API 做薄做稳,再在 shield_cluster 中补多节点能力。

参考

Apache License 2.0