ホームページ  >  記事  >  バックエンド開発  >  golangのプロセスが勝手に消えてしまう

golangのプロセスが勝手に消えてしまう

PHPz
PHPzオリジナル
2023-05-10 10:14:06799ブラウズ

最近、Golang で書かれたプログラムで非常に奇妙な問題に遭遇しました。つまり、プロセスが自動的に消えてしまいます。いくつかのトラブルシューティングを行った後、問題を見つけたので、いくつかの経験をまとめました。以下に私が遭遇した問題と解決策を共有しましょう。

問題の説明

当社の製品は毎日定期的にタスクを実行していますが、ここ数日、タスクが常に数分後に停止することがわかり、プロセスのログ出力を設定しました。をファイルに書き込み、ログを確認したところ、プロセスは数分間だけ実行され、その後自然に消えたことがわかりました。通常の開発やテストでは同様の問題に遭遇したことがないため、この状況は非常に奇妙です。

トラブルシューティングのプロセス

まず、最も簡単な解決策を考えました。それは、コードにデバッグ情報を追加することでした。そこで、プロセスを開始したときに start のログを出力し、その後、重要な操作を実行するたびに、対応するログを出力しました。そこでタスクを再起動し、停止するのを待ってログを確認したところ、プロセスは開始から数分で停止しましたが、ログにはエラーメッセージは出力されず、終了したようでした。自体。

次に、strace コマンドを使用してプロセスのシステム コールをトレースし、プロセスが終了した理由を確認してみました。ただし、このプロセスの構造は比較的複雑で、複数のゴルーチンが実行されます。 strace コマンドを使用してゴルーチンの 1 つ (ndeliver) をトレースし、そのシステム コールを確認しました。 ndeliver goroutine の関連コードは次のとおりです。

c := make(chan os.Signal, 1)

signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)

go func() {
    sig := <-c
    log.Errorf("main: received signal %s, shutting down server", sig.String())
    server.Stop()
    os.Exit(0)
}()

go func() {
    err := server.Start()
    if err != nil {
        log.Fatalf("ndeliver: server start error: %s", err)
    }
}()

このコードの機能は、プロセスの信号処理関数を登録し、ゴルーチンを開始して server.Start を実行することです。 () 関数。この関数はプロセスが終了するまでブロックされます。

strace コマンドにより、このゴルーチンには例外がなく、エラーが発生することなく終了したことがわかりました。しかし、プロセス中に他のゴルーチンがあることがわかりました。引き続き strace コマンドを使用してゴルーチンの 1 つをトレースしました。その後、問題が見つかりました。ゴルーチンがパニックを発生させ、そのパニックが処理されないため、プロセス全体がクラッシュします。

解決策

コードを確認すると、このパニックはファイルの削除が原因であることがわかりましたが、コードではこのエラーが処理されませんでした。 goroutine パニックが処理されない場合、プロセス全体がクラッシュするため、プロセスが自動的に消滅します。

この問題を解決するには、パニックを処理してプロセス全体のクラッシュを防ぐ必要があります。必要に応じて回復関数を使用してパニックをキャプチャし、それを処理してプロセスのクラッシュを回避できます。

以下はパニックを処理するためのコード例です:

defer func() {
    if r := recover(); r != nil {
        log.Errorf("goroutine panic: %v", r)
        // TODO: 处理 panic
    }
}()

// 代码片段

defer 関数を使用すると、ゴルーチンが終了すると、たとえパニックが発生したとしても、それをキャプチャしてそれに応じて処理できます。単にパニック情報を出力するだけですが、実際には、アラートの送信やエラーに関する詳細情報のログ記録など、他の処理をここで実行することもできます。

概要

Golang コードを作成する場合、ゴルーチンの特殊な性質により、ゴルーチンがパニックになると、プロセス全体がクラッシュする可能性があります。したがって、コードを記述するときは、この状況を考慮して、この状況に対処するコードを記述する必要があります。コードにパニック処理を追加することは非常に重要です。これは、運用環境での同様の問題を回避するのに役立ちます。

以上がgolangのプロセスが勝手に消えてしまうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。