服务器系统回写,游戏服务器架构:数据回写

描述

在游戏服务器中,数据回写是指将内存中的数据回写更新到数据库(MongoDB),触发回写的情况通常有两种:

定时回写:每个一段时间将将数据刷新到数据库中

停服回写:在关闭游戏服务器时回写所有数据

设计方案

设计方案如下图,涉及到的接口和类概况:

GameServer:游戏服务器

PlayerService:玩家数据业务

Player:玩家信息 Bean

IFlushTimer:定时回写接口,Bean 类需实现该接口的两个方法

delay():返回定时回写时间

run():执行定时回写操作

DBFlushTimer:定时回写工具类,通过 ScheduledExecutorService 实现定时回写

42e77dd614a9

数据回写

代码案例

定义 IFlushTimer 接口,继承自 Runnable

public interface IFlushTimer extends Runnable {

int delay();

}

Bean 类实现 IFlushTimer 接口的 delay()、run() 方法

public class Player implements IFlushTimer {

private int id;

private String name;

private ScheduledFuture> db_sf = null;

public Player(int id, String name) {

this.id = id;

this.name = name;

}

@Override

public int delay() {

return 5;

}

@Override

public void run() {

this.flush();

}

/**

* 启动定时回写任务

*/

public void startup() {

db_sf = DBFlushTimer.add(this);

}

/**

* 模拟数据库回写

*/

private void flush() {

System.out.println("id:" + this.id + "回写中...");

// 模拟回写操作延迟

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

/**

* 清除定时回写并回写数据

*/

public void clear() {

synchronized (db_sf) {

db_sf.cancel(false);

db_sf = null;

}

runClose();

}

/**

* 回写数据并执行其他操作

*/

public void runClose() {

this.flush();

}

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

编写定时回写工具类 DBFlushTimer,需要注意的是这里使用的是 scheduleWithFixedDelay(...) 方法,ScheduledExecutorService 有两个方法:

scheduleAtFixedRate(...):固定每隔多少秒执行一次任务

scheduleWithFixedDelay(...):当前任务结束的时才开始结算间隔时间,如 0 秒开始执行第一次任务,任务耗时 5 秒,任务间隔时间 3 秒,那么第二次任务执行的时间是在第 8 秒开始

public class DBFlushTimer {

private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

public static ScheduledFuture add(IFlushTimer timer){

ScheduledFuture scheduledFuture = scheduler.scheduleWithFixedDelay(timer,(long)timer.delay(),(long)timer.delay(),TimeUnit.SECONDS);

return scheduledFuture;

}

}

编写业务类 PlayerService

public class PlayerService {

public static final ConcurrentHashMap playerId2Player = new ConcurrentHashMap();

/**

* 开服初始化,模拟从数据库加载玩家信息

*/

public static void init() {

Player p1 = new Player(1, "p1");

Player p2 = new Player(2, "p2");

PlayerService.playerId2Player.put(p1.getId(), p1);

PlayerService.playerId2Player.put(p2.getId(), p2);

// 启动定时回写

p1.startup();

p2.startup();

}

/**

* 停服回写所有数据

*/

public static void flushToDB(){

System.out.println("flush player data to db .....");

for (Player player : playerId2Player.values()){

player.clear();

}

System.out.println("flush tong data end .....");

}

}

编写 GameServer

public class GameServer {

public static void main(String[] args)throws Exception {

init();

TimeUnit.SECONDS.sleep(12);

stop();

}

public static void init(){

System.out.println("init game server .....");

PlayerService.init();

}

// 关服

public static void stop(){

System.out.println("stop game server .....");

PlayerService.flushToDB();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值