手游server之数据IO进化
这里数据IO是指游戏数据存盘和读取。
假设IO处理不好。server在IO时会导致。游戏卡顿较长的时间,严重影响游戏体验。
近期服务端刚好对IO这一块做了优化,把优化过程记录一下。
一 原始版
刚開始立项的时候,仅仅是做了一个Demo,加上也刚開始做服务端,仅仅是做了一个仅仅可以測试用的server。
当时是在每一个场景对象area中加入了一个users对象,通过uid来保存每一个玩家的数据。
当玩家登录的时候,将玩家的数据读入。退出的时候将玩家的数据写回。
var users = {};
function onLogin(uid){
var user = DBMgr.read(uid);
users[uid] = user;
}
function onLogout(uid){
var user = users[uid];
DBMgr.write(user);
delete users[uid];
}
为了防止server宕机数据丢失,再添加了一个定时存盘。
function onTick(){
for (var uid in users) {
var user = users[uid];
DBMgr.write(user);
}
}
这样做有两个非常明显的问题:
1 假设一个玩家下线之后马上又一次登录,就会又一次IO的过程;
2 每次都须要将所有玩家的数据写入。玩家多了之后会卡非常长时间。
二 进阶版
为了解决如上问题,添加了一个cache。
玩家离线后。先将其数据移到cache中,每隔一段时间,将cache中的玩家写入存储介质中。
登录的时候先在cache中查找玩家的数据,假设找不到。再去读数据。
然后结构就变成了这样:
var users = {};
var cache = {};
function onLogin(uid){
if (!!cache[uid]) {
users[uid] = cache[uid];
delete cache[uid];
} else {
users[uid] = DBMgr.read(uid);
}
}
function onLogout(uid){
var user = users[uid];
cache[uid] = user;
delete users[uid];
}
function onTick(){
for (var uid in cache) {
var user = cache[uid];
DBMgr.write(user);
delete cache[uid];
}
}
然而,前面两个问题并没有彻底地解决掉。
1 假设玩家下线之后。刚好onTick时间到,这样数据就被写回了,下次登录就得又一次读一次;
2 若是在onTick这个周期内下线的玩家太多。onTick之中还是会有非常多玩具须要写入。
三 终极版
为了优化前面的两点,不再玩家的数据移到cache,而是在cache中保存玩家的下次存盘时间。
每次登录直接在users中找数据,假设找不到,就读数据库。
假设玩家下线。就将其下次存盘时间在变为对应的负数,来标记玩家已经下线。
在onTick中,先将到存盘时间的玩家存盘,然后已下线的玩家从users和cache中同一时候移除。
var users = {};
var cache = {};
function onLogin(uid){
var user = users[uid];
if (!user) {
user = DBMgr.read(uid);
users[uid] = user;
cache[uid] = curTime + WRITE_GAP;// WRITE_GAP为存盘间隔时间
}
}
function onLogout(uid){
cache[uid] = 0 - (curTime + WRITE_GAP);
}
function onTick() {
for (var uid in cache) {
var time = cache[uid];
if (curTime < Math.abs(time)) {
continue;
}
DBMgr.write(users[uid]);
if (time < 0) { // 离线玩家
delete users[uid];
delete cache[uid];
} else { // 在线玩家
cache[uid] = curTime + WRITE_GAP;
}
}
};
这种结构定时存盘一批玩家数据,即使玩家离线也能够在内存中保存一段时间。
眼下我们的服务端存盘机制就是这种,假设以后有优化再补充。
手游server之数据IO进化的更多相关文章
- 记一个手游app数据文件的破解
出于一些非常猥琐的须要,同一时候自己也想做一些新奇的尝试,周末用了大半天时间破解了某款手游的数据文件. 过程比我预想的要顺利,主要原因还是我们开发者的懈怠.咳咳. 步骤例如以下: 下载安装包,解压,发 ...
- Cocos2d-x手游技术分享(1)-【天天打蚊子】数据存储与音效篇
前言: 手游项目<天天打蚊子>终于上线,特地写几篇技术分享文章,分享一下其中使用到的技术,其中使用cocos2d-x引擎,首选平台iOS,也请有iPhone或者iPad的朋友帮忙下载好评. ...
- 如何从“点子”落地到“执行”?—完整解析1个手游传播类mini项目的进化
本文来自网易云社区 作者:林玮园 从点子到落地,是不确定到确定的过程,是从模糊概念到具体现实的实现过程.无论什么点子,在落地变现的过程中都会有很多疑问产生. 首先,不确定点子本身是否成立.点子的背后是 ...
- SLG手游Java服务器的设计与开发——数据管理
文章版权归腾讯GAD所有,禁止匿名转载:禁止商业使用:禁止个人使用. 一.前言 上文介绍了我们的SLG手游的服务器架构设计以及网络通信部分,本文介绍数据管理部分,在数据存储方面,我选择了Mysql.M ...
- Unity3D手游开发实践
<腾讯桌球:客户端总结> 本次分享总结,起源于腾讯桌球项目,但是不仅仅限于项目本身.虽然基于Unity3D,很多东西同样适用于Cocos.本文从以下10大点进行阐述: 架构设计 原生插件/ ...
- 腾讯首度公开S级手游品质管理方法
weimjsam 引言 在最新的手游市场占有率统计中,腾讯游戏稳稳占据一半江山,目前仍以每月一到两款的速度推出新品,在如此复杂多变.响应要求极高的市场环境下,能持续推出高质量产品并保持高效迭代更新 ...
- 手游Apk破解疯狂,爱加密apk加固保护开发人员
2013年手游行业的规模与收入均实现了大幅增长,发展势头强劲.权威数据显示, 我国移动游戏市场实际销售收入从2012年的32.4亿猛增到2013年的112.4亿元,同比增长了246.9%,手游用户从2 ...
- SLG手游Java服务器的设计与开发——架构分析
微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...
- 《疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)》
<疯狂iOS讲义(下)——iPhone/iPad高级应用与手游开发(含CD光盘1张)> 基本信息 作者: 李刚 肖文吉 出版社:电子工业出版社 ISBN:9787121224379 ...
随机推荐
- cookie/session在nodes中的实战
cookie 和 session 众所周知,HTTP 是一个无状态协议,所以客户端每次发出请求时,下一次请求无法得知上一次请求所包含的状态数据,如何能把一个用户的状态数据关联起来呢? 比如在淘宝的某个 ...
- 易企CMS主要模板文件介绍
article.tpl 文章内容页模板 catalog.tpl 文章,产品目录页模板 category.tpl 分类页模板 comment.tpl 留言页模板 footer.tpl 页尾模板 head ...
- windows和linux无法访问VMware中linux的tomcat主页问题
1.一定确定自己的tomcat服务器是启动的.(为了确保保险可以在测试前重新shutdown,startup一次) 2.确定自己访问的ip地址和端口号是正确的 如果是VMware外部windows的话 ...
- 【Linux】计划任务管理crontab、at
一.计划任务管理 —— crontab 1. crontab 命令 • 按照预先设置的时间周期(分钟.小时.天…… )重复执行用户指定的命令操作,属于周期性计划任务,默认打开“/var/spool/ ...
- AI不与人为敌
业界广为流传着一句话:有多少人工就有多少智能. 其实还应该有一句话:有多少付出就因该有多少回报.公正是世界永恒的话题. 一.人工智能还是人工愚蠢 科技从来没有善恶,也不会杀人,愚蠢的人比聪明的人做的错 ...
- python sqlalthemy 总结
orm 数据状态的预知识 瞬时状态:刚创建的对象还没有被Session持久化.缓存中不存在这个对象的数据并且数据库中没有这个对象对应的数据为瞬时状态这个时候是没有OID. 持久状态:对象经过Sessi ...
- HttpRunnerManager 搭建使用方法
HttpRunnerManager Design Philosophy 基于HttpRunner的接口自动化测试平台: HttpRunner, djcelery and Django_. HttpRu ...
- appium的python异常处理
from appium import webdriver from selenium.common.exceptions import NoSuchElementException desired_ ...
- vue.js层叠轮播
最近写公司项目有涉及到轮播banner,一般的ui框架无法满足产品需求:所以自己写了一个层叠式轮播组件:现在分享给大家: 主要技术栈是vue.js ;javascript;jquery:确定实现思路因 ...
- d正则表达式相关
控件看Delphi正则表达式使用方法(TPerlRegEx)的介绍: 使用正则表达式获取Sql查询语句各项(表名.字段.条件.排序) 希望在线测试正则表达式 在线正则表达式测试 有许多常规表达式 希 ...