[attach]708[/attach]
看了http://wenda.workerman.net/?/question/358
http://wenda.workerman.net/?/question/1242
這兩個關(guān)于處理繁重任務(wù)和游戲服務(wù)器架構(gòu)問題的問答。設(shè)想出如上圖中的游戲服務(wù)器大概架構(gòu)。
用gamecenter一個單進程來維持客戶端連接和給任務(wù)處理進程 分配任務(wù)以及接受結(jié)果后發(fā)送給客戶端。把隨機掉落,戰(zhàn)斗,AI等CPU開銷高的任務(wù)獨立出來,根據(jù)需求開N個worker通過AsyncTcpConnection異步來處理。
這樣設(shè)計主要是想在單臺服務(wù)器承載不了的時候可以把掉落,戰(zhàn)斗,AI一類的高負載任務(wù)獨立到其它服務(wù)器來分布式處理從而提高單服玩家容量。
現(xiàn)在有3個問題不太明白:
1.假設(shè)我隨機掉落由10個worker組成,AsyncTcpConnection能夠自動根據(jù)worker的負載把任務(wù)合理的分配給這10個worker處理嗎?還是需要我自己來分配?如果是應(yīng)該怎么做呢?
2.使用AsyncTcpConnection來連接使用任務(wù)處理進程合理嗎?是否使用或者結(jié)合Channel組件更好?
3.這樣設(shè)計,進程間通訊會十分頻繁,會不會反而得不償失呢?
不知道這種架構(gòu)是否可行,請walkor老大和各位大神指點。
1、gameCenter進程可以再開一個內(nèi)部端口,隨機掉落worker的所有進程可以主動去連gameCenter,這樣gameCenter和所有worker進程都保持一個長連接,這樣就可以將某個請求按照自己的某種算法轉(zhuǎn)發(fā)給某個worker處理,然后異步等待結(jié)果。
2、我覺得很合理,也簡單些
3、簡單的計算可以直接在gameCenter完成,阻塞類或者cpu消耗非常大的計算放到worker進程。如果處理任務(wù)的消耗遠大于進程間通訊消耗那么就很劃算
另外這種架構(gòu)可以部署多套,類似多個區(qū)。那么人數(shù)再多只要分區(qū)就行了。
GameCenter.php
$ws_worker = new Worker("websocket://0.0.0.0:2346");
// 啟動1個進程對外提供服務(wù)
$ws_worker->count = 1;
//用于指定當前任務(wù)分配給哪個任務(wù)worker
$current_lootWorker=0;
//新增一個屬性用于保存掉落產(chǎn)生任務(wù)worker
$ws_worker->lootWorkerList = array();
$ws_worker->onWorkerStart=function ($ws_worker)
{
//建立一個內(nèi)部端口
$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的處理結(jié)果并向客戶端發(fā)送結(jié)果
};
$loot_spawn_worker->listen();
};
// 新增加一個屬性,用來保存uid到connection的映射
$ws_worker->uidConnections = array();
//得到客戶端掉落生成請求后,根據(jù)自定義邏輯向掉落任務(wù)進程分配任務(wù)
$ws_worker->onMessage = function($connection, $data)
{
//.....用戶登錄分配uid
//.....任務(wù)分發(fā)邏輯
$ws_worker->lootWorkerList->send('請求信息');//向掉落處理worker發(fā)送數(shù)據(jù)
};
// 運行worker
Worker::runAll();
物品隨機掉落Worker
$ws_worker = new Worker("websocket://0.0.0.0:2347");
// 啟動4個進程對外提供服務(wù)
$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返回掉落結(jié)果
$gameCenter_connection->send(‘裝備信息’);
}
};
Worker::runAll();