能尽量用数据库代替内存就用吧,减少整天担心内存问题

游戏不好搞啊,设计的东西,能尽量简单就简单,代码太多判断就写死行了,反正它运行起来是对的就行了。

情形:09:00

昨天发生了很痛苦的一件事情,那就是游戏中data内存同步不到data数据库,这个问题在第二天才发现(游戏还可以正常玩),这让人很担心啊。同步data内存的是一个定时器TaskTimer,这个定时器会定时回写数据到data库中,但在某个时间点后就发现数据库没有增,一直停留停在那个点上;看到这个问题时,游戏肯定是不允许kill掉重启的(部分玩家数据会没有,会回档)。

确认问题:18:00

一开始时,就以为是后台操作不对,或配置有问题会导致data同步TaskTimer停掉,但开服后过一段时间才是这样,TaskTimer停掉的时候管理员也没有做不当的操作,所以查找操作日志是否恰当,查找配置是否有问题,查找数据库的密码是否被改过,查找代码是否有问题等,排除了外部的问题后,觉得是底层代码有问题,于是看了同步内存的代码,逻辑上是没有什么问题的,以前也没有出现过这种问题(开过好多个服),也是只之前的运气好,呵呵,其中发现在save(保存)操作时是没有try catch是,如果save有超时,过多操作等问题这里可能会报错。其中save方法里没有throw Error,但我们还是相信是这里出了问题。

想出解决办法:21:00

随着玩家数的增加,充值的增加,也意味着要快点解决问题,或则没有办法同步数据则丢失数据更严重。于是查看了游戏重启接口,这里是当游戏停服时,会停掉外网玩家的请求,将内存数据立即写入数据库,完成后会调用sh脚本kill me 再启动游戏。但同步内存代码和重启同步是同一个方法(同一个代码),痛苦啊。。。。定时器挂掉也是这段代码,虽然我们觉得是save有报错而停掉,如果不是,重启还是一样保存不了,那更惨。。。又认真研究这些代码,save报错的可能性最大,第二可能性是数据库操作对象无郊了,于是将目光转移到数据库操作对象这里,这个对象重启时会不会有问题呢?后来发现在重启时,是new 一个同步对象出来的,同步把新的数据库连接对象放入进去(很好的设计)。 于是我们就不担心数据库操作对象的问题了,这是方案一;如果方案一失败后,就直接导致无法恢复,这也是不允许的(除非逼不得已),于是有了方案二(备用方案,将损失降到最低),该方案是模拟现在所有的玩家,去登录外网服,然后请求能用于用户数据恢复的接口,将获得的数据,再一步步解析出来,用这些数据去还原一个玩家的重要数据,这也就相当于做前端了,比如:获得用户的等级level,则记录下来,再自己去new 一个User到自己数据库保存好。方案二也是逼不得已的,方案二的可行性及实现性很低,完全恢复也不是可能的,数据大多,并且工作量巨大。但不能丢掉数据,唉,方案一一旦执行后,则无法执行方案二,所以只能去试试方案二了。

实现方案:00:00

一开始方案二无从下手,要获得一个完整的玩家数据,则要从多个接口去获得,并且写的时候还不能直接去测试(会对外网玩家有很大的影响),只能将备份外网的数据库过来测。这些数据是正确的,但data库中(有三个库)数据不全(在内存中),这三个库如果是正常测试的话,数据是要一一对应的。所以蛋痛啊。。。。这叫我怎么去写代码拿数据,几个小时后还是没有办法写出代码来,估计是一辈子要写最凄凉的代码了。。。

最终执行:04:50

方案二明显是不可能做到的,于是放弃了,也是没有办法的了,所以将目光转向到方案一,方案一是重启,但又不想让程序停掉,所以我们将kill的脚本给删除了,到时重启时程序无法找到脚本从而无法重启,这时我们又可以多测试几次执行将内存同步数据库的代码,这恐怖的代码,让我们还是不放心,于是就在内网做定时器的异常报错,重启时再跑那些代码,内网测试是能同步内存的。所以现在将内存同步代码try catch 多写个可以控制游戏内存同步数据库的代替接口,将该版本更新到外网(重启后生效)。

最终结果:5:30

成功!再进入游戏测试,结果数据都同步到了数据。。。这天都不知道死了多少脑细胞。。。。。

【总结】

1、如标题:能尽量用数据库代替内存就用吧,减少整天担心内存问题—-内存确实是能带来读取数据的方便与快,但管理内存却是一件很头痛的事情,也很容易失去数据,所以效率允许的情况下,你还是改用数据库吧,毕竟–安全,稳定之后 才是效率

2、多写容错结构,像重启时执行代码对象里,是重新分配一个新的数据库操作对象过来,如是还是用旧的那个,之前别的地方用它挂掉了,那其他重要的执行则无法执行了。

3、相信自己的眼光,不要过多的猜想,运行好久的底层代码也是不可靠的

Original: https://www.cnblogs.com/hellohuang/archive/2013/04/20/3032255.html
Author: HolleHuang
Title: 能尽量用数据库代替内存就用吧,减少整天担心内存问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/612800/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • java中重载(overload)与重写(override)的区别

    方法重载(overload): 方法重载就是在一个类中可以创建多个方法,它们具有相同的名字,但是具有不同的参数和不同的定义,调用方法时通过传递给它们的不同参数个数和参数类型来决定具…

    数据库 2023年6月6日
    088
  • PHP最全编码规约

    1.1 标签 (1)【强制】PHP 程序可以使用或来界定 PHP 代码,在 HTML 页面中嵌入纯变量时,可以使用这样的形式,不可使用其他的标签变种。 正例: (2)【强制】纯 P…

    数据库 2023年6月14日
    0109
  • jspdf.js+html2canvas将HTMl导出PDF

    jspdf.js+html2canvas将HTMl导出PDF 功能: PDF分页插入页头页尾 输出A4格式PDF 支持单页、多页输出 效果预览:查看演示PDFdemo地址:demo…

    数据库 2023年6月11日
    0100
  • Golang 接口(interface)

    Go 语言的接口遵守LSP(里氏替换原则),即 一个类型可以自由地被另一个满足相同接口的类型替换。 接口类型具体描述了一系列方法的集合,一个实现了这些方法的具体类型是这个接口类型的…

    数据库 2023年6月16日
    070
  • Shell文件属性的判断与比较

    Shell支持对文件属性的判断,常用的文件属性操作符很多,如下表所示。更多文件属性操作符可以参考命令帮助手册man test [root@centos7~]#…

    数据库 2023年6月14日
    082
  • Win10系统-接口自动化测试持续集成

    使用工具:jdk+jmeter+Ant+jenkins jdk-1.8.0_241版本【安装参考链接:https://blog.51cto.com/u_15463439/52268…

    数据库 2023年6月14日
    089
  • Exception Handling Considered Harmful

    Do, or do not. There is no try. — Yoda, The Empire Strikes Back(George Lucas) Recent progr…

    数据库 2023年6月9日
    083
  • Rocksdb Compaction原理

    compaction主要包括两类:将内存中imutable 转储到磁盘上sst的过程称之为flush或者minor compaction;磁盘上的sst文件从低层向高层转储的过程称…

    数据库 2023年6月9日
    088
  • Java异步执行器CompletableFuture源码解析

    CompletableFuture是对 Future的一种强有力的扩展, Future只能通过轮询 isDone()方法或者调用 get()阻塞等待获取一个异步任务的结果,才能继续…

    数据库 2023年6月11日
    082
  • Hbase中(java.io.IOException: Could not locate executable nullbinwinutils.exe in the Hadoop binarie)

    报错信息如下: 结合大神分析,应该为本机使用Hbase时,没有配置其环境变量。 出处:https://www.cnblogs.com/jessezeng/p/5520915.htm…

    数据库 2023年6月11日
    069
  • MySQL连接的建立与使用

    在 MYSQL的启动过程中,可以看到在 mysqld_main() 函数的最后调用了 mysqld_socket_acceptor->connection_event_loo…

    数据库 2023年6月9日
    072
  • Mysql8.0修改lower_case_table_names参数导致重启失败

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 GreatSQL是MySQL的国产分支版本,使用上与MySQL一致。 事件起因:在测试一个数据迁移工具…

    数据库 2023年5月24日
    093
  • select,poll,epoll

    select、poll、epoll 区别总结: 底层实现 select/poll 首先把关注的Socket集合从用户态拷贝到内核态,然后由内核检测事件,遍历整个集合(由于线性结构实…

    数据库 2023年6月16日
    087
  • JUC的数据库连接池小练习

    JUC练习数据库连接池实现 通过一个连接数组来充当连接池 一个原子的标记数组 通过cas来保持多线程下的安全,用synchronized来进行暂停和唤醒 @Slf4j public…

    数据库 2023年6月11日
    082
  • 将博客搬至CSDN

    将博客搬至CSDN posted @2021-11-11 15:01 深海云帆 阅读(20 ) 评论() 编辑 Original: https://www.cnblogs.com/…

    数据库 2023年6月9日
    083
  • java中如何将函数作为参数传递呢?

    函数简介: 函数(function)的定义通常分为传统定义和近代定义,函数的两个定义本质是相同的,只是叙述概念的出发点不同,传统定义是从运动变化的观点出发,而近代定义是从集合、映射…

    数据库 2023年6月11日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球