1. 适用场景
适用于这类项目:
- 业务服务端基于
Skynet
- 项目里除了
framework/,还有自己的 lualib-src/、service-src/、根 Makefile
- 不是纯净官方工程,存在本地定制
本教程以本项目为例,目标是把框架升级到:
2. 升级原则
做这类升级,核心原则只有 3 条:
- 以官方新版本为主干
- 本地定制逐项合并回去
- 先跑通编译和启动,再处理运行期兼容
不要直接在旧代码上零散修补,也不要盲目整目录覆盖后不做对照。
3. 先搞清楚项目结构
这类项目通常有两套原生模块:
framework/lualib-src
lualib-src
这两个目录不要混。
本项目里真正要关注的目录是:
framework/
lualib-src/
service-src/
services/
- 根
Makefile
r.sh
run.sh
stop.sh
config_maker.lua
4. 升级前必须做的检查
先确认旧版本基线:
grep -n '^v' framework/HISTORY.md | head
grep -n 'LUA_VERSION_RELEASE' framework/3rd/lua/lua.h
再找本地定制点:
rg -n "profile_context|netpack.pop|TLS_MODULE|CIPHER_MODULE|lua-vscdebugaux|lcrc|lsha2" framework services lualib-src service-src Makefile
本项目升级前,真正高风险的点是:
framework/service-src/service_snlua.c
framework/Makefile
lualib-src/profile/profile.c
lualib-src/lua-netpack.c
services/login/server.lua
5. 准备官方源码
不要只下载压缩包,最好拉带子模块的官方代码:
git clone --depth 1 --branch v1.8.0 --recurse-submodules https://github.com/cloudwu/skynet skynet-v1.8.0
原因:
3rd/jemalloc 需要完整子模块
- 只拿压缩包时,
jemalloc 目录可能不完整
6. 正确的升级方式
第一步:备份关键本地文件
至少备份这些:
framework/Makefile
framework/platform.mk
framework/service-src/service_snlua.c
services/login/server.lua
lualib-src/profile/profile.c
config_maker.lua
r.sh
stop.sh
第二步:用官方新版本覆盖框架主干
直接覆盖这些目录和文件:
framework/skynet-src/
framework/service/
framework/service-src/
framework/lualib/
framework/lualib-src/
framework/3rd/lua/
framework/3rd/lpeg/
framework/3rd/lua-md5/
framework/3rd/jemalloc/
framework/HISTORY.md
framework/README.md
framework/LICENSE
不要动项目根目录自己的:
lualib-src/
service-src/
- 根
Makefile
7. 覆盖后必须合并回去的改动
7.1 framework/service-src/service_snlua.c
这类项目如果自定义了 lprofile,通常会依赖 snlua 的分配器 userdata 布局。
本项目必须保留:
void * profile_context;
并且要保证它仍然是 struct snlua 的第一个字段。
做法:
- 以官方
v1.8.0 的 service_snlua.c 为基准
- 保留本地
profile_context
- 保留官方
ATOM_INT trap、ATOM_LOAD、ATOM_INIT 等新逻辑
7.2 framework/Makefile
不要直接用官方版本,也不要直接保留旧版本。
正确做法:
- 用官方
v1.8.0 Makefile 做基础
- 再把本地扩展模块合并回去
本项目必须保留:
ltls
lcipher
pb
cjson
luarsa
textfilter
zlib
skiplist
lcrc.c
lsha2.c
lua-vscdebugaux.c
mkdir -p
client.so 的额外依赖
linux_nojemalloc
同时保留官方新增:
- jemalloc 构建链路
lpeg 的 lpcset.c
8. 业务兼容一定要查的点
8.1 自定义 netpack
如果项目自己有:
就一定要检查 netpack.pop(queue) 返回值有没有变化。
本项目自定义 netpack.pop(queue) 返回:
fd, id, sz, idx, msg
所以业务代码必须全部按 5 值处理。
本次实际修复文件:
services/login/server.lua
8.2 自定义 lprofile
如果项目有:
lualib-src/profile/profile.c
那它大概率依赖 Lua 内部结构。
本次从 Lua 5.4.2 升到 5.4.7 后,实际要改的是:
far->i_ci->func 改为 far->i_ci->func.p
这是运行期深兼容点,编译不过时优先查这里。
8.3 项目自己的 skynet.xxx 扩展函数
升级官方 framework/lualib/skynet.lua 后,要检查项目是否依赖自定义接口。
本项目实际缺的是:
skynet.loge
skynet.logw
skynet.logi
skynet.logd
做法很简单:
- 在
framework/lualib/skynet.lua 里补兼容层
- 底层仍然调用
skynet.error
9. Linux 上的标准验证流程
9.1 预检
先确认环境:
bash scripts/skynet_v180_preflight.sh
9.2 编译框架
cd framework
make cleanall
make linux
如果没有 autoconf,可用:
make linux_nojemalloc
9.3 编译项目自定义模块
cd ..
make
9.4 单进程启动
bash r.sh debug 8 Manager
先跑一个,再跑全量。
9.5 全量启动
./run.sh debug
9.6 进程确认
ps -ef | grep tlbb | grep -v grep
10. 日志和停服要一起适配
10.1 主日志路径
如果你要这种日志:
/home/ubuntu/log/Manager8
/home/ubuntu/log/Span4
/home/ubuntu/log/Game2
那就把:
logger = "../log/%s%d"
写进 config_maker.lua。
10.2 stop.sh 归档
如果原来的 stop.sh 只支持月目录归档,就要补平铺文件归档。
否则会看到:
No monthly log directories found under /home/ubuntu/log
正确做法:
- 保留月目录归档
- 新增
/home/ubuntu/log/Manager8 这类平铺日志文件归档
11. 本项目升级时实际踩到的问题
按出现顺序,真实问题如下:
jemalloc 依赖 autoconf
r.sh 过严导致正常场景误退出
config_maker.lua 里 VSCode 调试变量导致配置解析失败
lprofile 不兼容 Lua 5.4.7
- 项目业务依赖
skynet.loge/logi/logw/logd
- 停服脚本只识别月目录日志,不识别平铺主日志
所以经验是:
- 能启动,不代表能运行
- 能运行,不代表日志和停服可用
- 升级时要把“构建、启动、日志、停服”一起验证
12. 最后的验收标准
以下全部满足,才算升级完成:
make linux 成功
- 根目录
make 成功
run.sh debug 能拉起所有核心进程
ps -ef 能看到所有目标进程
- 主日志能正常写入
/home/ubuntu/log
stop.sh 能正常停服并归档日志
- 登录、进服、场景、DB、cluster 回归无异常
13. 最后一句经验
Skynet 升级最难的从来不是官方框架本身,而是你项目里“依赖框架内部实现”的那些本地定制。
先把这些定制点找全,再升级,效率最高。
|