ホームページ >バックエンド開発 >Golang >golangでスムーズに再起動する方法

golangでスムーズに再起動する方法

WBOY
WBOYオリジナル
2023-05-12 20:37:061072ブラウズ

フロントエンド開発、バックエンド開発、DevOpsの分野において、スムーズな再起動は非常に重要な技術です。既存のリクエストを中断せずにアプリケーションを更新する必要がある場合、グレースフル リスタートにより更新プロセスがよりスムーズになります。グレースフル リスタートは Golang の比較的新しいテクノロジですが、Golang の注目が高まるにつれ、必須の機能になりました。この記事ではGolangでスムーズな再起動を実装する方法を紹介します。

スムーズな再起動とは何ですか?

グレースフル リスタートは、既存のリクエストを妨げることなく更新プロセスを実行するアプリケーション更新手法です。従来の再起動とは、アプリケーションを停止して新しいインスタンスを起動することを意味します。これを行うと、新しいインスタンスが起動を完了してリクエストを引き継ぐまで、受信リクエストが応答しなくなります。グレースフル リスタートはこの問題を解決し、アプリケーションの更新プロセスを既存のインスタンス内で実行できるようにします。

なぜスムーズな再起動が必要なのでしょうか?

グレースフル リスタートを行わないと、アプリケーションを更新する必要があるたびに、一定期間使用できなくなることになります。これにより、クライアント/ユーザーに不便が生じます。グレースフル リスタートはこの問題を回避し、アプリケーションをより快適で回復力のあるものにすることができます。これは、トラフィックが多いときに特に役立ちます。

Golang の組み込み http 最適化

Golang では、http.Server が一般的に使用される Web フレームワークです。これにより、グレースフル リスタートなどの多くのオプションが提供されます。 http.Server には、すべてのクライアント接続が閉じられるまで操作を中断せずにサーバーを停止する Shutdown メソッドがあります。

システムの SIGINT (Ctrl C/kill)、SIGTERM (kill)、およびその他のシグナルをリッスンし、http.Server.Shutdown() を呼び出すことによって既存の接続を処理すると、サーバーを停止できます。停止中に、すべてのハンドラーが完了するまで待機するか、タイムアウト後に操作を閉じることができます。

以下は短い例です。

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    // 创建我们的HTTP Server,参数为 Mux/Router 实例
    srv := &http.Server{
        Addr: ":8080",
        // 服务器转发请求给自己,重写了请求的url(必填)
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("Welcome to my website!"))
        }),
    }

    // 新开 goroutine 监听用户信号(操作系统可以选择向进程发送的信号)
    go func() {
        sigs := make(chan os.Signal, 1)
        // 常见用户信号 ctrl+c, kill ,sigterm 等
        signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

        <-sigs

        // 创建新的 context 用于调用 shutdown 方法
        ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
        defer cancel()

        if err := srv.Shutdown(ctx); err != nil {
            log.Fatal("Server forced to shutdown:", err)
        }

        log.Println("Server gracefully stopped")
    }()

    log.Println("Server started at", srv.Addr)

    // 最终函数会阻塞在这里,等待用户信号
    if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
        log.Fatal("Server exited:", err)
    }
}

この例で実際のサーバーを使用する場合、http.Server.Serve() によって返されるエラー (http.ErrServerClosed など) が上書きされないことを確認する必要があります。これを使用すると、操作 (即時エラーなど) を正しく処理し、予期しないサーバーのシャットダウンやサーバーの再起動を回避できます。

待機を処理する前に、渡されたコンテキストが閉じられていないことを確認する必要があります (コードの実装によって異なります)。 )、待機中の操作がタスクを完了するのに十分な時間を確保できるようにします。

概要

スムーズな再起動は、アプリケーションの再起動によって引き起こされる一時的な使用不能を回避するのに役立ち、高可用性を必要とするアプリケーションにとって不可欠です。 Golang は、高性能で開発と拡張が容易な言語として、スムーズな再起動を当然サポートする必要があります。 Golang では、http.Server.Shutdown() メソッドを使用するだけでスムーズな再起動を実現し、これに基づいてビジネス ロジックを実装できます。

以上がgolangでスムーズに再起動する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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