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一下重新建立连接等
我们服务器数据库节点和其他的节点并没有放到一台机器上,如果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一下重新建立连接等
相关文章推荐
- otter如何保持数据有序,回滚时如何丢弃避免重复执行,是否存在重复执行,重复执行是否有影响
- erlang获取离线玩家数据
- PXC集群添加新节点如何使用IST方式避免使用SST方式传输数据
- 求助大神!怎样除去XML节点反复的值的数据
- Velocity中避免null引起的数据问题
- C#数据回滚实例
- ZooKeeper数据模型、命名空间以及节点的概念
- EntiryFramework中事务操作(三)事务回滚数据模型和数据库不对应问题
- 如何避免Hadoop streaming 自动给单行数据加tab
- Effective C++ Item 28 避免返回对象内部数据的引用或指针
- SqlServer批量刷数据执行事务回滚语句备份
- [asp.net]控制ajax接收数据的编码格式和避免乱码的方法
- MySQL Cluster 4个数据节点压力测试--mysqlslap工具压400W写
- conn.setAutoCommit(false)数据回滚设置
- [大数据处理]-如何用消息系统避免分布式事务?
- mysql中间件Mycat:配置1(多节点取数据)
- json数据建立ztree并实现节点增删改
- winform开发打开窗体时, 若要在加载设计器前避免可能发生的数据丢失,必须纠正以下错误:
- Android读取Manifest文件下Application等节点下的metadata自定义数据
- xpath的数据和节点类型以及XPath中节点匹配的基本方法