1. 数据存档检查
(1) 检查跨区是否会导致活动数据异常或丢失。一般来说跨区是不应该修改活动数据的,所以通常会在活动相关的定时器、事件触发以及消息触发入口处进行屏蔽,且跨区加载数据时会先备份一下数据,回原区的时候,直接把备份的数据原封不动带回。
(2) 检查跨区是否能获取活动奖励,如果能的话,将可能导致奖励被刷。这是因为,根据(1)的规则,已经获取奖励的标志一般不会带回(除非特殊处理),这样一来,玩家回原区的时候就可以再次获取活动奖励。所以要么把获取奖励的标志带回(商业化活动一般跨区不开放,通常不这样做),要么进行屏蔽。通常来说都是跨区时候对商业化活动进行屏蔽,玩家跨区时无法参加该类活动的。
(3) 加载数据的时候如果有repeated字段,需要先clear一下接收的数据结构,再进行加载,否则跨区回原区的时候会重新加载,从而导致接收的数据结构会重复加载repeated数据。
(4) 检查存档数据的活动,这时如果存档有repeated字段的话,要注意先clear一下然后再存档,这是因为有些数据跨区后可能会被带回,如果没clear直接调用save就会进行二次存档,将导致repeated数据重复存储,最终档案过大且数据异常。
(5) 检查跨区是否会导致活动异常开启或关闭的情况(比如重复开启、提前关闭、清理数据)。
(6) 检查数据的初始化。使用未初始化的数据将可能导致无法预知的问题。
(7) 如果有清理数据的地方,检查清理的对象是否正确,以及清理的时间点是否正常。
(8) 检查是否存在遗漏存储数据的情况。安全重启一下服务器,如果数据没了,有可能就是没有存档。
(9) 检查数据库存档时是否有字段大小超出限制,导致存档失败,数据丢失。
(10) 检查跨服切场景是否会导致数据异常,比如活动进行中跨服切场景,临时数据是否正常保存等。
(11) 是否修改了已有的字段,如果修改,需要保证版本兼容以及数据不丢失。
(12) 提交时proto字段冲突,只能改自己未提交的proto字段,不可修改已有的proto字段。
(13) 多位同事同时提交一份proto协议时,有时候字段编号存在一样的,但是没有提示有冲突。需要检查是否存在这种情况,如果存在将会导致数据存档异常。
(14) 对于proto的repeated字段,检查是否设置了大小上限,数据量是否会无限增加。
(15) 是否做了防护机制,数量超了以后需要封禁,禁止玩家登陆,防止进一步丢失档案。
(16) 尽量不要存储全局repeated数据到二进制字段中,这样很容易增加存档量,比如一些使用全局管理管理的数据,如果玩家多,数据量就会大,很容易就爆掉。(一般单个proto消息序列化后存档的数据大小不超过64k)
(17) 考虑存档是否过于频繁,是否需要进行一些优化,比如立即存档,改为定时存档(存储次数过多,用这种方式可以改为一次)。所有数据的存档,改为针对变动数据的存档(数据量大的,可调节存档数据量)。单条数据存档,改为一次多条批量存档(记录多时,这样做可以减少io时间)。针对变更数据做存档,无法区别时使用replace,不要做delete再insert的事情(replace是delete和insert的合成版)。数据量过大,序列化或压缩等消耗时间,改到其他线程压缩后再存档。
(18) 尽量规避一份数据存到多个地方的操作,这样做可以防止数据不一致,档案激增等。可以存储关系,起服构建各自的数据,相当于把这一份数据独立出来管理。
(19) 版本切换是否正确。是否会因为版本切换不正确导致数据被清掉。
2. 合区检查
(1)合区数据是否正常,是否会因为合区导致活动异常关闭,重开,或奖励重发,不发等行为。
(2)合区是否会 导致主键冲突,从而无法完成合区操作,如果冲突是否有解决方案。
(3)考虑合服后相应字段的处理,比如,考虑合服后的数据是否可用或者说是选择使用本服的数据还是合进来区服的数据。
(4)新增或变更数据库表相应的处理方式是否记录下来,记录备案以供检查。
3. 回档检查
(1)是否会因为玩家回档导致刷金子,比如活动要给金子,回档之后已给金子的标记跟着恢复为未给状态从而导致重新给金子。
(2)回档隐患检查,针对跳场景、重登陆、跨区等业务处理,检查是否存在档案没有正确保存的隐患。
4. 活动重开检查
(1)检查重开活动时,是否会因为上次活动的残留数据(未结算,上次活动未完成直接下线,该次活动期间上线等)导致活动异常,无法开启活动,或者活动异常结束,结算等。
(2)老功能修改是否会破坏已有的数据,或者无法正常进行版本的更替。
(3)活动中的一些合成数据(经过多个变量计算后的数据)是否会因为重开次数,时间等的限制导致数据溢出的问题。
(4)是否会因为数量相关配置变更导致活动异常。
5. 检查修改过的代码
(1)是否修改了不属于本次开发功能的代码。
(2)是否修改了多个功能共用的代码,是否将影响到的功能标记下来并反馈给qa测试。
(3)是否修改了已有的计数器的类型,导致无法正常计数。
6. 奖励检查
(1)是否存在给了奖励之后没有记上标记的情况,导致被刷奖励。
(2)遍历将道具插入邮件,然后发送该邮件,是否会出现最后一封邮件没有发送的情况(最后一封邮件可能因为数量不满足条件,一般最多5种或6种道具,退出循环)。
(3)是否出现了新活动给了老活动奖励的情况。
7. 宕机检查
(1)检查空指针,使用前需要判空。
(2)检查野指针,是否会delete后指针没有释放的情况,需要置为NULL。可以写个宏定义safe_delete:delete后指针再置为空。
(3)是否存在循环遍历中有修改容器的行为,比如遍历map或者vector时,删除某个元素等。
(4)除0检查。
8. 其他检查
(1)日志输出是否过于频繁,频率很高的日志输出很容易造成磁盘被写满,从而影响正常运行。
(2)检查消息大小是否超出限制。
(3)检查消息的发送和接收是否过于频繁,一般来说,单台机器36M/s就需要提高警惕了。
(4)对配置文件里面的主要数据要进行正确性检查,尤其是修改已有数据时。
(5)是否存在内存泄漏,主要是检查内部new出来的对象没有及时释放内存。
(6)是否存在死循环,包括是否存在函数相互调用导致死循环等。
(7)性能评估。确定功能大概类型,从而判断出是否涉及数据库访问,是否涉及大量运算,是否涉及大量数据同步等情况,如果涉及到这些情况,需要重点检查相关性能是否存在瓶颈,会不会导致服务器卡顿。
(8)安全检查。对于客户端发的所有消息,里面的每个字段,都要进行合法性判断,判断是否考虑到所有异常情况等。
(9)变长消息,是否有限制长度。最大消息长度为64k,如果不限制的话,有可能溢出。
(10)如果存在对数据的操作,比如加减乘除等,检查是否有溢出的可能。
(11)禁止一切不带长度限定的字符串操作函数,比如strcat,strlcat,strcpy,strlcpy,strcat,strncat等。
(12)流程重入检查,对逻辑流程需要跨服处理的,检查是否需要有流程锁。
(13)道具隐患检查,对于发放奖励性质的道具处理时,检查是否存在未验证、未记录领取次数,是否存在由于流程重入而造成客户端多次发送领取消息可以重复领取奖励的严重bug。
(14) 类似累计充值送奖励等活动,需要判断活动是否开启,不应该在活动未开启的时候,累计玩家充值金额,从而导致误发奖励。
9. 总结
(1)形成防御性编程思想,防止空指针,野指针,内存泄漏,除0,溢出等,还要考虑一些异常情况,防止waigua等。
(2)数据的清理与初始化,防止未清理数据以及未初始化数据给程序带来不可估计的后果。
(3)正确考虑数据的存储。
(4)跨场景和跨地图的处理,主要考虑数据会不会同步。
(5)服务器重启的处理,主要看重启后数据有没有消失 。
(6)服务器宕机的处理,一般需要处理数据保存以及同步的问题。
(7)玩家掉线以及正常上下线的情况。
(8)性能问题,该优化的时候需要进行优化,不要过于频繁的操作数据库,考虑数据量过大时的处理,比如缩小数据同步范围与频率等。
(9)return的时候要小心,防止提前返回,导致后面本要执行的代码没有机会执行。
(10)多自测,自己作为最后一道防线,不要寄托于策划和qa测试。