グレースフルシャットダウン

グレースフルシャットダウンとは、サーバーを停止する際に、すべての接続を即座に切断するのではなく、まず新しいリクエストの受け付けを停止し、既に受け付けたリクエストが十分な時間をかけて処理を完了できるようにしてからサービスを終了する方法です。この方法により、リクエストが突然中断されることを防ぎ、ユーザー体験とシステムの信頼性を向上させることができます。

Salvoはグレースフルシャットダウンをサポートしており、Serverhandleメソッドでサーバーハンドルを取得し、stop_gracefulメソッドを呼び出すことで実現できます。このメソッドを呼び出すと、サーバーは以下の動作を行います:

  • 新しい接続リクエストの受け付けを停止
  • 既存のリクエストの処理完了を待機
  • 指定されたタイムアウト時間後(指定されている場合)、残りの接続を強制的に閉じる

以下は簡単な例です:

use salvo_core::prelude::*;

#[tokio::main]
async fn main() {
    let acceptor = TcpListener::new("127.0.0.1:5800").bind().await;
    let server = Server::new(acceptor);
    let handle = server.handle();

    // サーバーをグレースフルにシャットダウン
    tokio::spawn(async move {
        tokio::time::sleep(std::time::Duration::from_secs(60)).await;
        handle.stop_graceful(None);
    });
    server.serve(Router::new()).await;
}

上記の例では:

  • server.handle()でサーバーのハンドルを取得し、サーバーのライフサイクルを制御可能
  • handle.stop_graceful(None)でグレースフルシャットダウンを開始、Noneはタイムアウト時間を設定せず、すべてのリクエストが処理されるまで待機
  • タイムアウト時間を設定する場合はSome(Duration)を渡すことができ、タイムアウト後に残りの接続を強制的に閉じます

この方法は特に、コンテナ環境やクラウドプラットフォームにデプロイするアプリケーションや、ホットアップデート時にリクエストが意図せず中断されないようにする必要がある場合に適しています。