Skip to content

可擴展性

Colyseus 如何實現可擴展性?

  • 增加處理器數量可以讓系統創建更多的房間.
  • 房間在多處理器之間平均分配.
  • 每個處理器的使用情況儲存在 Redis 數據庫中.
  • 每個房間隸屬於一個 Colyseus 進程.
    • 每個房間有其可承載的 最大玩家數量.
    • 每個房間的最大玩家數量由多種因素決定. 參考常見問題.
  • 每個客戶端連接隸屬於一個進程.
    • 使用 proxy 方案時, 客戶端與服務器的交流由代理程序負責.
    • 使用 direct 方案時, 客戶端與服務器的交流直接完成.

配置共享 PresenceDriver

首先, 下載並安裝 Redis.

import { Server } from "colyseus";
import { RedisPresence } from "@colyseus/redis-presence";
import { RedisDriver } from "@colyseus/redis-driver";

const gameServer = new Server({
  // ...
  presence: new RedisPresence(),
  driver: new RedisDriver(),
});
const colyseus = require("colyseus");
const { RedisPresence } = require("@colyseus/redis-presence");
const { RedisDriver } = require("@colyseus/redis-driver");

const gameServer = new colyseus.Server({
  // ...
  presence: new colyseus.RedisPresence(),
  driver: new colyseus.RedisDriver(),
});

其中 presence 用於進程間調用房間的 "seat reservation" 功能, 還用於讓開發者可以在房間之間共享數據. 詳情請參閱 Presence API.

其中 driver 表示可用房間的共享緩存, 以及實現 Colyseus 進程的房間檢索功能.

每個 Colyseus 進程還會用 presence API 註冊自身的 processId 和網絡位置, 以便使用 動態代理 服務. 優雅關閉時, 進程會自我註銷.

方案 1: 使用動態代理

安裝好 @colyseus/proxy.

npm install --save @colyseus/proxy

動態代理自動監聽 Colyseus 進程的運行情況. 可以把客戶端請求路由到正確的 Colyseus 進程中.

所有客戶端請求必須經由代理進入. 這種方案下, 客戶端捕魚服務器 直接 交流, 而是通過代理完成.

生產環境下, 代理需要綁定端口 80 / 443.

環境變量

根據需要配置下列環境變量:

  • PORT 代理綁定的端口號.
  • REDIS_URL 配合 Colyseus 進程運行的 Redis 實例路徑.

啟動代理

npx colyseus-proxy

> {"name":"redbird","hostname":"Endels-MacBook-Air.local","pid":33390,"level":30,"msg":"Started a Redbird reverse proxy server on port 80","time":"2019-08-20T15:26:19.605Z","v":0}

方案 2: 不使用代理

註意

該方案是試驗性的.

另一種選擇, 可以配置每個 Colyseus 進程使用自己的公開地址, 以便客戶端直接與之通信.

const server = new Server({
    // ...
    presence: new RedisPresence(),
    driver: new RedisDriver(),

    // 每個進程一個唯一公開地址
    publicAddress: "server-1.yourdomain.com"
});

理想情況下, 應該有一個負責載入均衡的程序來處理所有的 Colyseus 進程 - 而這個程序應作為所有客戶端的連接入口.

運行多個 Colyseus 進程

想要在一個服務器中運行多個 Colyseus 實例, 您需要讓每個實例監聽不同的端口號. 推薦使用 3001, 3002, 3003 這樣的端口. Colyseus 進程 不應 對外公開, 而應該只公開 動態代理.

強烈推薦使用 PM2 process manager 管理多個 Node.js 應用實例.

PM2 提供名為 NODE_APP_INSTANCE 的環境變量, 對於每個進程這個變量數字是唯一的, 可以用其界定端口號.

import { Server } from "colyseus";

// 給每個實例綁定各不相同的端口號.
const PORT = Number(process.env.PORT) + Number(process.env.NODE_APP_INSTANCE);

const gameServer = new Server({ /* ... */ })

gameServer.listen(PORT);
console.log("Listening on", PORT);
npm install -g pm2

使用如下 ecosystem.config.js 配置:

// ecosystem.config.js
const os = require('os');
module.exports = {
    apps: [{
        port        : 3000,
        name        : "colyseus",
        script      : "lib/index.js", // 主入口頁面
        watch       : true,           // 可選
        instances   : os.cpus().length,
        exec_mode   : 'fork',         // 註意: 不要使用 cluster 模式.
        env: {
            DEBUG: "colyseus:errors",
            NODE_ENV: "production",
        }
    }]
}

現在您就可以開啟多個 Colyseus 進程了.

pm2 start

PM2 和 TypeScript

建議在運行 pm2 start 之前, 使用 npx tsc 編譯 .ts 文件. 或者您可以為 PM2 安裝 TypeScript 解釋器 (pm2 install typescript) 並設置 exec_interpreter: "ts-node" (更多參考).

Back to top