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 控制台使用技巧

skynet.call 潜在问题

最近朋友问我,说到他们项目不使用 skynet.call,他不是很理解,问我为啥。

于是,我看了 skynet.call 的代码。实现上,skynet.call 是服务 A 给服务 B 发 request 消息,等服务 B 处理完,再给服务 A 发 response 消息,最后交由服务 A 处理。(源代码可以参考 skynet服务的本质与缺陷

通常,skynet.call 这个过程是没有问题的,但在服务 B 繁忙无法响应时,就可能有问题。

没有超时机制

skynet.call 没有超时机制,执行的过程不能中断,得一直等到目标服务处理完才返回,所以业务可能出现长时间中断。如果想实现超时,可以利用另外一个协程来唤醒自己。
继续阅读skynet.call 潜在问题

lua5.4 分代垃圾回收

前注

最近我看了 lua 5.4 分代垃圾回收的代码,网上很少讲到这块内容,于是,我写这篇文章分享一下,也当做总结。文章就以我看的 lua 5.4.4 做分析。

在进入今天的主题前,先回顾我之前写的 lua5.3 垃圾回收分析,重复的内容不再赘述。

lua 5.4 支持两种 gc 方式, 增量式 gc 和分代 gc ,默认是增量式,可以通过以下 api 切换。

切换成分代 gc:
collectgarbage "generational"
切换成增量式 gc:
collectgarbage "incremental"

提出问题

1. 增量式 gc 跟分代 gc 的对比?
2. 分代 gc 过程是怎样的?
3. 分代 gc 有哪些状态?
4. 分代 gc 怎么调优?

继续阅读lua5.4 分代垃圾回收

skynet 高内存占用问题

前段时间,在服务器的监控后台发现,在线人数上去后 skynet 进程内存成倍升高,占系统 40% ~ 50 %,但人数回落到 1/3 后,内存使用并没有明显减少,仍有 40 % 左右。

服务器、skynet相关版本信息如下:
linux version 4.18.0
skynet v1.1.0
lua 5.3.4
jemalloc 5.0.1-0

我在本地压测时,却没有发现这个情况。在线人数上去,内存也是一样增加,但人数下来后,内存也逐渐释放了。项目代码是一样的,唯一不同的是,本地压测使用的系统是 CentOS 7 (Linux version 3.10.0), 我换了 CentOS 8 (Linux version 4.18.0) 压测后,发现跟线上的问题一样。
继续阅读skynet 高内存占用问题

找到 lua 死循环代码

最近遇到 lua 死循环的情况,就研究下如何找到死循环所在的代码,方便定位和解决问题。

首先,要找到出问题的协程(lua_State)。lua vm 实现时,每个协程都有自己独立的堆栈(stack),以及函数栈(CallInfo)。

所以,要先找到死循环的协程,再从这个协程函数栈找到代码。

怎么找到这个协程?

有三种办法:
方法1、 在死循环会执行到的 opcode ,加代码取得当前协程;
方法2、 遍历所有 gc 数据对象,找到当前正在执行的协程;
方法3、 重写 coroutine.resume 及 wrap 函数,取得当前协程。
继续阅读找到 lua 死循环代码