前一段时间做的一个小模块,做的节点监控,处理一些异常情况,比如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节点,这样只能让