skynet的服务间共享table的实现

     背景是这样的,我最近在监控哪些代码会比较消耗cpu,监控到场景服务启动没多久,一帧运行了2秒钟左右,我本能的觉得这里有问题,通过监控的信息,断定是在场景服务向战斗服务发送数据的时候,占用了过多的cpu时间,编译skynet的时候,没有注意警告,导致没有看到数据打包和解包的调试信息,这里多花了点时间进行分析和定位,经过对消息投递,调用函数时对元表__index函数的调用,数据的解包和打包的调试和分析,最终锁定在数据的打包和解包占用了过多的cpu时间,数据打包和解包的时候分别花了300ms左右,开了很多战斗服务。
      知道了是因为数据的打包和解包占用了过多的cpu时间,结合之前对lua虚拟机之间共享数据的实现机制的理解,以及我对lua源码的理解,我想另辟蹊径。我的想法是定义一个新的消息类型(lua、response分别是一种消息类型,每种类型有自己的打包和解包的方法),先将调用的函数和参数打包成一个table,设置这个table为只读(通过设置元表),发送消息的服务缓存这个table,并且这个table是缓存在注册表中(其实放在某个lua文件的table里也可以),然后将可查到这个table的lua_State的地址和查找前面table的索引打包,总共12字节,在解包的地方根据这12字节逆向操作,就能拿到要执行的函数和参数,执行完函数,把这个table的deleted设置为true,发送方每间隔1秒钟会检测有没有table的deleted为true,如果有,就赋值为nil,解除引用关系,lua的gc最终会释放内存。经历了打包发送服务的主线程(lua_State),新建一个协程,由数据发送服务方和数据接收服务方共同确定一个key,来新建一个独立的lua_State(要设置一个元表的__gc,在表被删除的时候,删除这里的lua_State),确定下来,用最后这种方案是安全可靠的,经过测试,这里的消耗小于1ms,我比较满意。
      这个小功能经过多轮迭代,中间也产生了很多思考,尤其是对接口的抽象和封装深有体会,如果已有的代码在一个服务向另一个服务发送消息时,有一个通用的接口,这里我只要改一下这个接口的实现,就能实现全部替换。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值