请问这种游戏服务器架构是否可行?目的是想要尽量提升单服可容纳玩家量。

StaticM

[attach]708[/attach]
看了http://wenda.workerman.net/?/question/358
http://wenda.workerman.net/?/question/1242
这两个关于处理繁重任务和游戏服务器架构问题的问答。设想出如上图中的游戏服务器大概架构。
用gamecenter一个单进程来维持客户端连接和给任务处理进程 分配任务以及接受结果后发送给客户端。把随机掉落,战斗,AI等CPU开销高的任务独立出来,根据需求开N个worker通过AsyncTcpConnection异步来处理。

这样设计主要是想在单台服务器承载不了的时候可以把掉落,战斗,AI一类的高负载任务独立到其它服务器来分布式处理从而提高单服玩家容量。

现在有3个问题不太明白:
1.假设我随机掉落由10个worker组成,AsyncTcpConnection能够自动根据worker的负载把任务合理的分配给这10个worker处理吗?还是需要我自己来分配?如果是应该怎么做呢?
2.使用AsyncTcpConnection来连接使用任务处理进程合理吗?是否使用或者结合Channel组件更好?
3.这样设计,进程间通讯会十分频繁,会不会反而得不偿失呢?

不知道这种架构是否可行,请walkor老大和各位大神指点。

4029 2 1
2个回答

walkor

1、gameCenter进程可以再开一个内部端口,随机掉落worker的所有进程可以主动去连gameCenter,这样gameCenter和所有worker进程都保持一个长连接,这样就可以将某个请求按照自己的某种算法转发给某个worker处理,然后异步等待结果。
2、我觉得很合理,也简单些
3、简单的计算可以直接在gameCenter完成,阻塞类或者cpu消耗非常大的计算放到worker进程。如果处理任务的消耗远大于进程间通讯消耗那么就很划算

另外这种架构可以部署多套,类似多个区。那么人数再多只要分区就行了。

  • StaticM 2017-07-31

    非常感谢,请问walkor大神,您1里面所建议的做法是像我下面贴的代码这样做吗?我在win上面运行成功。还有请问GameCenter和任务处理Worker(例如随机装备掉落)之间分布式部署时需要加心跳吗?

  • walkor 2017-08-01

    是的,就是类似这样。服务器间长连接最好有心跳

  • StaticM 2017-08-02

    好的,非常感谢~

StaticM

GameCenter.php

$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 启动1个进程对外提供服务
$ws_worker->count = 1;
//用于指定当前任务分配给哪个任务worker
$current_lootWorker=0;
//新增一个属性用于保存掉落产生任务worker
$ws_worker->lootWorkerList = array();

$ws_worker->onWorkerStart=function ($ws_worker)
{
//建立一个内部端口
    $loot_spawn_worker = new Worker('Text://0.0.0.0:5678');

    $loot_spawn_worker->onConnect = function($connection)
    {
       //当loot worker连接时将其保存起来
        global $ws_worker;
        array_push($ws_worker->lootWorkerList,$connection);
        echo count($ws_worker->lootWorkerList);
    };

    $loot_spawn_worker->onMessage = function($connection, $data)
    {
        //收到掉落worker的处理结果并向客户端发送结果
    };
    $loot_spawn_worker->listen();
};
// 新增加一个属性,用来保存uid到connection的映射
$ws_worker->uidConnections = array();
//得到客户端掉落生成请求后,根据自定义逻辑向掉落任务进程分配任务
$ws_worker->onMessage = function($connection, $data)
{
//.....用户登录分配uid
//.....任务分发逻辑
$ws_worker->lootWorkerList->send('请求信息');//向掉落处理worker发送数据
};

// 运行worker
Worker::runAll();

物品随机掉落Worker

$ws_worker = new Worker("websocket://0.0.0.0:2347");
// 启动4个进程对外提供服务
$ws_worker->count = 4;
//异步主动连接GameCenter
$gameCenter_connection = new AsyncTcpConnection('Text://127.0.0.1:5678');
$ws_worker->onWorkerStart=function($ws_worker)
{
    //连接GameCenter进程
    global $gameCenter_connection;
    $gameCenter_connection->connect();

};

$gameCenter_connection->onMessage = function($ws_connection, $data)
{
    global $gameCenter_connection;
            #
            #掉落生成逻辑
            #
            //向GameCenter返回掉落结果
            $gameCenter_connection->send(‘装备信息’);
    }
};

Worker::runAll();
  • 暂无评论
年代过于久远,无法发表回答
🔝