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

这次维护时,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. express

    1.基于node.js的web开发框架. 2.express目录结构: node_modules public routes views app.js:项目主文件 package.json 3.获取程 ...

  2. 吐槽!important专用博文

    在IT公司实习了1个多月,氛围还是不错的,也算是积累了一些项目经验,同时在代码模块化.版本控制.任务优先级等方面有了更进一步的体会和理解,深刻认识到在一个团队,最重要的是沟通和负责. 嗯,说了下题外话 ...

  3. 在CentOS 6.7中安装 latex2html, 实现 latex 自动转化为 word

    由于latex文档生成的pdf不便于提供审阅和修改,亟需一个软件实现从latex向word文档的自动转换( 如何把Latex自动转为Word 介绍了由latex2html 可实现这个功能,这也是初衷) ...

  4. Leetcode 详解(Substing without repeats character)

    Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...

  5. ZOJ 3817Chinese Knot(The 2014 ACM-ICPC Asia Mudanjiang Regional First Round)

    思路: 将4个串每个串都反向这样得到新的四个串一共8个串,对于母串每个位置检测这个串能不能放进去,hs或者后缀数组都可以.然后dp[i][j]  (0<i<len  0<=j< ...

  6. SEO学习笔记-误区和经验总结

    原文链接:http://www.cnblogs.com/monxue/p/seo_note.html 常见误区和错误: 1.忽视404错误页面的优化,没有及时处理死链导致权重降低 2.做外链优化只链到 ...

  7. Windows Server 2012 中80端口被PID为4的系统进程占用解决方法

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP 把"start" 的值改成4.

  8. MD5使用

    MD5加密算法,即"Message-Digest Algorithm 5(信息-摘要算法)",它由MD2.MD3.MD4发展而来的一种单向函数算法(也就是HASH算法),它是国际著 ...

  9. StormNimbus集群保证CAP流程

    Nimbus启动时,检查当前本地是不是有所有的topology的代码,同时去申请获取leader锁,如果某台nimbus节点成为了集群的leader,会再去检查一次当前本地的代码是不是包含所有活动状态 ...

  10. run VLC in root

    sed -i 's/geteuid/getppid/' /usr/bin/vlc