最近一次线上更新,老项目挂了,遍地哀嚎,日活跃掉了好多,心痛。。。

这次维护时,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游戏事故分析的更多相关文章

  1. 游戏模块分析总结(2)之UI、操作篇

    转自:http://www.gameres.com/309812.html 游戏模块分析总结(2)之UI.操作篇 发布者: wuye | 发布时间: 2014-12-12 15:03| 评论数: 0 ...

  2. 记一次 .NET 某供应链WEB网站 CPU 爆高事故分析

    一:背景 1. 讲故事 年前有位朋友加微信求助,说他的程序出现了偶发性CPU爆高,寻求如何解决,截图如下: 我建议朋友用 procdump 在 cpu 高的时候连抓两个dump,这样分析起来比较稳健, ...

  3. 记一次某制造业ERP系统 CPU打爆事故分析

    一:背景 1.讲故事 前些天有位朋友微信找到我,说他的程序出现了CPU阶段性爆高,过了一会就下去了,咨询下这个爆高阶段程序内部到底发生了什么? 画个图大概是下面这样,你懂的. 按经验来说,这种情况一般 ...

  4. [erlang]一次erlcron崩溃引起的事故分析

    事故背景 由于误操作在erlcron设置了一个超过3个月后的定时任务.然后第二天之后发现每天的daily reset没有被执行,一些定时任务也没有被执行.瞬间感觉整个人都不好了,怎么无端端就不执行了呢 ...

  5. 887C. Slava and tanks#轰炸弹坦克游戏(分析)

    题目出处:http://codeforces.com/problemset/problem/877/C 题目大意:按照游戏规则,求最小炸弹使用次数 #include<iostream> u ...

  6. Java实现 LeetCode 810 黑板异或游戏 (分析)

    810. 黑板异或游戏 一个黑板上写着一个非负整数数组 nums[i] .小红和小明轮流从黑板上擦掉一个数字,小红先手.如果擦除一个数字后,剩余的所有数字按位异或运算得出的结果等于 0 的话,当前玩家 ...

  7. 再记一次 应用服务器 CPU 暴高事故分析

    一:背景 1. 前言 大概有2个月没写博客了,不是不想写哈

  8. 使用Adreno Profiler分析android游戏

    有时候我们需要对自己的游戏或者别人的游戏进行分析,比如我们需要了解一个引擎的大体渲染的流程,这个时候我们可以借助一些工具,在PC上我们可以使用Microsoft PIX.Intel GPA.Nvidi ...

  9. Android-贪吃蛇小游戏-分析与实现-Kotlin语言描述

    Android-贪吃蛇小游戏-分析与实现-Kotlin语言描述 Overview 本章的主要的内容是贪吃蛇小游戏的分析和实现,关于实现的具体代码可以在,文章底部的github的链接中找到. 整个游戏通 ...

随机推荐

  1. 编译MVC解决方案老出现这个问题的原因

    Server Error in '/' Application. The view at '~/Views/Home/Index.cshtml' must derive from WebViewPag ...

  2. 通过pip安装模块

    环境:ubuntu,python2/3 命令: pip3 install ipy # 通过pip3给python3.x安装ipypip3 install --upgrade pip # 升级pippi ...

  3. node.js 学习

    http://www.cnblogs.com/haogj/category/612022.html

  4. POJ2774 (后缀数组)

    #include<cstdio> #include<cstring> using namespace std; ],b[]; ],x[],wv[],ws[],h[],rank[ ...

  5. HttpServletResponse常用的方法

    所有Servlet响应都实现ServletResponse接口.ServletResponse接口主要有以下方法: (1)从Servlet中可以通过getWriter方法取得PrintWriter对象 ...

  6. A、B、C、D和E类IP地址

    IP地址分为A,B,C,D,E五类. 网络号:用于识别主机所在的网络:主机号:用于识别该网络中的主机. 其中A类分配给政府机关使用,B类地址给大中型企业使用,C类地址给个人使用.这三种是主要的. IP ...

  7. HalconMFC(一)之多版本配置

    今天比较匆忙,还得写周六日考试扯P的PPT,就先这样开个头吧.我的电脑是win7,32位的系统,我用Halcon10.0.但是很多小伙伴的都是64位系统的,所以我用小伙伴的64位系统试过很多次用VC配 ...

  8. golang实现冒泡排序

    //BubbleSort.go package main import "fmt" func main() { , , , , , , , , ,} fmt.Println(val ...

  9. tomcat启动不了

    今天弄了一个项目想在在自己的电脑上面运行起来,当部署在tomcat上的时候发现tomcat就是启动不来,思忖了一段时间后发现原来是tomcat的相关jar没有导入进去.所以,properties-&g ...

  10. jacoco原理

    Jacoco的原理 转自:kingzzm 的博客,感谢~ 覆盖率计数器 Jacoco使用一系列的不同的计数器来做覆盖率的度量计算.所有这些计数器都是从java的class文件中获取信息,这些class ...