背景
我们的后台框架支持两种语言:Lua和Go(rust有小伙伴在做了,开发中…)
目前业务主要使用Lua框架,但部分新业务使用Go框架。
配置表通过转表工具转换为Lua文件,由Lua框架读取,并支持热加载,因此,Go框架存在读取配置的问题。
最初在转表工具(Excel->Lua)转换后增加了一个流程,将Lua转换为JSON,Go框架读取JSON文件。
不过有些配置是由开发手工维护的,如果同时维护Lua和JSON两份配置,可能会存在漏改的问题。
如果都使用JSON,需要让Lua框架支持JSON文件的热加载。
一开始只有一个由Lua手工维护的配置表需要被Go框架读取,我们使用了让Go框架加载Lua配置的方案,使用ChatGPT生成读取Lua文本的代码,然而随着Lua配置的变更,解析变得更加复杂。
因此,我们考虑为Go引入Lua扩展,但仅用于配置的读取。
有几个常见的纯Go的Lua库,如:
- go-lua,支持Lua5.2,最后更新时间为2022年10月
- gopher-lua,支持Lua5.1,最后更新时间为2023年5月
使用这些库存在以下问题:
- Lua版本与我们的Lua版本不一致(Lua框架是5.3.4),可能存在兼容性问题
- 这些库具有一定的学习成本,而C版本我们非常熟悉
- 如果Go框架支持了Lua配置,策划配置也可以不再转为JSON,所以要在后台长时间运行,存在稳定性风险
最终,我们决定使用cgo,为其做了一层简单的封装,仅用于读取配置和执行简单的函数。
由于使用了cgo,我们约定了以下规范:
- 尽量减少cgo和Go调用栈的切换。对于高频函数中的多次c调用,使用c代码进行封装,以避免多次cgo调用。
- cgo代码只跑在一个协程中,防止线程泄露。
代码可以在cgo-lua中找到,同时也支持了我们一直使用的Lua模块方案,这方面可以参考lua小工具–>Import的lua版本中的介绍。