PM2での利用
PM2は、Node.jsアプリケーション向けの、ロードバランサーが内蔵された本番環境向けプロセス管理ツールです。アプリケーションを常に稼働させ、ダウンタイムなしで再読み込みを行い、一般的なシステム管理タスクを容易にすることができます。
ドキュメントはこちらで確認できます:https://pm2.dokyumento.jp/docs/usage/pm2-doc-single-page/
PM2でSocket.IOサーバーをスケールするには、3つの解決策があります。
- クライアント側でHTTPロングポーリングを無効にする
const socket = io({
transports: ["websocket"]
});
ただし、その場合、WebSocket接続を確立できないとHTTPロングポーリングへのフォールバックは行われません。
ワーカーごとに異なるポートを使用し、それらの前にnginxのようなロードバランサーを配置する
@socket.io/pm2
を使用する
インストール
npm install -g @socket.io/pm2
pm2
がすでにインストールされている場合は、まず削除する必要があります
npm remove -g pm2
@socket.io/pm2
はpm2
の代替としてそのまま使用でき、クラスpm2
ユーティリティのすべてのコマンドをサポートしています。
唯一の違いは、このコミットによるものです。
使用方法
worker.js
const { createServer } = require("http");
const { Server } = require("socket.io");
const { createAdapter } = require("@socket.io/cluster-adapter");
const { setupWorker } = require("@socket.io/sticky");
const httpServer = createServer();
const io = new Server(httpServer);
io.adapter(createAdapter());
setupWorker(io);
io.on("connection", (socket) => {
console.log(`connect ${socket.id}`);
});
ecosystem.config.js
module.exports = {
apps : [{
script : "worker.js",
instances : "max",
exec_mode : "cluster"
}]
}
次に、pm2 start ecosystem.config.js
(またはpm2 start worker.js -i 0
)を実行します。 これだけです! ポート8080でSocket.IOクラスターにアクセスできるようになりました。
仕組み
複数のノードにスケールする場合、2つのことを行う必要があります。
- スティッキーセッションを有効にして、Socket.IOセッションのHTTPリクエストが同じワーカーにルーティングされるようにする
- カスタムアダプターを使用し、他のワーカーに接続されている場合でも、パケットがすべてのクライアントにブロードキャストされるようにする
これを実現するために、@socket.io/pm2
には2つの追加パッケージが含まれています。
pm2
との唯一の違いは、このコミットによるものです。
- Godプロセスは独自のHTTPサーバーを作成し、HTTPリクエストを適切なワーカーにルーティングします。
- Godプロセスは、
io.emit()
がすべてのクライアントに正しく到達するように、ワーカー間でパケットをリレーします。
複数のホストでそれぞれPM2クラスターを実行している場合は、Redisアダプターなどの別のアダプターを使用する必要があることに注意してください。
フォークのソースコードはこちらにあります。 pm2
パッケージのリリースに密接に従うように努めます。