skynet项目内存使用优化

Skynet/Lua 凭借其轻量易用、灵活热更、Actor并发模型的特性被广泛应用于游戏开发等场景,但 Lua 动态内存管理机制也带来了内存占用过高的挑战。

本文结合我最近对一个 skynet 项目做的内存优化分析经验,做一下分享。

1、lua 内存使用优化

1.1. 减少 lua 函数调用层数

服务端收到协议后,要经过很多次函数调用才到真正的执行函数。以手头的项目举例,服务 A 函数负责接收协议数据,收到数据后,会将协议和参数传给 B 函数处理,B 函数根据定义找到对应的模块和方法,再由 C 函数排队(一个玩家一个队列)调用 D 目录下对应的模块和函数, D 目录的模块再 require 对应的目标模块,才调用到真正的执行函数 E。最后,E 函数还会调用其他模块来完成业务逻辑。

调用层数过深的问题是,lua 要为每个过程保留过程数据,如函数地址、参数等,也就是调用栈信息(CallInfo),也叫栈帧

建议:减少调用层级,可以使用注册回调机制
继续阅读skynet项目内存使用优化

skynet lua生成火焰图

最近在搞skynet生成火焰图, github 上刚好有解决方案 skynet_systemtap_set,但代码比较老旧,不支持新版的 skynet 及 lua5.4

生成火焰图的原理是,利用 systemtap 抓取 lua栈,分析函数代码的热路径。

所以,我在他的基础上,主要处理以下两个问题:
1. lua5.4 内部数据结构做了调整,取代码文件地址、代码行数也有改动。
2. skynet shareproto 结构调整

我修改完的代码也放在github分享,有兴趣的小伙伴可以围观 skynet_systemtap_set
继续阅读skynet lua生成火焰图

lua定位CPU100%问题

在开始这个话题前,说下我遇到的 skynet 进程 CPU100% 占用问题,查找 bug 的过程比较繁琐,后来想到做改进,这也是促成我写这篇文章的原因。

查到是一段 lua 代码有问题,这里截取其中出问题的代码:

-- 活动开始时间: 2033-01-01 00:00:00
local start_time = 1988121600

function start_activity()
    local now = os.time()
    local diff = now - start_time
    if diff < 0 then
        skynet.timeout((-diff)*100, start_activity)
        return
    end

    -- todo 省略活动内容
end

以上代码,通过 skynet.timeout 设置定时器,定时触发 start_activity , 看似没有问题,但是,当 skynet.timeout 第一个参数过大时,会有意想不到的收获。
继续阅读lua定位CPU100%问题

skynet 编译问题总结

原文 2015-09-23 23:48:54 发表于 CSDN,这里对以前写的文章做下收录。

skynet 下载编译过程对系统环境有很大依赖性,编译说明过于简单,没有提及到。所以,文章这里总结 skynet 比较常见的编译问题,希望有所帮助。

skynet 的编译过程:

git clone https://github.com/cloudwu/skynet.git
cd skynet
make linux

简单3步,对于很多高版本的系统来说,可能就这3步。但是,低版本系统可能无法编译,如下:
1. gcc 版本问题
2. 缺少 readline
3. 缺少 ncurses
4. 缺少 git (非必要项,则要手动下载skynet及3rd下的jemalloc)
5. 缺少 autoconf 等等
继续阅读skynet 编译问题总结

skynet 控制台使用技巧

原文 2016-01-07 01:14:27 发表于 CSDN,这里对以前写的文章做下收录。

skynet 自带了一个控制台服务,可以很方便获取和调试 skynet 运行数据,而且可以热更新代码,所以,弄明白 skynet 控制台管理可以让你更好地使用 skynet,甚至改进这个控制台服务,以满足不同业务需求。

这个服务默认不会启动,需要你手动启动它,如下:
skynet.newservice("debug_console", 8000)

设计原因,调试控制台只监听本地地址 127.0.0.1 ,如果需要远程使用,需要先登录到本机,然后再连接。

使用时,通过 telnet 或 nc 登录调试控制台,启动后显示:

$ nc 127.0.0.1 8000
Welcome to skynet console

表示连接成功。
继续阅读skynet 控制台使用技巧