skynet.call 潜在问题

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

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

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

没有超时机制

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

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 死循环代码

skynet服务的本质与缺陷

原文 2015-11-03 22:45:17 发表于 CSDN,这里对以前写的文章做下收录。

skynet是为多人在线游戏打造的轻量级服务端框架,使用c+lua实现。使用这套框架的一个好处就是,基本只需要lua,很少用到c做开发,一定程度上提高了开发效率。但skynet文档也相对较少,所以这里利用一点时间学习和总结skynet相关内容,文章这里就讲解下skynet服务的本质与缺陷,希望能有所帮助。

skynet服务的本质

或许我们对skynet服务有着太多的疑问:

skynet服务究竟是什么,为什么有人说服务是一个lua虚拟机,服务与服务之间的通讯是怎样的,为什么服务的内存高居不下, 为什么拿skynet服务和erlang进程做比较?等等。。。而这一切的答案都在代码里面,让我们一步一步解开她的面纱。

继续阅读skynet服务的本质与缺陷

skynet 热更新 lua 代码

原文 2016-12-30 16:18:15 发表于 CSDN,这里对以前写的文章做下收录。

skynet开发太多数情况下只是写lua代码,很少用写c,这一定程度上提高了项目的开发效率。lua虽然没有C高效,但开发复杂业务却是非常便捷,而且lua支持热更。skynet有两种方法热更新lua代码,clearcache和inject,文章分别对这两种方法做说明。

继续阅读skynet 热更新 lua 代码