【基于skyent的热更思考】

基于skyent的热更思考

  • skynet-inject热更原理
  • 关键源码分析
  • 热更方式
  • 拓扑图
  • 注意事项

skynet-inject热更原理

inject是一个用于动态加载 Lua 代码文件并执行其中定义的函数的功能。可以在运行时动态加载 Lua 代码文件,然后调用其中定义的函数,通过修改模块及其函数的upvalue,实现代码的动态注入和执行。热更实现的大概思路:通过向指定服务注入cmd实现热更
参考wiki https://blog.codingnow.com/2016/11/lua_update.html

关键源码分析

-- debug_console.lua

local function adjust_address(address)
    local prefix = address:sub(1,1)
    if prefix == '.' then
        return assert(skynet.localname(address), "Not a valid name")
    elseif prefix ~= ':' then
        address = assert(tonumber("0x" .. address), "Need an address") | (skynet.harbor(skynet.self()) << 24)
    end
    return address
end


function COMMAND.inject(address, filename, ...)
    address = adjust_address(address)
    local f = io.open(filename, "rb")
    if not f then
        return "Can't open " .. filename
    end
    local source = f:read "*a"
    f:close()
    local ok, output = skynet.call(address, "debug", "RUN", source, filename, ...)
    if ok == false then
        error(output)
    end
    return output
end

adjust_address: 用于调整传入的地址参数,对传入的地址参数进行转换,以保证将热更脚本注入到正确的服务地址
io.open(filename, “rb”): 以二进制只读的方式读取文件内容
source: 存放读取到的热更脚本内容
skynet.call(address, “debug”, “RUN”, …): 通过skynet的debug消息类型,将读取的热更脚本内容注入到目标服务地址(debug.RUN内部实现)

-- skynet.debug.lua

function dbgcmd.RUN(source, filename, ...)
    local inject = require "skynet.inject"
    local args = table.pack(...)
    local ok, output = inject(skynet, source, filename, args, export.dispatch, skynet.register_protocol)
    collectgarbage "collect"
    skynet.ret(skynet.pack(ok, table.concat(output, "\n")))
end
-- skynet.inject.lua

return function(skynet, source, filename, args, ...)
    if filename then
        filename = "@" .. filename
    else
        filename = "=(load)"
    end
    local output = {}

    local function print(...)
        local value = { ... }
        for k,v in ipairs(value) do
            value[k] = tostring(v)
        end
        table.insert(output, table.concat(value, "\t"))
    end
    local u = {}
    local unique = {}
    local funcs = { ... }
    for k, func in ipairs(funcs) do
        getupvaluetable(u, func, unique)
    end
    local p = {}
    local proto = u.proto
    if proto then
        for k,v in pairs(proto) do
            local name, dispatch = v.name, v.dispatch
            if name and dispatch and not p[name] then
                local pp = {}
                p[name] = pp
                getupvaluetable(pp, dispatch, unique)
            end
        end
    end
    local env = setmetatable( { print = print , _U = u, _P = p}, { __index = _ENV })
    local func, err = load(source, filename, "bt", env)
    if not func then
        return false, { err }
    end
    local ok, err = skynet.pcall(func, table.unpack(args, 1, args.n))
    if not ok then
        table.insert(output, err)
        return false, output
    end

    return true, output
end

这两段核心代码实现了一个动态加载和执行 Lua 代码的功能,通过构建环境表、加载代码并执行,最终返回执行结果。这个函数是实现动态注入功能的关键部分,能够实现在 Skynet 框架中动态加载并执行 Lua代码,完成注入热更脚本

热更方式

  1. 可以直接在debug控制台通过调用inject将指定代码注入到指定地址实现,但对于同类型的服务需要手动依次执行,效率较低
  2. 可通过实现sh脚本获取到指定服务地址(例如hotfix服),然后在框架中的hotfix服内实现对框架类型服务的热更lua脚本
  3. 实现sh脚本,用于启动debug控制台,执行热更逻辑
  4. 添加hotcfg,用于配置需要热更的服务与要执行lua脚本路径,并定义lua脚本
  5. 根据框架架构(单点 or 集群),在hotfix服务中实现获取指定服务组的addr
  6. 通过配置的hotcfg实现将lua热更脚本依次注入到目标服务中

拓扑图

方案1:
在这里插入图片描述

方案2:
在这里插入图片描述

注意事项

  1. 要注意新代码与原有代码的兼容性,避免因为接口变更或依赖关系导致运行时错误
  2. 要注意避免对全局环境造成非预期的影响,尽量将修改限制在局部代码范围内
  3. 需要加入足够的异常处理机制,以在热更新过程中出现异常情况时能够及时捕获并处理,以保证系统的稳定性
  4. 在进行热更新前最好制定好回滚策略,以便在更新失败时能够及时恢复到原有的稳定状态
  5. 尽量避免热更新过程对系统性能造成过大影响,可以在适当的时机进行优化,减少更新对系统性能的影响
  6. 在进行热更新时建议增加详细的日志记录和监控机制,以便随时监测更新过程中的各种信息并进行分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/481682.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【小米汽车SU7实测】 小米汽车su7到底行不行?小米新能源轿车体验感怎么样?

小米汽车SU7是小米汽车的首款车型&#xff0c;定位“C级高性能生态科技轿车”&#xff0c;也是小米迈入新能源赛道的首次成果落地。 首先&#xff0c;让我们来谈谈它的性能。试驾过程中&#xff0c;小米SU7展现出了惊人的加速能力&#xff0c;0-100km/h加速仅需2.78秒&#xf…

射频前端架构之Phase8简介

Phase8系列方案有三种&#xff0c;分别是Phase8、Phase8M、Phase8M。 Phase8与Phase8M方案采用的是低频及中高频两颗L-PAMiD构成完成方案&#xff0c;目标是高端及旗舰手机&#xff0c;方案强调强大的射频能力&#xff0c;以及完整的CA、EN-DC支持&#xff0c;当然这两个方案的…

C++读取文本文件中的汉字出现乱码的原因及解决措施

大家好&#xff01; 作者今天在写代码时遇到了读取文本文件中的汉字时出现乱码的情况&#xff0c;所以本文介绍Windows操作系统中&#xff0c;C读取文本文件中的汉字出现乱码情况原因及解决措施。 下面代码可以读取Stu.txt中的内容并输出&#xff1a; ifstream ifs; ifs.open(…

Python编程—Ajax数据爬取

Python编程—Ajax数据爬取 ​ 在浏览器中可以看到正常显示的页面数据&#xff0c;而使用requests得到的结果中并没有这些数据。这是因为requests获取的都是原始HTML文档&#xff0c;而浏览器中的页面是JavaScript处理数据后生成的结果&#xff0c;这些数据有多种来源&#xff…

模糊PID模糊化(三角隶属度函数SCL代码)

模糊PID系列文章大家可以查看PID专栏,这里我们再次对模糊化进行细分,为大家呈现不同的程序写法。 1、模糊控制模糊PID学习笔记 https://rxxw-control.blog.csdn.net/article/details/124380674https://rxxw-control.blog.csdn.net/article/details/1243806742、模糊PID(三角…

25.8 MySQL 数据处理之增删改

1. 数据完整性问题 数据完整性问题: 数据的插入, 更新, 删除等操作都需要满足数据库表的完整性约束条件, 否则这些操作将会失败. 完整性约束在数据库设计中起到了至关重要的作用, 它们确保了数据库中数据的准确性和一致性.约束条件的全称通常被称为完整性约束条件(Integrity Co…

物理查询优化(二):两表连接算法(附具体案例及代码分析)

前言 关系代数的一项重要操作是连接运算&#xff0c;多个表连接是建立在两表之间连接的基础上的。研究两表连接的方式&#xff0c;对连接效率的提高有着直接的影响。 连接方式是一个什么样的概念&#xff0c;或者说我们为何要有而且有好几种&#xff0c;对于不太了解数据库的人…

Sentry(Android)源码解析

本文字数&#xff1a;16030字 预计阅读时间&#xff1a;40分钟 01 前言 Sentry是一个日志记录、错误上报、性能监控的开源框架&#xff0c;支持众多平台&#xff1a; 其使用方式在本文不进行说明了&#xff0c;大家可参照官方文档&#xff1a;https://docs.sentry.io/platforms…

2000-2022年上市公司客户、供应商集中度数据

2000-2022年上市公司客户、供应商集中度数据 1、时间&#xff1a;2000-2022年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;年份、股票代码、股票简称、行业代码、省份、城市、省份代码、城市代码、上市状态、前五名客户产生的营业收入_亿元、占全年营业收入的比例…

告别写作瓶颈,AI写作软件为你开启新篇章

如今&#xff0c;文字的力量对于人们愈发凸显。然而&#xff0c;对许多人来说&#xff0c;写作却是一项困难而耗时的任务。从学生的论文到商务报告&#xff0c;从小说创作到文案&#xff0c;写作瓶颈常常成为人们面临的挑战。然而&#xff0c;随着人工智能技术的不断发展&#…

想来开视频号小店,你需要准备好这些内容!新手建议收藏!

大家好&#xff0c;我是电商小布。 视频号小店项目&#xff0c;作为当前在电商行业内推出时间最短的项目&#xff0c;内部发展潜力大&#xff0c;吸引到了很多小伙伴想要来入局其中。 而对于我们新手朋友来说&#xff0c;在开店的时候&#xff0c;不知道该准备哪些东西&#…

MySQL数据库-MySQL基础-下篇-函数、约束、多表查询、事务

文章目录 函数一、字符串函数练习 二、数值函数三、日期函数四、流程函数总结 约束概述约束演示外键约束概念语法删除/更新行为 总结 多表查询多表关系一对多&#xff08;多对一&#xff09;多对多一对一 多表查询概述内连接外连接自连接*联合查询-union, union all子查询标量子…

A股大变局:从“加速度”到“内在价值”

随着经济发展的变化&#xff0c;A股投资者认知正发生根本性转变&#xff0c;从追求“交易边际变化”到重新认知“内在价值”&#xff0c;“稳定价值类”资产配置价值上升。 广发证券在最新的报告中指出&#xff0c;市场过去偏爱企业“加速度”&#xff0c;但现在却更注重于企业…

分布式搜索引擎ES-RestClient查询文档快速入门

RestClient查询文档快速入门 文章目录 RestClient查询文档快速入门1.1、match_all1.2、全文检索查询1.3、精确查询1.4、复合查询-boolean query1.5、排序和分页1.6、高亮&#xff08;解析查询高亮结果&#xff09; 1.1、match_all package cn.mannor.hotel;import org.apache.…

C语言与sqlite3入门

c语言与sqlite3入门 1 sqlite3数据类型2 sqlite3指令3 sqlite3的sql语法3.1 创建表create3.2 删除表drop3.3 插入数据insert into3.4 查询select from3.5 where子句3.6 修改数据update3.7 删除数据delete3.8 排序Order By3.9 分组GROUP BY3.10 约束 4 c语言执行sqlite34.1 下载…

打造稳健测评体系:亚马逊测评的关键环节解析

亚马逊测评&#xff0c;简而言之&#xff0c;便是通过真实的购买体验&#xff0c;对产品进行的客观评价。这种评价不仅为卖家提供了产品优化的方向&#xff0c;更为消费者提供了决策的依据&#xff0c;使得产品得以在市场中脱颖而出。然而&#xff0c;现今许多卖家选择自主管理…

ideaSSM 财务凭证管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 idea 开发 SSM 财务凭证管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff…

LeetCode540 有序数组中的单一元素

Leetcod540 有序数组中的单一元素 1.题目描述 2.解题思路 同样是二分搜索&#xff0c;利用当i为偶数时候&#xff0c;数组中单独元素左侧的所有i位置与i1位置的数字相同&#xff0c;而单独元素右侧的所有i位置与i1位置元素不同的特性&#xff0c;来进行二分搜索 3.算法思路 …

Java多线程(进阶)

文章目录 目录 文章目录 前言 一 . 常见的锁策略 乐观锁 VS 悲观锁 读写锁 轻量级锁 VS 重量级锁 自旋锁 VS 挂起等待锁 公平锁 VS 非公平锁 可重入锁 VS 不可重入锁 二 . 死锁 死锁的三种典型情况 死锁产生的必要条件 死锁的解决办法 三 . CAS ABA问题 四. S…

Kubernetes(k8s)集群健康检查常用的五种指标

文章目录 1、节点健康指标2、Pod健康指标3、服务健康指标4、网络健康指标5、存储健康指标 1、节点健康指标 节点状态&#xff1a;检查节点是否处于Ready状态&#xff0c;以及是否存在任何异常状态。 资源利用率&#xff1a;监控节点的CPU、内存、磁盘等资源的使用情况&#xf…