您的位置:首页 > 其它

erlang节点挂掉避免玩家数据回滚

2013-06-19 09:28 288 查看
前一段时间做的一个小模块,做的节点监控,处理一些异常情况,比如db节点挂掉,或者db节点所在主机出现断网情况。

我们服务器数据库节点和其他的节点并没有放到一台机器上,如果db节点挂掉或者db节点所在机器断网,玩家数据会出现异常,因为玩家的数据存贮到ets中,每隔几分钟写入数据库的,出现上述情况之后玩家照样可以玩游戏,获得物品,但是写库操作会失败。之前游戏中对并没对这种情况做一些相应处理,db挂掉或者db节点断网玩家可以继续玩游戏,直到玩家操作会直接读写数据库,出现异常然后玩家掉线。但是从db挂或者断网之后玩家得到的物品经验都会无效,因为ets中的玩家数据并没有写入数据库,玩家数据要回滚。

为了避免玩家数据回滚,在程序中加了一些捕获异常的操作。首先做数据库写入、删除异常捕获,如果数据库写入失败,返回{badrpc,nodedown}则将写库操作的函数,以及传递的参数写入文件,注意出现异常后会有大量玩家写库失败然后写入文件,我们要做好数据同步处理,其实很简单,写文件操作由一个进程来做即可。其次做节点监控,如果db挂掉会马上收到nodedown消息,如果出现db所在机器断网会在大约30s之内收到nodedown消息(断网情况下,收到nodedown消息之前很可能写文件操作已经进行了30s)server_manger节点做节点监控,server_manger得知db节点出现问题后,关闭gate,也就是使玩家不能再继续登录,给在线玩家发送一个db_nodedown消息,改消息发送到了玩家进程,玩家进程受到该消息之后,将ets中的数据马上进行一次写库操作,其实就是写入文件(前边说了,不是玩家进程写文件,而是玩家进程给该节点一个公告进程发消息,由改公共进程写大量玩家的数据,避免数据混乱),然后踢玩家下线。然后server_manger对除map之外的节点发送停服命令,告诉map节点,map写文件完成之后直接停服。所有的服都停之后(当然不包括server_manger),server_manger重启服务器,重启时候,map节点在之前写入文件的数据会直接写入mnesia数据库,这样就避免了玩家的数据回滚。

当然这里面还有好多需要注意的细节,例如,

保证玩家数据都写入数据库然后停map节点,这样只能让map自己停掉自己,而别的节点可以使用server_manger停,

保证所有的节点都停掉之后再进行重启等等,

捕获数据库写、删除操作异常不要修改数据库函数的返回值,

我们不仅要有文件备份库操作的异常捕获,还需要备份ets中的数据,

对db节点挂和其他节点挂需要做不同的处理,

网络畅通后自动启服

对于重启节点之后,节点之间要互ping一下重新建立连接等
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: