网游运维管理系统

经历过网络游戏运营的朋友都应该体会过,服务器集群的管理不是一件容易的事,特别是服务器/进程的数量变得
越来越多的时候.我上一个运营的游戏,最开始并没有把服务器管理考虑在里面,开服的时候远程到物理机器上一个
个进程的启动/重启把我给折腾坏了。后来制作了一个管理工具,可以直接通过一个客户端去操作进程了。但那套系
统做得并不完善使用也不太方便.

本文的主要内容是介绍我为Survive轻型网游服务器设计的运维系统.

设计的时候我最初考虑的前端应该如何做:

  • 使用web前端,好处是只要用能上网的手就能连上运维系统,随时随地都能监控和管理。

  • 使用传统的客户端,命令行或界面都可以.跟第一种比我没想到有任何好处,而且如果想在手机上监控还需要单独做
    个手机的app.可是,对web服务器和前端我没有任何经验,为了开发速度,我还是选择了使用传统客户端.

下面介绍下管理系统的总体结构:

router

router主要的作用就是消息路由,在整个服务器集群中唯一配置.默认监听0.0.0.0:8888.

daemonserver

物理机器上启动的守护进程,负责进程的启动/关闭,供运维客户端连接以进行维护操作,供gm工具连接以执行
某些gm操作.daemonserver默认监听0.0.0.0:8889.daemonserver在启动之后就会尝试与router建立连接.

下面将介绍整个运维系统的核心

中心数据库

为了让router和daemonserver可以在意外终止之后安全重启而不丢失任何配置和应用进程的信息.这套系统
使用一个中心数据库管理这些信息.这个中心数据库使用(redis/ssdb)这样的nosql数据库(被命名为globaldb)

假如一个服务器集群上运行着3个游戏世界,分别命名为世界1,世界2,世界3.

那么globaldb中就有3个key,分别为世界1,世界2,世界3.而对应的value是一个hash表.这个hash表中的每个key是
机器的内网ip,value是机器上部署的应用进程.

例如世界1部署在两台机器192.168.1.10和192.168.1.11上.下面举例一个合法的value值.(注:value中存储的是
lua table转化的json字符串,下图为了方便直接以lua table展示)

    key=192.168.1.10
    value = {   {type="gateserver",name="gate1",host="211.128.130.2",port=8010,agentcount=4},
                      {type="gameserver",name="game1",host="192.168.1.10",port = 8011},
                      {type="groupserver",name="groupserver",host="192.168.1.10",port = 8014},
                      {type="chatserver",name="chatserver",host="192.168.1.10",port=8015}}
            
    key=192.168.1.11
    value = {   {type="gateserver",name="gate1",host="211.128.130.2",port=8010,agentcount=4},
                      {type="gameserver",name="game1",host="192.168.1.10",port = 8011}}

router启动之后就会连上globaldb索取这个全局配置表,并把合法的机器ip分离记录下来,当daemonserver连接router
的时候,根据ip表判断是接受还是拒绝连接.

全局表的作用是配置一台物理机器上可以启动的进程,那么如果判断一个进程是否工存活,进程产生的统计信息又如何
处理.

  • 一种方式是daemonserver fork子进程并监听子进程的终止信号.
  • 另一种方式是子进程启动之后反连daemonserver,daemonserver根据连接的存活来判断进程的存活.

但是以上两种方式无法避免一个问题,就是如果daemonserver意外终止.将丢失所有的信息.

所以我在globaldb建了另外一个key,process.process的value也是一个hash表.其中的key是有下形式,
world名.ip.name,例如世界1,191.168.1.11上的game1,其key为[世界1.191.168.1.11上.game1],
对应的value有4个字段[info][pid][lastupdate][startcount].

当进程启动之后,就以固定的频率去刷新这个表,[lastupdate]记录最近的刷新时间.如果最新刷新时间距离当前时间差距
过大,则进程可能已经消失或者进入死循环.

运维客户端

运维客户端可以连接任意一个有外网ip的daemonserver.用户合法性及权限配置在[globaldb][user]中.

基本命令如下:

list world:显示有所区

list worldname ip:显示区worldname下ip机器的进程信息

list ip pid:显示ip机器上pid进程的详细信息 

start worldname ip all:启动区worldname下ip机器的所有应用进程

start worldname ip name:启动区worldname下ip机器name进程

stop worldname ip all:关闭区worldname下ip机器的所有应用进程

stop worldname ip name:关闭区worldname下ip机器name进程

kill ip pid:强杀ip机器上的pid进程.

当请求操作的进程不在当前登陆daemonserver上时,消息通过router路由到目标机器所在daemonserver上执行.

posted @ 2014-08-13 14:38  sniperHW  阅读(1269)  评论(0编辑  收藏  举报