skynet框架:跨进程组播实现方案
存在业务场景,从单点进程(source)批量向集群内其他节点(target)推送消息,目标节点数量可能达三位数。
提供一个实现方案:
- target上开启进程内的组播服务,只负责当前节点的组播推送业务;服务支持接收其他节点的通知消息(目标服务只在所在节点内的组播服务上做订阅等操作,由该组播服务负责管理);
- source进程构造组播消息包,做一次循环将消息发送到所有目标节点(这里只是寻常的remote send,multicast消息类型不是必须的,最常用的lua消息类型足够使用);
- target上的组播服务将数据包pack成multicast消息类型转发到所有目标订阅服务;
一段代码说明下:
-- source service
for _, skynet_node in ipairs(get_target_nodes()) do
cluster.send(skynet_node, "multicastd", "lua", "remote_publish", channel, msg)
end
-- multicastd
local subscribes = {
-- channel = {
-- service,
-- ...
-- },
-- ...
}
local MULTICAST_CMD = {
publish = function(channel, msg)
for service in pairs(subscribes[channel]) do
skynet.send(service, "multicast", msg)
end
end,
subscribe = function(...)
...
end,
newchannel = function(...)
...
end,
...
}
local LUA_CMD = {
remote_publish = function(...)
local channel, msg = unpack(...)
MULTICAST_CMD.publish(channel, msg)
end
}
function init_service()
...
skynet.dispatch("lua", function(_, _, cmd, ...)
LUA_CMD[cmd](...)
end)
end
skynet.start(init_service)
-- target service
function init_service()
...
skynet.dispatch("multicast", function(...)
...
end)
end
skynet.start(init_service)
上述方案中multicastd服务核心只做一个事情:当收到组播通知时,将消息推送到订阅的所有服务中去。这个组播通知可以来自包括服务所在节点内的任何集群内节点,我们常常是把channel id跟某个业务玩法绑定,所有节点约定这个id,target service订阅这个channel后,关联的这个玩法(可能跑在当前或其他节点)有组播需求时,会通知到关心该消息的所有target service。
可以看出,方案并没有区分local channel和remote channel。这里发起组播请求的总是单点玩法节点,而multicastd服务只是作为目标节点,等待组播通知,这里通知消息使用的消息类型也并不是multicastd。我们的业务,广播的需求场景基本是从单点节点单向发出,所有目标节点作为接收方进行接收处理。
本文来自博客园,作者:linxx-,转载请注明原文链接:https://www.cnblogs.com/linxx-/p/18091089
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库