Node.js テクノロジの継続的な開発と応用により、Web サーバー構築のアプリケーションはますます広く普及しています。開発プロセス中に、サーバーをシャットダウンするという要件が頻繁に発生します。では、Node.js アプリケーションでサーバーを正確かつ適切にシャットダウンするにはどうすればよいでしょうか?この記事では、Node.js を使用してサーバーを正常にシャットダウンできるアプリケーションを構築する方法について詳しく説明します。
1. Node.js サーバーの起動とシャットダウン
Node.js では、サーバーの起動は非常に簡単で、組み込みの http モジュールを使用するだけです。例:
const http = require('http'); const server = http.createServer((req, res) => { res.end('Hello World!'); }); server.listen(3000, () => { console.log('Server is running on port 3000'); });
上記のコードは、HTTP サーバーを作成し、ポート 3000 にバインドします。もちろん、Express などのフレームワークを使用して Web サーバーを作成することもできます。ただし、どのフレームワークを使用しても、サーバーをシャットダウンする方法は基本的に同じです。
サーバーをシャットダウンする必要がある場合は、次の 2 つの方法のいずれかを使用できます。
1. Ctrl C を使用してプロセスを強制終了する
コマンド ラインを使用して Node.js アプリケーションを開始する場合、Ctrl C キーの組み合わせを押すことでプロセスを終了できます。この方法はシンプルで高速ですが、洗練されておらず、必要なクリーンアップ作業が実行されないため、問題が発生する可能性があります。
2. SIGINT シグナルをリッスンしてサーバーをシャットダウンする
Node.js では、シグナル イベントをリッスンし、イベントの発生時にいくつかの操作を実行できます。 SIGINT シグナル イベントをリッスンすることでサーバーを正常にシャットダウンし、リソースの解放や状態の保存などの必要な操作を実行できます。以下はサンプルコードです:
const http = require('http'); const server = http.createServer((req, res) => { res.end('Hello World!'); }); server.listen(3000, () => { console.log('Server is running on port 3000'); }); process.on('SIGINT', () => { console.log('Received SIGINT signal, shutting down server...'); server.close(() => { console.log('Server has been shut down.'); process.exit(); }); });
上記のコードでは、プロセス オブジェクトを通じて SIGINT シグナルをリッスンし、シグナルがトリガーされると、ログ情報が出力され、Web サーバーが正常にシャットダウンされます。コード内のserver.close()メソッドは、サーバーを停止し、すべての接続が切断された後にコールバック関数を実行できます。コールバック関数では、サーバーのシャットダウンに関する情報を出力し、process.exit() メソッドを使用してプロセスを終了します。
実際の使用では、データベースへの状態の保存、通知メールの送信など、追加の操作を実行する必要がある場合があることに注意してください。これらの操作をコールバック関数に配置すると、サーバーのシャットダウン時に確実に実行されます。
2. Node.js サーバーの正常なシャットダウン
上記の例では、サーバーのシャットダウンの基本プロセスが完了しました。ただし、実際のアプリケーションでは、サーバーをより適切にシャットダウンするために、いくつかの最適化が必要になる場合があります。
1. リクエスト処理のタイムアウト
Web サーバーがリクエストを処理しているときに、リクエストに時間がかかりすぎると、サーバーが適切にシャットダウンしない可能性があります。したがって、サーバーをシャットダウンする前に、すべてのリクエストの処理を停止するか、リクエストのタイムアウトを設定して、タイムアウト内に処理が完了するようにする必要があります。
const http = require('http'); const server = http.createServer((req, res) => { res.end('Hello World!'); }); server.listen(3000, () => { console.log('Server is running on port 3000'); }); let connections = []; server.on('connection', (connection) => { connections.push(connection); connection.on('close', () => { const index = connections.indexOf(connection); if (index !== -1) { connections.splice(index, 1); } }); }); function closeConnections() { console.log('Closing all connections...'); connections.forEach((connection) => { connection.end(); }); setTimeout(() => { connections.forEach((connection) => { connection.destroy(); }); server.close(() => { console.log('Server has been shut down.'); process.exit(); }); }, 10000); } process.on('SIGINT', () => { console.log('Received SIGINT signal, shutting down server...'); closeConnections(); });
2. 未完了のリクエストの処理
Web サーバーがリクエストを処理するとき、ファイルの読み取り、データベースのクエリなどの複数の操作が含まれる場合があります。サーバーがシャットダウンされる前にこれらの操作が完了しないと、データの損失、接続の中断、その他の問題が発生する可能性があります。したがって、サーバーをシャットダウンする前に、すべての操作が完了していることを確認する必要があります。たとえば、ファイルの読み取りを処理するには Promise を使用します。
const http = require('http'); const fs = require('fs').promises; const server = http.createServer((req, res) => { fs.readFile('./index.html') .then((data) => { res.end(data); }) .catch((err) => { console.error(err); res.statusCode = 500; res.end('Internal server error'); }); }); server.listen(3000, () => { console.log('Server is running on port 3000'); }); let connections = []; server.on('connection', (connection) => { connections.push(connection); connection.on('close', () => { const index = connections.indexOf(connection); if (index !== -1) { connections.splice(index, 1); } }); }); function closeConnections() { console.log('Closing all connections...'); connections.forEach((connection) => { connection.end(); }); setTimeout(() => { connections.forEach((connection) => { connection.destroy(); }); server.close(() => { console.log('Server has been shut down.'); process.exit(); }); }, 10000); } process.on('SIGINT', () => { console.log('Received SIGINT signal, shutting down server...'); // 进行必要的清理工作 console.log('Cleaning up...'); fs.unlink('./index.html') .then(() => { console.log('File has been deleted.'); }) .catch((err) => { console.error(err); }); // 关闭所有连接 closeConnections(); });
上記のコードでは、Promise を使用してファイルを読み取り、サーバーを閉じる前にファイルが正しく削除されたことを確認します。サーバーをシャットダウンする前に、すべての接続も閉じ、10 秒後にすべての接続とサーバーを強制的に閉じました。実際の使用では、必要に応じて異なるタイムアウトを設定できます。
3. 概要
Node.js アプリケーションでは、Web サーバーをシャットダウンすることが一般的な要件です。この記事では、組み込みの http モジュールを使用して Web サーバーを作成し、SIGINT 信号をリッスンしてサーバーを正常にシャットダウンする方法について説明します。同時に、さまざまな状況下でサーバーを正常にシャットダウンできるように、サーバーをシャットダウンするプロセスを最適化する方法も紹介しました。実際のアプリケーションでは、さまざまなニーズに合わせて必要に応じて適切に拡張および最適化できます。
以上がnodejsのサーバーを閉じる関数の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。