ヘルスチェックとグレースフルシャットダウン

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

アプリケーションの新しいバージョンをデプロイする場合、以前のバージョンを置き換える必要があります。使用しているプロセス管理ツールは、まずアプリケーションに SIGTERM シグナルを送信し、アプリケーションが停止することを通知します。アプリケーションはこのシグナルを受け取ると、新しいリクエストの受付を停止し、進行中のすべてのリクエストを完了し、データベース接続やファイルロックなど、使用していたリソースをクリーンアップしてから終了する必要があります。

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

const server = app.listen(port)

process.on('SIGTERM', () => {
  debug('SIGTERM signal received: closing HTTP server')
  server.close(() => {
    debug('HTTP server closed')
  })
})

ヘルスチェック

ロードバランサーはヘルスチェックを使用して、アプリケーションインスタンスが正常でリクエストを受け入れることができるかどうかを判断します。たとえば、Kubernetes には 2 つのヘルスチェックがあります。

サードパーティソリューション

警告: この情報は、Expressjs チームによってメンテナンスされていないサードパーティのサイト、製品、またはモジュールに関するものです。ここにリストすることは、Expressjs プロジェクトチームからの推奨または推奨を構成するものではありません。

Terminus

Terminus は、定型コードを記述する必要をなくすために、アプリケーションにヘルスチェックとグレースフルシャットダウンを追加するオープンソースプロジェクトです。グレースフルシャットダウンのクリーンアップロジックとヘルスチェックのロジックを提供するだけで、残りは Terminus が処理します。

Terminus を以下のようにインストールします。

$ npm i @godaddy/terminus --save

Terminus の使用方法を示す基本的なテンプレートを以下に示します。詳細については、https://github.com/godaddy/terminus を参照してください。

const http = require('http')
const express = require('express')
const { createTerminus } = require('@godaddy/terminus')

const app = express()

app.get('/', (req, res) => {
  res.send('ok')
})

const server = http.createServer(app)

function onSignal () {
  console.log('server is starting cleanup')
  // start cleanup of resource, like databases or file descriptors
}

async function onHealthCheck () {
  // checks if the system is healthy, like the db connection is live
  // resolves, if health, rejects if not
}

createTerminus(server, {
  signal: 'SIGINT',
  healthChecks: { '/healthcheck': onHealthCheck },
  onSignal
})

server.listen(3000)

Lightship

Lightship は、アプリケーションにヘルスチェック、準備性チェック、生存性チェックを追加するオープンソースプロジェクトです。Lightship はスタンドアロンの HTTP サービスとして、別の HTTP サービスとして実行されます。これにより、パブリックインターフェースに公開することなく、ヘルスチェック・準備性・生存性 HTTP エンドポイントを持つことができます。

Lightship を以下のようにインストールします

$ npm install lightship

Lightship の使用方法を示す基本的なテンプレート

const http = require('http')
const express = require('express')
const {
  createLightship
} = require('lightship')

// Lightship will start a HTTP service on port 9000.
const lightship = createLightship()

const app = express()

app.get('/', (req, res) => {
  res.send('ok')
})

app.listen(3000, () => {
  lightship.signalReady()
})

// You can signal that the service is not ready using `lightship.signalNotReady()`.

Lightship のドキュメントでは、対応するKubernetes 設定の例と、Express.jsとの統合の完全な例を提供しています。

http-terminator

http-terminator は、express.js サーバーをグレースフルに終了するためのロジックを実装します。

Node.js で HTTP サーバーを終了するには、開いているすべての接続を追跡し、サーバーがシャットダウンしていることを通知する必要があります。 http-terminator は、すべての接続とタイムアウト時の終了を追跡するロジックを実装します。 http-terminator は、サーバーがシャットダウンする意図を現在このサーバーから応答を受け取っているクライアントにグレースフルに伝達することも保証します。

http-terminator を以下のようにインストールします

$ npm install http-terminator

http-terminator の使用方法を示す基本的なテンプレート

const express = require('express')
const { createHttpTerminator } = require('http-terminator')

const app = express()

const server = app.listen(3000)

const httpTerminator = createHttpTerminator({ server })

app.get('/', (req, res) => {
  res.send('ok')
})

// A server will terminate after invoking `httpTerminator.terminate()`.
// Note: Timeout is used for illustration of delayed termination purposes only.
setTimeout(() => {
  httpTerminator.terminate()
}, 1000)

http-terminator のドキュメントでは、API ドキュメントと他の既存のサードパーティソリューションとの比較を提供しています。

express-actuator

express-actuator は、アプリケーションの監視と管理に役立つエンドポイントを追加するミドルウェアです。

express-actuator を以下のようにインストールします。

$ npm install --save express-actuator

express-actuator の使用方法を示す基本的なテンプレート

const express = require('express')
const actuator = require('express-actuator')

const app = express()

app.use(actuator())

app.listen(3000)

express-actuator のドキュメントでは、さまざまなカスタマイズオプションを提供しています。