ホームページ  >  記事  >  バックエンド開発  >  golang のエレガントなシャットダウン方法について話しましょう

golang のエレガントなシャットダウン方法について話しましょう

PHPz
PHPzオリジナル
2023-04-27 09:11:061205ブラウズ

golang を開発および使用していると、通常、シャットダウンまたは実行の停止が必要な状況に遭遇します。たとえば、プログラムが終了するか例外が発生した場合は、正常にシャットダウンする必要があります。

正常なシャットダウンはプログラムを停止すると同時に、開始されたタスクの処理を許可し、データ損失やリソース漏洩などの問題を回避し、クライアントに不必要な損失を与えません。この記事では、golang の正常なシャットダウン方法について説明します。

優雅なシャットダウン方法

golang では、セマフォやチャネルを設定することで正常なシャットダウンを実装することができます。具体的な実装方法は次のとおりです。 ## セマフォを介して実装

package main

import (
    "log"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    stop := make(chan os.Signal, 1)
    signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

    log.Println("Starting...")

    go func() {
        <-stop
        log.Println("Stopping...")

        // 处理关闭逻辑
        time.Sleep(3 * time.Second)

        log.Println("Graceful shutdown finished")
        os.Exit(0)
    }()

    // 处理业务逻辑
    for {
        log.Println("Running...")
        time.Sleep(1 * time.Second)
    }
}

このコードでは、タイプ os.Signal および長さ 1 のシグナル バッファー チャネルが make によって作成され、シグナル パッケージの Notify 関数を通じてオペレーティング システムに通知されます。監視したい信号は SIGINT と SIGTERM で、どちらもプログラムのシャットダウン要求を表すことができます。

次に、Goroutine を開始し、停止チャネルをリッスンします。SIGINT または SIGTERM シグナルが受信されると、Goroutine の実行がトリガーされます。実行プロセス中にシャットダウン ロジックを処理します。ここで Time.Sleep を使用して、時間のかかる操作をシミュレートし、プログラムが正常に終了するかどうかをより適切にテストします。最後に、os.Exit 関数を通じて、プログラムのシャットダウン要求が処理されたことがオペレーティング システムに通知されます。

メインの goroutine では、ビジネス ロジックを処理し、毎秒 "Running..." を出力します。これは単なる例です。通常、ビジネス ロジックを処理するときは、定期的に保存する必要があります。データやリリースリソースなど。

スルーチャネル

package main

import (
    "log"
    "os"
    "time"
)

func main() {
    done := make(chan bool)

    log.Println("Starting...")

    go func() {
        osSignals := make(chan os.Signal, 1)
        signal.Notify(osSignals, syscall.SIGINT, syscall.SIGTERM)

        select {
        case <-osSignals:
            log.Println("Stopping...")

            // 处理关闭逻辑
            time.Sleep(3 * time.Second)

            log.Println("Graceful shutdown finished")
            done <- true
        }
    }()

    // 处理业务逻辑
    for {
        log.Println("Running...")
        time.Sleep(1 * time.Second)
        select {
        case <-done:
            return // 正常退出
        default:
            continue
        }
    }
}

このコードでは、プログラムが完了したかどうかを示すブール型のdone変数を作成し、メインのゴルーチンでビジネスロジックを処理して定期的に出力します。 「実行中...」と選択機能を使用して完了を聞きます。 Done 変数が true に設定されている場合、プログラムは終了し、main 関数に戻ってプログラムの終了を完了します。

別のゴルーチンでは、make を通じて os.Signal 型、長さ 1 のシグナル バッファー チャネルを作成し、シグナル パッケージの Notify 関数を通じて、どのようなシグナルを監視するかをオペレーティング システムに伝えます。そしてSIGTERM。次に、select 関数を使用して osSignals をリッスンし、SIGINT または SIGTERM シグナルを受信すると、特定の操作がトリガーされます。

プログラムによって監視される信号

Linux システムには、通常、次の信号があります。

信号名 ##SIGINTターミナル割り込み文字。通常はコントロール CSIGTERM ## を通じて発行されます。 # 終了信号。通常、プログラムの実行を独自に停止するよう要求するために使用されます。 #SIGHUP 一時停止信号。通常、端末接続が中断されたことを示します。構成ファイルなどを再読み込みする必要があります。##SIGKILLKill 停止したプロセス シグナルをキャッチまたは無視できません。プロセスは暴力的に強制終了することのみ可能です。 SIGSTOP プロセス停止シグナルをキャッチまたは無視できません。プロセスは強制的に停止することしかできません。SIGCONTプロセスの実行を継続しますSIGPIPEパイプ破断信号。通常はデータの読み取りを示します。相手側が接続を閉じました。SIGALRMアラーム クロック信号。定期的に操作をトリガーするために使用されます。#SIGCHLD通常は、SIGINT シグナルと SIGTERM シグナルをリッスンするだけで済みます。 正常なシャットダウンの役割正常なシャットダウンにより、リクエストや操作の失敗によって引き起こされるデータ損失、リソース漏洩、その他の問題を回避できます。サービスを提供する長時間実行されるプログラムやアプリケーションの場合、特に重要です。特に分散システムやマイクロサービス アーキテクチャでは、正常なシャットダウンはシステムの安定性とパフォーマンスを効果的に確保できますが、対象となる問題処理機能がないと、プログラムが勝手に終了したり、停止信号を受信した後にクラッシュを引き起こしたりして、深刻な問題を引き起こす可能性があります。クライアントに不必要な損失を与えます。 概要
信号の説明
##SIGUSR1-31 カスタムシグナル
サブプロセス終了シグナル

この記事を通じて、正常なシャットダウンに golang のチャネルと os/signal パッケージを使用する方法、およびシグナルをリッスンして正常なシャットダウンを完了する方法を学びました。実際の開発において、アプリケーションを正常にシャットダウンすることは非常に重要な作業であり、正常なシャットダウンはプログラムの安定性を効果的に向上させ、リソースの無駄やデータの損失などの問題を回避します。

以上がgolang のエレガントなシャットダウン方法について話しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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