GitLabのテストインスタンスでカオスを発生させます。

Amazon Web Services の CTO であるWerner Vogels氏の有名な言葉です。

開発者として、典型的なオペレーションと同様に、ソフトウェアが動作する可能性のある故障モードを考慮することも重要です。そうすることで、ごく一部のユーザーが経験する500 エラーの散乱につながる小さな不具合と、長期間にわたってすべてのユーザーに影響を与える完全なサイト停止の違いを意味することができます。

トルストイの言葉を借りれば、_幸せなサーバーは皆同じですが、失敗しているサーバーは皆、それぞれの方法で失敗して_いるのです。幸運なことに、これらの障害モードをシミュレートする方法があり、カオスエンドポイントはこのプロセスを支援するツールです。

現在、以下の状態をシミュレートするための4つのエンドポイントがあります:

  • 遅いリクエスト。
  • CPUバウンドリクエスト。
  • メモリリーク。
  • 予期しないプロセスのクラッシュ

カオスエンドポイントの有効化

明らかな理由により、これらのエンドポイントはproduction ではデフォルトでは有効になっていません。開発者環境ではデフォルトで有効になっています。

caution
シークレットトークンを使ってカオスエンドポイントへのセキュリティを確保する必要があります。何をやっているのか絶対に分かっているのでなければ、本番環境では有効にすべきではありません。

シークレットトークンはGITLAB_CHAOS_SECRET 環境変数で設定できます。例えば、GDKを使用する場合、以下のコマンドで設定できます:

GITLAB_CHAOS_SECRET=secret gdk start

secret をあなた自身の秘密トークンに置き換えてください。

カオスの起動

chaos エンドポイントを有効にしてアプリケーションを再起動したら、エンドポイントを使ったテストを開始できます。

デフォルトでは、カオスエンドポイントを呼び出すと、リクエストを受け取ったウェブワーカープロセスがそれを処理します。つまり、例えばKillオペレーションが呼び出された場合、リクエストを処理するPumaワーカープロセスは強制終了されます。Sidekiqでこれらのオペレーションをテストするには、各エンドポイントのasync パラメータをtrueに設定します。 これにより、Sidekiqワーカーでchaosプロセスが実行されます。

メモリリーク

アプリケーションのメモリリークをシミュレートするには、/-/chaos/leakmem エンドポイントを使用します。

リクエストが終了してもメモリは保持されません。リクエストが終了すると、Ruby のガベージコレクタがメモリの回収を試みます。

GET /-/chaos/leakmem
GET /-/chaos/leakmem?memory_mb=1024
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50&async=true
属性種類必須説明
memory_mb整数。いいえリークされるメモリ量(MB)。デフォルトは100MBです。
duration_s整数。いいえメモリを保持する最小時間_s(秒)。デフォルトは30秒です。
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスでメモリをリークする場合はtrueに設定します。
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10&token=secret"

CPUスピン

このエンドポイントは、指定された期間、100% で、単一のコアを完全に使用しようとします。

ラックサーバーのセットアップによっては、あらかじめ決められた期間 (通常は 60 秒) が経過するとリクエストがタイムアウトすることがあります。

GET /-/chaos/cpu_spin
GET /-/chaos/cpu_spin?duration_s=50
GET /-/chaos/cpu_spin?duration_s=50&async=true
属性種類必須説明
duration_s整数。いいえCoreが使用される時間(秒)。デフォルトは30秒
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスでCPUを消費する場合はtrueに設定します。
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/cpu_spin?duration_s=60&token=secret"

DBスピン

このエンドポイントは、指定された期間、単一の Core を完全に使用し、DB 要求とインターリーブしようとします。このエンドポイントは、同時実行時に他のスレッドに実行をゆだねるモデルに使用できます。

ラックサーバーのセットアップによっては、あらかじめ決められた期間 (通常は 60 秒) が経過するとリクエストがタイムアウトすることがあります。

GET /-/chaos/db_spin
GET /-/chaos/db_spin?duration_s=50
GET /-/chaos/db_spin?duration_s=50&async=true
属性種類必須説明
interval_sフロートいいえDBリクエストの間隔を秒単位で指定します。デフォルトは1秒
duration_s整数。いいえCoreが使用される時間(秒)。デフォルトは30秒
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスでオペレーションを実行する場合はtrueに設定します。
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60&token=secret"

スリープ

このエンドポイントは CPU Spin エンドポイントと似ていますが、バックエンドサービスへのネットワーク呼び出しなど、プロセッサ外のアクティビティをシミュレートします。与えられたduration_s の間スリープします。

CPU Spin エンドポイントと同様に、duration_s が設定された制限を超えた場合、リクエストがタイムアウトする可能性があります。

GET /-/chaos/sleep
GET /-/chaos/sleep?duration_s=50
GET /-/chaos/sleep?duration_s=50&async=true
属性種類必須説明
duration_s整数。いいえリクエストがスリープする時間(秒)。デフォルトは 30 秒です。
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスでスリープするにはtrueに設定します。
curl "http://localhost:3000/-/chaos/sleep?duration_s=60" \
     --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/sleep?duration_s=60&token=secret"

キル

このエンドポイントはKILL シグナルを使って、ワーカープロセスの予期せぬ死をシミュレートします。

このエンドポイントはKILL シグナルを使用するため、プロセスはクリーンアップやシャットダウンの機会を与えられません。

GET /-/chaos/kill
GET /-/chaos/kill?async=true
属性種類必須説明
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスにシグナルを送るにはtrueに設定します。
curl "http://localhost:3000/-/chaos/kill" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/kill?token=secret"

終了

このエンドポイントは、QUIT シグナルを使ってワーカープロセスの予期せぬ死をシミュレートします。KILLとは異なり、QUIT シグナルは Core ダンプの書き込みも試みます。詳細はcore(5)を参照してください。

GET /-/chaos/quit
GET /-/chaos/quit?async=true
属性種類必須説明
asyncbooleanいいえSidekiqバックグラウンドワーカープロセスにシグナルを送るにはtrueに設定します。
curl "http://localhost:3000/-/chaos/quit" --header 'X-Chaos-Secret: secret'
curl "http://localhost:3000/-/chaos/quit?token=secret"

ガベージコレクタの実行

このエンドポイントはリクエストを処理するワーカーの GC をトリガーし、ワーカー ID と GC の統計情報を JSON で返します。このエンドポイントは Puma をスタンドアローンモードで実行するときに便利です。

エンドポイント

POST /-/chaos/gc

リクエストの例

curl --request POST "http://localhost:3000/-/chaos/gc" \
     --header 'X-Chaos-Secret: secret'
curl --request POST "http://localhost:3000/-/chaos/gc?token=secret"

応答例

{
  "worker_id": "puma_1",
  "gc_stat": {
    "count": 94,
    "heap_allocated_pages": 9077,
    "heap_sorted_length": 9077,
    "heap_allocatable_pages": 0,
    "heap_available_slots": 3699720,
    "heap_live_slots": 2827510,
    "heap_free_slots": 872210,
    "heap_final_slots": 0,
    "heap_marked_slots": 2827509,
    "heap_eden_pages": 9077,
    "heap_tomb_pages": 0,
    "total_allocated_pages": 9077,
    "total_freed_pages": 0,
    "total_allocated_objects": 14229357,
    "total_freed_objects": 11401847,
    "malloc_increase_bytes": 8192,
    "malloc_increase_bytes_limit": 30949538,
    "minor_gc_count": 71,
    "major_gc_count": 23,
    "compact_count": 0,
    "remembered_wb_unprotected_objects": 41685,
    "remembered_wb_unprotected_objects_limit": 83370,
    "old_objects": 2617806,
    "old_objects_limit": 5235612,
    "oldmalloc_increase_bytes": 8192,
    "oldmalloc_increase_bytes_limit": 122713697
  }
}