共享配置数据

前言

由于skynet每个服务都是独立的lua虚拟机,一般游戏开发又需要加载大量的配置文件,如果每个服务都加载一遍,会造成过多的内存浪费,所有skynet就提供了sharedata,sharetable共享配置数据的手段。由于两种方案各有优缺点,所以我在封装实现上让使用者可以任选其一,在make/script增加热更配置命令,方便于热更配置。

优缺点对比

sharedata

  • 优点

    1. c内存占用低
    2. 热更后旧配置方便销毁
  • 缺点

    1. 对于访问配置中的每个table都会创建一个proxy对象,意味者访问者(一个服务)越多,内存占用越大
    2. 通过proxy访问c,访问稍慢

sharetable

  • 优点

    1. 访问配置,不会产生proxy代理对象,访问者内存占用低
    2. 相当于lua本地表访问,访问更快
  • 缺点

    1. 热更后,旧配置需要等所有引用到的服务退出才能销毁
    2. update热更方式性能稍差
    3. c内存占用更大

鉴于优缺点对比,我觉得使用者可以根据配置场景择优选择。
比如不经常更新的配置用sharetable,经常更新的用sharedata
table多的配置用sharetable, table少的用sharedata

具体实现

加载

通常配置文件会很多,开发中我们并不想手动指定哪个配置需要加载,所以我设计的加载指定文件夹下所有lua文件。

热更

通过记录文件修改时间,决定哪些文件需要更新,在script增加触发热更检查命令。

访问

通常对于配置访问,需要检查配置合理性建立访问索引

  • 配置合理性
    对于配置合理性,可以在配置导出阶级检查,也可以在程序运行时检查,我在设计上对于运行时检查做了少量支持。

  • 建立访问索引
    我们需要建立map,maplist索引。

  • map
    比如以道具ID为key的索引。

  • maplist
    比如某个道具类型的所有道具配置。

使用例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
local sharedata = require "skynet-fly.sharedata"

local function testsharedata()
sharedata.load({
'./common/cfgs'
}, sharedata.enum.sharedata)

local cfg2 = sharedata:new("./common/cfgs/test_cfg2.lua", sharedata.enum.sharedata):builder()
local data_table = cfg2:get_data_table()

local sub_table = data_table[1]

log.info("wait update 10s >>> ")
skynet.sleep(1000) --等待去更新配置

log.info("old", data_table) --会更新到
log.info("subold", sub_table) --会更新到
log.info("new", cfg2:get_data_table()) --会更新到
end

local function testsharetable()
sharedata.load({
'./common/cfgs'
}, sharedata.enum.sharetable)
local cfg2 = sharedata:new("./common/cfgs/test_cfg2.lua", sharedata.enum.sharetable):builder()
local data_table = cfg2:get_data_table()

local sub_table = data_table[1]

log.info("wait update 10s >>> ")
skynet.sleep(1000) --等待去更新配置

log.info("old", data_table) --更新不到
log.info("subold", sub_table) --更新不到
log.info("new", cfg2:get_data_table()) --更新到
end

加载配置

sharedata.load(dir_list, mode) 我们通常在main.lua启动文件中加载即可。

访问配置

sharedata:new(file_path, mode) 在对于需要访问配置的地方创建即可。

使用注意点

sharedata和sharetable访问对象的区别,由于sharetable使用update更新的方式性能稍差,所以我用的是query更新的方式。
所以sharetable被外部引用的配置table,不会被更新好。

建议

所以我建议在使用上,每次想拿取最新配置,请通过访问对象去拿取。

API


共享配置数据
https://huahua132.github.io/2024/09/14/skynet_fly_word/word_3/Q_sharedata/
作者
huahua132
发布于
2024年9月14日
许可协议