一个对象的key引发的血案

现在正在开发一个MMOSLG的手游,最近公测了,本来是挺让人期待,可是前两天由于一个对象的key引发了一场血案。

那天周六,照常加班到晚上六点下班。回到宿舍,吃了个饭,休息到八点,刚想玩一会游戏,接到客服电话,说有玩家丢兵丢将了(就是把城中部队派出去了,但是再也没回来了)。于是乎就匆忙打车到公司(将近八点半到的),毫无疑问,先去查了一遍报错日志,结果并没有发现什么有价值的东西。于是乎,没办法,只能去查代码,粗略看了一遍没啥问题,但是结合游戏日志,可以查到是在哪个阶段出的问题,反复读那个阶段的执行代码,终于发现有个对象用来保存玩家部队(object[key] = troop),咋一看,好像没啥问题,但是认真看了一下,那个key是一个时间time,并且那个time的时间精度是一秒,这样就导致同一秒进入这个执行逻辑的玩家,只会有一个被保存,因此就出现了其他人部队丢失的事件。

知道问题出现在哪里了,作为程序,改起来当然很简单,这个过程就不细说。然而事情并没有就这么结束,更加复杂的事情还在后面。

程序问题改了,但是玩家问题还没处理,玩家很多都是充钱玩的,有好几个还是充了好多钱的。那么问题来了,有些玩家部队丢了,甚至是由于部队丢了,导致老家没有防守力量而被攻击,造成了不小的损失。这个时候,我们就得赔偿玩家了,策划和产品研究后,让我统计了一番玩家数据,把出现丢兵丢将的玩家以及他们丢兵丢将后的战争损失全部算了一遍。然后就去翻数据库,查各个表,想办法把他们要的数据给弄出来,把所有数据取出所有数据后,写了个脚本,把这些数据过滤处理了一遍。完事之后,就开始处理了。首先先服务器在线更新,把bug解决了,之后就是处理玩家的情况,先把玩家丢的部队给他弄回去,然后呢就是把玩家由于丢部队被打的损失,给补回去。对于全部玩家给予一定的补偿,对于丢兵丢将的玩家给予额外的补偿。事情好像很简单,大概在凌晨一点的时候全部操作完毕,然后就回宿舍了,刚回宿舍,又收到通知,玩家进不去服务器了,心里很忐忑,该不会是刚刚自动更新导致的问题吧,没办法,又打车回公司,结果发现,不是游戏问题,是机房网络断了,然后就通知运维,等运维处理好,回到家里,大概就两点了。通知测试第二天上班,测试一下新提交的东西(事情比较紧急,测试家里又比较远,所以就先更新出去了)。

第二天早上十点,程序测试准时到公司,开始测昨天的修改。结果客服就来反应了,说玩家来反馈了,尤其是那些大R,都在闹退游。我也有玩游戏,其中一个大R就是我们帮派的,看了他在帮派管理员群里面说的,他也想退游了,吓死我,他怎么可以退游,然后紧急通知产品,产品要了玩家电话,好说歹说,又是讨价还价,又是被玩家威胁的,总之,其中的滋味,真是苦不堪言。虽然最后勉强把玩家留了下来,但是发现大家已经热情大减了,都基本可以让人感觉整个服快要废了。大概就是这样,一个bug,导致游戏质量深受质疑,使玩家超级不爽。

所以,作为一个程序,必须不能大意,也许有一天,你写的一个小bug,会让整座大山倒下,全军覆没。

时间: 2024-10-14 05:34:23

一个对象的key引发的血案的相关文章

openstack运维实战系列(十三)之glance更改路径引发的"血案"

1. 背景说明 glance在openstack中负责镜像相关的服务,支持将运行的虚拟机转换为快照,镜像和快照都存储在glance中,glance的后端支持多种存储方式,包括本地的文件系统,http,glusterfs,ceph,swift等等. 默认情况下,glance采用本地文件系统的方式存储image,存储的路径为/var/lib/glance/images,随着时间的推移,当镜像越来越多的时候,根目录的空间将会越来越大,所以对于glance的路径来说,需要提前做好规划和准备,如划分一个单

JVM--JVM finalize实现原理与由此引发的血案

原创内容,转载请注明出处 本文由一桩因为使用了JAVA finalize()而引发的血案入手,讲解了JVM中finalize()的实现原理和它的陷阱所在,希望能够对广大JAVA开发者起到一点警示作用.除此之外,本文从实际问题出发,描述了解决问题的过程和方法.如写模拟程序来重现问题,使用jmap工具进行分析等,希望对大家提供借鉴. 本文分三个章节,先介绍实际项目中遇到的问题,随后介绍了问题重现和分析方法,最后对问题的元凶,override finalize()的实现原理和陷阱进行了讲解和介绍.篇幅

一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁

前续 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(一)——地:起因 一个无锁消息队列引发的血案:怎样做一个真正的程序员?(二)——月:自旋锁 平行时空 在复制好上面那一行我就先停下来了,算是先占了个位置,虽然我知道大概要怎么写,不过感觉还是很乱. 我突然想到,既然那么纠结,那么混乱,那么不知所措,我们不如换个视角.记得高中时看过的为数不多的长篇小说<穆斯林的葬礼>,作者是:霍达(女),故事描写了两个发生在不同时代.有着不同的内容却又交错扭结的爱情悲剧,一个是“玉”的故事,一个是“月”

一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]

目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的艺术 [续] 开篇 这是第五篇的后续,这部分的内容同时会更新和添加在 第五篇:RingQueue(中) 休眠的艺术 一文的末尾. 归纳 紧接上一篇的末尾,我们把 Windows 和 Linux 下的休眠策略归纳总结一下,如下图: 我们可以看到,Linux 下的 sched_yield() 虽然包括了

一个二级菜单引发的血案

近期发现自己css不是很好,于是又看了一遍<css权威指南>.总感觉自己抓不到重点.弃疗中...于是看看其他书.然后学妹跟我说她的二级菜单写得很乱.当时我心里就在想二级菜单,有何难?自认为10分钟能搞定.跟她要效果图并很自大的说了句“等会儿,我写个简单的”.于是血案由此引发... 二级菜单要实现的原效果图是: (如发现雷同,不是巧合,是我从别的网页上截屏下来的 ~_~).既然说了简单,肯定效果没这么精美.但是至少基本效果和原理要实现. 10分钟过去了....15分钟过去了....这个“等会儿”

模板链接与前置声明引发的血案

模板链接与前置声明引发的血案 模板链接与前置声明引发的血案 现象 问题原型 模板參数类型类 使用类模板的类 分析 objdump -S TemplateLink SUPERSUBCLASS 分析 objdump -S UsingBaseo objdump -S UsingChildo 问题解答 解答问题一 解答问题二 解决方式 类型萃取辅助类 应用 不足 现象: 有一个类模板,它会依据模板类型參数T的实际类型,调用不同的实例化泛型函数子去处理实际事情. 在程序运行时.发如今不同的模块中用相同的类

一个Sqrt函数引发的血案

我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然有可能你平时没有想过这个问题,不过正所谓是"临阵磨枪,不快也光",你"眉头一皱,计上心来",这个不是太简单了嘛,用二分的方法,在一个区间中,每次拿中间数的平方来试验,如果大了,就再试左区间的中间数:如果小了,就再拿右区间的中间数来试.比如求sqrt(16)的结果,你先试

一次优化引发的血案

前些天一个Nginx+PHP项目上线后遭遇了性能问题,于是打算练练手,因为代码并不是我亲自写的,所以决定从系统层面入手看看能否做一些粗线条的优化. 首先,我发现服务的Backlog设置过小,可以通过ss命令查询Send-Q来确认: shell> ss -ln Recv-Q Send-Q Local Address:Port Peer Address:Port 0 511 *:80 *:* 0 128 127.0.0.1:9000 *:* 明显看出,Nginx的Backlog是511:PHP的Ba

一个由内存泄漏引发的血案-Square

一个内存泄漏引发的血案-Square 原文链接 : A small leak will sink a great ship 原文作者 : Pierre-Yves Ricau 译文出自 : 开发技术前线 www.devtf.cn.未经允许,不得转载! 译者 : chaossss 校对者: 这里校对者的github用户名 状态 : 完成 在开发 LeakCanary 时我发现一处奇怪的内存泄漏,为了搞清楚到底是什么原因导致这个问题我一边 Debug,一边在邮件中和小伙伴们沟通,最后形成了这篇博文.