news 2026/4/16 21:26:54

skynet源码学习-clusteragent.lua

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
skynet源码学习-clusteragent.lua

skynet源码学习-clusteragent.lua

  • 一、文件概述
  • 二、模块依赖和初始化
    • 2.1 模块引入
    • 2.2 启动参数处理
  • 三、全局变量和状态管理
    • 3.1 large_request - 大请求分片缓存
    • 3.2 inquery_name - 名称查询等待队列
    • 3.3 register_name_mt - 名称缓存元表
    • 3.4 new_register_name 函数
    • 3.5 tracetag 变量
  • 四、核心请求分发函数
    • 4.1 函数名和参数
    • 4.2 初始处理
    • 4.3 分片请求处理
    • 4.4 请求类型处理
    • 4.5 响应打包和发送
  • 五、协议注册和服务初始化
    • 5.1 注册客户端协议
    • 5.2 转发网关数据
    • 5.3 Lua 消息处理
  • 六、关键设计原理
    • 6.1 连接模型
    • 6.2 分片处理机制
    • 6.3 名称服务设计
    • 6.4 跟踪系统集成
    • 6.5 错误处理策略
  • 七、性能优化设计
    • 7.1 零拷贝优化
    • 7.2 批量写入
    • 7.3 并发控制
    • 7.4 缓存策略
  • 八、与其他模块的交互
    • 8.1 与 clusterd 的关系
    • 8.2 与 gate 的关系
    • 8.3 与 clustersender 的关系
    • 8.4 与本地服务的关系
  • 九、使用场景和示例
    • 9.1 正常请求流程
    • 9.2 名称查询流程
    • 9.3 大消息处理流程
  • 十、限制和注意事项
    • 10.1 连接限制
    • 10.2 内存管理
    • 10.3 性能考虑

这是 Skynet 集群模块中的入站连接处理器,负责处理来自其他节点的连接请求,并将请求转发给本地服务。是 Skynet集群能够实现高性能、可靠的跨节点通信的关键组件之一

一、文件概述

clusteragent.lua 是 Skynet 集群模块中的入站连接处理器,它:

  1. 处理来自其他节点的连接请求
  2. 解析集群协议并转发给本地服务
  3. 管理服务名称查询和缓存
  4. 处理大消息分片和重组
  5. 支持跟踪(trace)功能传递

核心角色

  • 服务器端处理器:与 clustersender(客户端)对应
  • 协议解码器:解析集群协议格式
  • 本地服务路由器:将请求路由到正确的本地服务
  • 名称服务缓存:缓存远程节点查询的名称

服务启动参数

localclusterd,gate,fd=...clusterd=tonumber(clusterd)gate=tonumber(gate)fd=tonumber(fd)
  • clusterd: 集群核心服务地址
  • gate: 网关服务地址(接收网络连接)
  • fd: 连接文件描述符(网络套接字)

二、模块依赖和初始化

localskynet=require"skynet"localsocket=require"skynet.socket"localcluster=require"skynet.cluster.core"localignoreret=skynet.ignoreretlocalclusterd,gate,fd=...clusterd=tonumber(clusterd)gate=tonumber(gate)fd=tonumber(fd)

详细解析

2.1 模块引入

  1. skynet: Skynet 核心库
  2. skynet.socket: Socket 操作模块
  • 提供 socket.write, socket.lwrite 等函数
  1. skynet.cluster.core: 集群核心协议模块
  • 提供 cluster.unpackrequest, cluster.packresponse 等函数
  1. skynet.ignoreret: 特殊函数
  • 作用: 忽略返回值,避免自动回复
  • 在特定场景下使用(如 session 是 fd 时)

2.2 启动参数处理

clusterd=tonumber(clusterd)gate=tonumber(gate)fd=tonumber(fd)
  • 类型转换: 所有参数都是字符串,需要转换为数字
  • 参数来源: 由 clusterd 服务在创建代理时传入
  • 典型调用:
-- 在 clusterd.lua 的 socket 处理中localagent=skynet.newservice("clusteragent",skynet.self(),-- clusterdsource,-- gatefd-- 连接文件描述符)

三、全局变量和状态管理

locallarge_request={}localinquery_name={}localregister_namelocalregister_name_mt={__index=function(self,name)localwaitco=inquery_name[name]ifwaitcothenlocalco=coroutine.running()table.insert(waitco,co)skynet.wait(co)returnrawget(register_name,name)elsewaitco={}inquery_name[name]=waitcolocaladdr=skynet.call(clusterd,"lua","queryname",name:sub(2))-- name must be '@xxxx'ifaddrthenregister_name[name]=addrendinquery_name[name]=nilfor_,coinipairs(waitco)doskynet.wakeup(co)endreturnaddrendend}localfunctionnew_register_name()register_name=setmetatable({},register_name_mt)endnew_register_name()localtracetag

详细解析

3.1 large_request - 大请求分片缓存

locallarge_request={}
  • 结构: {session = 分片请求表}
  • 作用: 存储正在接收的分片请求,直到所有分片到达
  • 键: 请求的会话ID(session)
  • 值: 分片请求表,包含:
{addr=目标地址,is_push=是否推送,tracetag=跟踪标签,-- 分片数据通过 cluster.append 添加}

3.2 inquery_name - 名称查询等待队列

localinquery_name={}
  • 结构: {名称 = 等待协程数组}
  • 作用: 管理并发的名称查询,避免重复查询
  • 场景: 多个请求同时查询同一个名称时
  • 设计思想: 第一个查询进行实际查询,后续查询等待结果

3.3 register_name_mt - 名称缓存元表

这是一个关键设计,实现了名称查询的延迟加载和并发控制。

元表定义

localregister_name_mt={__index=function(self,name)-- 查询逻辑end}

查询函数详细解析

第1步:检查是否已有查询在进行

localwaitco=inquery_name[name]ifwaitcothenlocalco=coroutine.running()table.insert(waitco,co)skynet.wait(co)returnrawget(register_name,name)end

场景:已有其他协程正在查询同一名称

  1. 获取等待队列: local waitco = inquery_name[name]
  2. 加入队列: table.insert(waitco, co)
  • co: 当前协程
  1. 挂起等待: skynet.wait(co)
  • 等待查询完成
  1. 返回结果: return rawget(register_name, name)
  • 直接获取缓存结果
  • 注意: 使用 rawget 避免再次触发元表

第2步:开始新的查询

waitco={}inquery_name[name]=waitcolocaladdr=skynet.call(clusterd,"lua","queryname",name:sub(2))-- name must be '@xxxx'ifaddrthenregister_name[name]=addrendinquery_name[name]=nilfor_,coinipairs(waitco)doskynet.wakeup(co)endreturnaddr

详细流程:

  1. 创建等待队列: waitco = {}
  2. 标记为查询中: inquery_name[name] = waitco
  3. 发起实际查询:
localaddr=skynet.call(clusterd,"lua","queryname",name
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 9:24:37

AI物理技术加速半导体TCAD仿真

使用AI物理技术进行技术计算机辅助设计仿真 技术计算机辅助设计仿真,涵盖工艺仿真与器件仿真,是现代半导体制造的关键环节。它们实现了“虚拟制造”,使工程师能够在投入昂贵的物理制造流程之前,以数字化方式设计、构建和测试晶体管…

作者头像 李华
网站建设 2026/4/16 10:53:24

前端导入Word文档并保留图文混排的插件

企业级文档处理解决方案 作为贵州IT行业软件公司的.NET工程师,针对贵司在后台管理系统中增加Word粘贴和文档导入的需求,我提供以下专业解决方案,完全满足贵司的技术栈和预算要求。 技术架构设计 系统架构图 [客户端] ←HTTPS→ [Web层] ←…

作者头像 李华
网站建设 2026/4/16 10:53:46

文件管理自动化:.bat 脚本使用指南

您是否也曾被混乱的桌面和难以整理的文件所困扰?这篇文章的核心思想是,我们不必再进行繁琐的手动整理,而是可以通过创建简单的 .bat 自动化脚本,将文件管理变成一条高效的流水线,把脑力从重复的“数字体力活”中解放出…

作者头像 李华
网站建设 2026/4/16 11:00:08

IO模拟I2C

soft_i2c_io.h #pragma once #include <cstdint> class SoftI2cIo { public:virtual ~SoftI2cIo() default;virtual void init() 0; // GPIO初始化/* SCL */virtual void scl_low() 0; // 拉低virtual void scl_release() 0; // 释放&#xff08;输入/…

作者头像 李华
网站建设 2026/4/16 18:08:25

被锁死的想象力:当AI成了科研本身,人类只能是观众

别盯着AI写的烂文案了&#xff01;千亿级投入超越曼哈顿计划&#xff0c;科研速度抛弃人类带宽&#xff0c;一场「里氏10.0级」的震荡已在眼前。这不仅是工具的升级&#xff0c;更是文明断裂的开始。欢迎来到&#xff0c;人类即将无法认知的时代。我们对未来的想象力&#xff0…

作者头像 李华
网站建设 2026/4/16 12:45:47

短视频运营者智能获客全开源SAAS系统源码详解,轻松创建和管理子账户

温馨提示&#xff1a;文末有资源获取方式在数字化营销时代&#xff0c;拥有一套自主可控、功能全面的短视频运营系统&#xff0c;意味着掌握了流量获取与转化的主动权。今天介绍一款专为高效运营与商业变现而生的全开源智能系统源码&#xff0c;它将复杂操作简单化&#xff0c;…

作者头像 李华