mmzb游戏事故分析
最近一次线上更新,老项目挂了,遍地哀嚎,日活跃掉了好多,心痛。。。
这次维护时,SA为了缩减硬件资源,做了一次数据库迁移。给到开发手上的player db,只有一些索引数据,不带有任一玩家数据。玩家上线的时候,skynet自动从redis-persist服务中拉取(redis-persist是一个基于旁路监听的redis落地程序,相对独立,参见之前的博文)。这也是RP服务的第一次高强度使用。按之前的策略,每次玩家下线都会在RP服务中存档,三个月不上线的玩家,会自动从redis数据库中移除,以节约内存。当流失玩家再度上线时,skynet先从redis中直接查询,无法加载到玩家的话,再度从RP服务中拉取,可以简单的将RP服务视作redis的一个二级缓存。玩家下线后,数据继续在redis中保留三个月。所以,设计之初,RP服务就是作为一个低频服务存在的,没有考虑到大量加载玩家的情况。
这次开服前,SA有同步到这个情况,我们以为只是玩家上线登录会慢一点而已,结果换来的却是惨痛的教训。上线后,因为redis里面空空如也,而各种排行榜和群雄逐鹿玩法,需要拉取玩家的基本信息,诸如名字、uid、等级、公会、性别等等基础数据。这是依赖于一个profile服务实现的。而profile加载玩家信息的接口,又跟玩家登录所用的接口不一样,没有实现从RP服务中加载。这是当时RP服务上线时,特地干掉相应接口的,因为当时已经考虑到profile服务会是一个高频访问,容易压垮RP服务。在策划的再三要求下,开发迫不得已把这个接口加回去,免得玩家信息空白。结果,上线一个小时左右,skynet就因为占用内存太大,直接挂掉了。
事后分析,应该是profile服务太慢了,需要一个个从磁盘上加载玩家数据,虽然自身有缓存,但是压上来的请求数量太多,请求也没有做去重(比如同一个uid,只对RP服务发出一次请求)。返回结果时比较缓慢,玩家就直接退出重新登录,之前查询到的数据作为临时表,已经没有接收者了(原有的session已经消失),于是变为GC的压力,最后把系统压垮了。再次启动上线后,关闭群雄逐鹿玩法,希望能减少profile服务的压力,结果轮到战斗搜索出问题了,线上搜索玩家进行攻击,依赖于redis里的数据,由于redis里玩家太少(只有刚刚登录上的),无法搜索到有价值的对手。开发这边就通过运营导出最近玩家数据,将热玩家数据重新导入redis里,解决问题。
这次事故里,profile服务因为单点故障,备受诟病。但是,从一个高度依赖redis内存数据库的服务器里,转到主要依赖磁盘的数据库上,这个改动就不是一个小改动。不止profile服务,还有其他服务也依赖于redis数据库(比如战斗搜索),正因为redis的访问代价低,代码里的cache和预加载就可以少写一点。如果相关玩法的假设是,数据都从磁盘加载,排行榜和群雄逐鹿玩法就可以先单独从磁盘上加载好自己要用的玩家数据,不需要依赖profile服务了。相反,SA部署新的redis实例的时候,将那部分热门玩家先加载到内存中,让skynet直接在redis就可以取到数据,不需借道RP服务,也可以解决问题。往后这数据加热,还是应该自动化完成,只是先前数据都在内存,不需要加热,就没这个问题。
退一步说,假设各个玩法依然从profile里加载基本信息,如果profile服务可以过滤重复请求,就可以释放掉RP服务的压力。这时候,压力就集中在profile服务的消息队列上了,由于磁盘加载速度慢,依然会有大量的请求积压。云风曾经提过一个skynet.call的超时处理方案,如果这个方案再改动一下,发现某服务大量积压请求时,自动随机抛弃新请求,profile服务就可以得到解放了。
mmzb游戏事故分析的更多相关文章
- 游戏模块分析总结(2)之UI、操作篇
转自:http://www.gameres.com/309812.html 游戏模块分析总结(2)之UI.操作篇 发布者: wuye | 发布时间: 2014-12-12 15:03| 评论数: 0 ...
- 记一次 .NET 某供应链WEB网站 CPU 爆高事故分析
一:背景 1. 讲故事 年前有位朋友加微信求助,说他的程序出现了偶发性CPU爆高,寻求如何解决,截图如下: 我建议朋友用 procdump 在 cpu 高的时候连抓两个dump,这样分析起来比较稳健, ...
- 记一次某制造业ERP系统 CPU打爆事故分析
一:背景 1.讲故事 前些天有位朋友微信找到我,说他的程序出现了CPU阶段性爆高,过了一会就下去了,咨询下这个爆高阶段程序内部到底发生了什么? 画个图大概是下面这样,你懂的. 按经验来说,这种情况一般 ...
- [erlang]一次erlcron崩溃引起的事故分析
事故背景 由于误操作在erlcron设置了一个超过3个月后的定时任务.然后第二天之后发现每天的daily reset没有被执行,一些定时任务也没有被执行.瞬间感觉整个人都不好了,怎么无端端就不执行了呢 ...
- 887C. Slava and tanks#轰炸弹坦克游戏(分析)
题目出处:http://codeforces.com/problemset/problem/877/C 题目大意:按照游戏规则,求最小炸弹使用次数 #include<iostream> u ...
- Java实现 LeetCode 810 黑板异或游戏 (分析)
810. 黑板异或游戏 一个黑板上写着一个非负整数数组 nums[i] .小红和小明轮流从黑板上擦掉一个数字,小红先手.如果擦除一个数字后,剩余的所有数字按位异或运算得出的结果等于 0 的话,当前玩家 ...
- 再记一次 应用服务器 CPU 暴高事故分析
一:背景 1. 前言 大概有2个月没写博客了,不是不想写哈
- 使用Adreno Profiler分析android游戏
有时候我们需要对自己的游戏或者别人的游戏进行分析,比如我们需要了解一个引擎的大体渲染的流程,这个时候我们可以借助一些工具,在PC上我们可以使用Microsoft PIX.Intel GPA.Nvidi ...
- Android-贪吃蛇小游戏-分析与实现-Kotlin语言描述
Android-贪吃蛇小游戏-分析与实现-Kotlin语言描述 Overview 本章的主要的内容是贪吃蛇小游戏的分析和实现,关于实现的具体代码可以在,文章底部的github的链接中找到. 整个游戏通 ...
随机推荐
- Linux安装node
以Ubuntu为例 1.apt-get update 2.apt-get install python gcc make g++ 3.wget https://nodejs.org/dist/v4.3 ...
- stm8s103头文件
//============================================================================== //================= ...
- <java基础学习>02JAVA的基础组成
Java的基础组成 1 关键字 (被赋予了特殊含义的单词) 2 标识符 3 注释 4 常量和变量 5 运算符 6 语句 7 函数 8 数组 关键字 class Demo{ public static ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E. Goods transportation (非官方贪心解法)
题目链接:http://codeforces.com/contest/724/problem/E 题目大意: 有n个城市,每个城市有pi件商品,最多能出售si件商品,对于任意一队城市i,j,其中i&l ...
- YII2 缩略图生成 第三方包修改
"xj/yii2-thumb-action": "^2.0" 原本的上传路径是全路径 根据日期生成的上传文件夹 不适用 比如 : upload\article\ ...
- 《JavaScript高级程序设计》读书笔记--前言
起因 web编程过程使用javascript时感觉很吃力,效率很低.根本原因在于对javascript整个知识体系不熟,看来需要找些书脑补一下,同时欢迎众网友监督. 大神推荐书籍 看了博客大神们推荐的 ...
- Python array,list,dataframe索引切片操作 2016年07月19日——智浪文档
array,list,dataframe索引切片操作 2016年07月19日——智浪文档 list,一维,二维array,datafrme,loc.iloc.ix的简单探讨 Numpy数组的索引和切片 ...
- 使用git删除远程仓库文件
git rm -r -f --cached 文件或文件夹 git commit -m "移除文件或文件夹" git push origin master 注意:要删除的文件或文件夹 ...
- 【译】Android 6.0 Changes (机翻加轻微人工校对)
Android 6.0 Changes In this document Runtime Permissions Doze and App Standby Apache HTTP Client Rem ...
- AngularJs的UI组件ui-Bootstrap分享(十)——Model
Model是用来创建模态窗口的,但是实际上,并没有Model指令,而只有$uibModal服务,创建模态窗口是使用$uibModal.open()方法. 创建模态窗口时,要有一个模态窗口的模板和对应的 ...