不同服务器之间的数据同步(skynet 和 c++)

不同服务器之间的数据同步(skynet 和 c++),第1张

最近公司开发了一个捕鱼游戏,现在想要把这个项目嵌入到公司已有的游戏中,成为其子游戏,开发捕鱼的服务器框架是基于 skynet 的框架(独立一套系统)。而已有的游戏服务器框架是c++自研框架(也是独立的一套系统),所以需要解决一个问题:就是两个系统中数据共享的问题,因为用户都是现有游戏中的。捕鱼并没有用户,用户从主游戏中进入到捕鱼势必要把 ta 的金币、钻石、道具等数据带到捕鱼服务器,最终用户退出捕鱼游戏,要把用户现在的金币和其他数据移动回去,这里就涉及到数据共享和维护数据唯一性的问题了。

最初的方案是选择 http 请求通知的方式进行通信。但是考虑到极端情况: 如高并发,如果一秒钟发起 2W 次请求那么以 http 的处理方式就是要 每秒建立tcp链接和断开链接 * 2W次,文件描述符占用、和不能便捷集成到两个系统业务层中、以及网络异常处理需要依赖到DB保存数据待后续恢复、以及后续的集群部署需要再做考虑,等等这些缺点都是无法忍受的。

后面考虑用 redis 的 Pub/Sub 来实现高效的 MQ 并且在请求发起的时候如果超时,如果数据是必须被对方接收的话,还可以直接把数据写入缓存,让对端自行获取。遂和其他 xxMQ 进行对比,最后不管从易用性、通用性、高可用等等方面上都是 redis 胜出,当然 redis 的 Pub/Sub 也是有缺点的,但是使用到上述的这个应用场景来说,都是可以忽略的。

数据一致性保证机制

如果发起端请求对端超时 会将请求的数据写入到缓存,其格式如下:

保存到 redis 中的类型:set

key: 捕鱼缩写(f) + "_" + 用户uid

value: "请求的命令 "+" @ " + [ k + "|" + value [ k + "|" + value ...] ]

实例 key = f_10001 value = req_mv_gold@gold=10000|session=1

含义为:捕鱼发起的请求(f) 用户uid(10001) 命令(req_mv_gold)和携带数据用 "@" 分割,数据中字段与字段用 "|" 进行分割。数据解析,按对应命令协议定义结构进行解析。

1.用户登录了捕鱼,进入捕鱼游戏,用户向斗地主发起请求 req_mv_gold 数据中 gold 字段值为 0,斗地主就把用户的金币先保存到临时变量,然后置空用户的金币,再把用户金币通过 rsp_mv_gold 发送给捕鱼,如果 rsp_mv_gold 没有收到响应,斗地主要把钱加回给用户,意味这一次转移金币失败

2.假如用户已经成功完成了上面的步骤,此时用户在斗地主中的金币值为 0,在捕鱼中的金币值为用户实际金币值。

3.等用户退出捕鱼游戏就再次向斗地主发起第一个步骤的请求,如果成功,则完成了金币转移,如果失败(可能斗地主服务器中,这个用户下线了,可能斗地主奔溃了,可能网络阻塞或者掉线),捕鱼会把这次的请求写入到 redis 中,也就是上面的这个例子。

4.用户再次登录斗地主时,斗地主服务器需要去redis中查看是否有 捕鱼缩写(f) + " " + 用户uid 的这个健的存在,如果存在了,就要读取该键全部的成员

如:SMEMBERS f_10001,(理论上来说,每种请求最多一条记录)并且删除掉 redis中的 捕鱼缩写(f)+" "+uid 的健 如:DEL f_10001。并且按具体内容恢复数据。

这个机制适用于全部需要确保对端收到的命令。如果对端是捕鱼,那么 set 的键是 斗地主缩写(d) + "_" + uid,表示斗地主发起的请求失败了,捕鱼会按上面的流程自行处理。

开启 server的用户, 所用到的 cluster 方法:

访问 server的用户,所用到的 cluster 方法:

服务器ip 192.168.1.101 上有文件 main.lua , myserver1.lua , myserver2.lua , clustername.lua 和 config

clustername.lua 文件里面,写下你要开启监听的 cluster 节点

config 里把 clustername.lua 配置一下

下面是 main.lua

myserver1.lua 如下

myserver2.lua 如下

这两个server区别就是 CMD.func 的名字,里面的 print 和 return 的字符串.

服务器ip 192.168.1.102 上有文件 main.lua , clustername.lua 和 config

clustername 文件里面,写下你访问的 cluster 节点

config 里把 clustername.lua 配置一下

main.lua

上面三种方式里,需要注意的是 cluster.query 时, cluster.register 过的名字,在被使用时,是不用加 @ 符号的.

在 cluster.proxy 里如果不用 cluster.query 出来的地址,那么填写 cluster.register 过的名字时,是需要加 @ 符号的. 包括 cluster.call/send 第二参数也要加 @ 符号.

如果本文有什么问题,请留言,谢谢.


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/279024.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存