假设IO处理不好。server在IO时会导致。游戏卡顿较长的时间,严重影响游戏体验。
近期服务端刚好对IO这一块做了优化,把优化过程记录一下。
当时是在每一个场景对象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]; }
function onTick(){ for (var uid in users) { var user = users[uid]; DBMgr.write(user); } }
玩家离线后。先将其数据移到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之中还是会有非常多玩具须要写入。
假设玩家下线。就将其下次存盘时间在变为对应的负数,来标记玩家已经下线。
在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; } } };
这种结构定时存盘一批玩家数据,即使玩家离线也能够在内存中保存一段时间。
眼下我们的服务端存盘机制就是这种,假设以后有优化再补充。
原文:http://www.cnblogs.com/wzjhoutai/p/6940512.html