Node.js プロセスをアクティブに終了するためのいくつかの方法の詳細な説明

青灯夜游
リリース: 2021-04-27 09:14:31
転載
5988 人が閲覧しました

この記事では、Node プロセスの終了をアクティブにトリガーするいくつかの方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

Node.js プロセスをアクティブに終了するためのいくつかの方法の詳細な説明

#Node.js プロセスが終了する理由はいくつかあります。これらの中には、エラーがスローされた場合など、回避可能なものもありますが、メモリ不足など、回避できないものもあります。グローバル process は、実行が正常に終了したときに exit イベントを発行するイベント エミッター インスタンスです。プログラム コードは、このイベントをリッスンすることで、最終的な同期クリーンアップ作業を実行できます。

関連する推奨事項: 「nodejs チュートリアル

プロセス終了をアクティブにトリガーできるいくつかのメソッドを次に示します:

# #操作例手動プロセス終了キャッチされない例外未達成の約束無視されたエラー イベント未処理のシグナル

それらの多くは、キャッチされなかったエラーや未処理の Promise など、誤ってトリガーされますが、プロセスを直接終了するために作成されるものもあります。

プロセスの終了

process.exit(code) を使用するのが、プロセスを終了する最も直接的な方法です。これは、プロセスがライフサイクルの終わりに達したことがわかっている場合に役立ちます。 code 値はオプションで、デフォルト値は 0 で、最大値は 255 に設定できます。0 はプロセスが正常に実行されたことを示し、ゼロ以外の数値は問題が発生したことを示します。これらの値は、さまざまな外部ツールで使用できます。たとえば、テスト スイートを実行すると、ゼロ以外の値はテストが失敗したことを示します。

process.exit() を直接呼び出す場合、暗黙的なテキストはコンソールに書き込まれません。エラー表現を使用してこのメ​​ソッドを呼び出すコードを作成する場合、コードはユーザーにエラーを出力して、問題の解決に役立てる必要があります。たとえば、次のコードを実行します。

$ node -e "process.exit(42)"
$ echo $?
ログイン後にコピー

この場合、シェル プログラムは終了ステータスを出力しますが、単一行の Node.js プログラムは情報を出力しません。このようなプロセスの終了に遭遇すると、ユーザーは何が起こったのか理解できなくなります。したがって、プログラムが正しく構成されていない場合に実行される次のコードを参照してください。

function checkConfig(config) {
  if (!config.host) {
    console.error("Configuration is missing 'host' parameter!");
    process.exit(1);
  }
}
ログイン後にコピー

この場合、ユーザーは何が起こったのか明確に理解できません。彼らはプログラムを実行し、エラーをコンソールに出力し、問題を修正することができます。

process.exit() このメソッドは非常に強力です。プログラム コード内で独自の用途がありますが、再利用可能なライブラリには決して導入しないでください。ライブラリでエラーが発生した場合は、プログラムがその処理方法を決定できるように、このエラーをスローする必要があります。

例外、拒否、およびエラーの発行

process.exit() は便利ですが、実行時エラーの場合は別のツールを使用する必要があります。たとえば、プログラムが HTTP リクエストを処理している場合、通常、エラーによってプロセスが終了するのではなく、エラー応答のみを返す必要があります。エラーが発生した場所、つまり Error オブジェクトがスローされる場所を知ることも役立ちます。

Error クラスのインスタンスには、スタック トレース情報やメッセージ文字列など、エラーの原因に関する有用なメタデータが含まれています。独自のエラー クラスを Error から拡張するのが一般的です。 Error をインスタンス化するだけでは多くの副作用は発生しないため、エラーが発生した場合はスローする必要があります。

Error は、throw キーワードが使用された場合、または特定のロジック エラーが発生した場合にスローされます。これが発生すると、現在のスタックが「アンロール」されます。つまり、呼び出し関数が呼び出しを try/catch ステートメントでラップするまで、すべての関数が終了します。このステートメントが見つかった後、catch ブランチが呼び出されます。エラーが try/catch に含まれていない場合、エラーは捕捉されなかったとみなされます。

技術的には、throw new Error('foo') Talk など、Error とともに throw キーワードを使用する必要がありますが、スローすることもできます。何でも。何かがスローされると、それは例外とみなされます。これらのエラーをキャッチするコードはおそらく error 属性を期待するため、Error インスタンスをスローすることが重要です。

Node.js 内部ライブラリで一般的に使用されるもう 1 つのパターンは、リリース間で変更される文字列値である .code プロパティを提供することです。一貫性がある必要があります。たとえば、間違った .code 値は ERR_INVALID_URI です。人間が判読できる .message 属性は変更される可能性がありますが、この code値も変更しないでください。

残念ながら、エラーを区別するためのより一般的なパターンは、.message プロパティをチェックすることです。これは、スペル ミスを修正する必要があるため、通常は動的です。この方法は非常に危険であり、間違いが発生しやすくなります。 Node.js エコシステムには、すべてのライブラリのバグを区別するための完璧なソリューションはありません。

捕捉されなかったエラーがスローされると、スタック トレースがコンソールに出力され、プロセスは終了ステータス 1 で終了します。そのような例外の例を次に示します。

/tmp/foo.js:1
throw new TypeError('invalid foo');
^
Error: invalid foo
    at Object.<anonymous> (/tmp/foo.js:2:11)
    ... TRUNCATED ...
    at internal/main/run_main_module.js:17:47
ログイン後にコピー

上記のスタック トレース スニペットは、foo.js という名前のファイルの 2 行目、11 列目でエラーが発生したことを示しています。

グローバル process は、uncaughtException イベントをリッスンすることで、捕捉されなかったエラーをインターセプトできるイベント エミッターです。これを使用して、終了して非同期メッセージを送信する前にエラーをインターセプトする例を次に示します。

const logger = require(&#39;./lib/logger.js&#39;);
process.on(&#39;uncaughtException&#39;, (error) => {
  logger.send("An uncaught exception has occured", error, () => {
    console.error(error);
    process.exit(1);
  });
});
ログイン後にコピー

Promise の拒否は、エラーをスローすることと非常によく似ています。 Promise の reject() メソッドが呼び出された場合、または非同期関数でエラーが発生した場合、Promise は拒否される可能性があります。この点に関して、次の 2 つの例はほぼ同じです:

Promise.reject(new Error(&#39;oh no&#39;));

(async () => {
  throw new Error(&#39;oh no&#39;);
})();
ログイン後にコピー

これはコンソールに出力されるメッセージです:

(node:52298) UnhandledPromiseRejectionWarning: Error: oh no
    at Object.<anonymous> (/tmp/reject.js:1:16)
    ... TRUNCATED ...
    at internal/main/run_main_module.js:17:47
(node:52298) UnhandledPromiseRejectionWarning: Unhandled promise
  rejection. This error originated either by throwing inside of an
  async function without a catch block, or by rejecting a promise
  which was not handled with .catch().
ログイン後にコピー

Node.js v14 以降では、キャッチされない例外とは異なり、これらの拒否はプロセスをクラッシュさせないでください。 Node.js の将来のバージョンでは、これにより現在のプロセスがクラッシュします。また、これらの未処理の拒否が発生したときにイベントをインターセプトし、process オブジェクトで別のイベントをリッスンすることもできます。

process.on(&#39;unhandledRejection&#39;, (reason, promise) => {});
ログイン後にコピー

事件发射器是 Node.js 中的常见模式,许多对象实例都从这个基类扩展而来,并在库和程序中使用。它们非常欢迎,值得和 error 与 rejection 放在一起讨论。

当事件发射器发出没有侦听器的 error 事件时,将会抛出所发出的参数。然后将抛出出一个错误并导致进程退出:

events.js:306
    throw err; // Unhandled &#39;error&#39; event
    ^
Error [ERR_UNHANDLED_ERROR]: Unhandled error. (undefined)
    at EventEmitter.emit (events.js:304:17)
    at Object.<anonymous> (/tmp/foo.js:1:40)
    ... TRUNCATED ...
    at internal/main/run_main_module.js:17:47 {
  code: &#39;ERR_UNHANDLED_ERROR&#39;,
  context: undefined
}
ログイン後にコピー

确保在你使用的事件发射器实例中侦听 error 事件,以便你的程序可以正常处理事件而不会崩溃。

信号

信号是操作系统提供的机制,用于把用数字表示的消息从一个程序发送到另一个程序。这些数字通常用等价的常量字符串来表示。例如,信号 SIGKILL 代表数字信号 9。信号可以有不同的用途,但通常用于终止程序。

不同的操作系统可以定义不同的信号,但是下面列表中的信号一般是通用的:

process.exit(1)
throw new Error()
Promise.reject()
EventEmitter#emit('error')
$ kill
名称编号可处理Node.js 默认信号用途
SIGHUP1终止父终端已关闭
SIGINT2终止终端试图中断,按下 Ctrl + C
SIGQUIT3终止终端试图退出,按下 Ctrl + D
SIGKILL9终止进程被强行杀死
SIGUSR110启动调试器用户定义的信号1
SIGUSR212终止用户定义的信号2
SIGTERM12终止代表优雅的终止
SIGSTOP19终止进程被强行停止

如果程序可以选择实现信号处理程序,则 Handleable 一列则为。为的两个信号无法处理。 Node.js 默认 这一列告诉你在收到信号时,Node.js 程序的默认操作是什么。最后一个信号用途指出了信号对应的作用。

在 Node.js 程序中处理这些信号可以通过侦听 process 对象上的更多事件来完成:

#!/usr/bin/env node
console.log(`Process ID: ${process.pid}`);
process.on(&#39;SIGHUP&#39;, () => console.log(&#39;Received: SIGHUP&#39;));
process.on(&#39;SIGINT&#39;, () => console.log(&#39;Received: SIGINT&#39;));
setTimeout(() => {}, 5 * 60 * 1000); // keep process alive
ログイン後にコピー

在终端窗口中运行这个程序,然后按 Ctrl + C,这个进程不会被终止。它将会声明已接收到 SIGINT 信号。切换到另一个终端窗口,并根据输出的进程 ID 值执行以下命令:

$ kill -s SIGHUP <PROCESS_ID>
ログイン後にコピー

这演示了一个程序怎样向另一个程序发送信号,并且在第一个终端中运行的 Node.js 程序中输出它所接收到的 SIGHUP 信号。

你可能已经猜到了,Node.js 也能把命令发送到其他程序。可以用下面的命令以把信号从临时的 Node.js 进程发送到你现有的进程:

$ node -e "process.kill(<PROCESS_ID>, &#39;SIGHUP&#39;)"
ログイン後にコピー

这还会在你的第一个程序中显示 SIGHUP 消息。现在,如果你想终止第一个进程,要运行下面的命令向其发送不能处理的 SIGKILL 信号:

$ kill -9 <PROCESS_ID>
ログイン後にコピー

这时程序应该结束。

这些信号在 Node.js 程序中经常用于处理正常的关闭事件。例如,当 Kubernetes Pod 终止时,它将向程序发送 SIGTERM 信号,之后启动 30 秒计时器。然后程序可以在这 30 秒内正常关闭自己,关闭连接并保存数据。如果该进程在此计时器后仍保持活动状态,则 Kubernetes 将向其发送一个 SIGKILL

更多编程相关知识,请访问:编程视频!!

以上がNode.js プロセスをアクティブに終了するためのいくつかの方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート