11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Circuit Breakerの効用をEnvoy + Gatlingで検証してみた

Last updated at Posted at 2018-08-31

マイクロサービス時代に可用性を高めるにはサービス間に Circuit Breaker をはさむと良いらしいと聞きます。これにより障害の連鎖を防ぐことが重要らしいのですが、具体的にどのように効果があるのかイメージがわかなかったのでEnvoyをつかって検証してみました。

構成

Layout

MacBook Proのローカル環境でDocker for Macを動かし、その上で下記のコンテナを動作させました。本来はちゃんとしたアプリを作ったほうがいい&複数のバックエンドも用意したほうが本物っぽいですが、今回は極力簡略化しています。

  • フロントサービス役: OpenResty (← nginx + lua)
  • Envoy Proxy (サイドカーコンテナ)
  • バックエンドサービス: Busy Loopで高負荷な状態をシミュレートしたOpenResty
  • ベンチマークアプリ(Gatling/同一のMacBook上で実行)

テストシナリオ

負荷テストはGatlingアプリで実施しました。負荷のかけ方は下記のような流れです:

  1. さばける最大QPS(400 QPS)まで徐々に上げていき、しばらくキープ (0-30秒目)
  2. 600 QPS程度まで、さらにQPSを上げていく (30-45秒目)
  3. 400QPSに下げる (45-60秒目)

結果

サーキットブレーカーがないときー...... :

gatling-knockouted-wo-circuit-breaker.png
  • 上記シナリオ2(負荷を上げすぎたタイミング)ですべてのリクエストに対してノックアウト
  • 負荷を400QPSに戻しても、ノックアウト状態のまま

例えばECやインターネット広告などのレイテンシーが重要なシステムにおいては、この「一度負荷があがったらその後のすべてのレスポンスでレイテンシーが落ちる」といった状態は致命的ではないでしょうか。

サーキットブレーカーがあるときー! :

gatling-with-circut-breaker.png
  • 一時的な負荷増大に対して、サーキットブレーカーが落ちることでバックエンドに過負荷がかからない
  • 負荷が400QPSに戻ったときに、負荷がかかる前と同じようにレスポンスを返せている

まとめ

サーキットブレーカーの効果

  • サーキットブレーカーがないと...

    • 見積り以上の負荷がいったんかかると、負荷が下がっても正常にレスポンスを返せるようにならない
    • → システムのキャパシティに余裕を持たせなければならず、余計なシステムコストかかる
  • サーキットブレーカーがあれば...

    • 突発的に負荷がかかっても、さばける範囲内で処理できる
    • キャパシティの余裕を減らせてシステムコストを減らせる
  • Envoyはバックエンドへの接続数/リクエスト数・ペンディング数/リトライ回数にもとづきサーキットオープンするので

    • バックエンドの負荷増減に対して反応がいい
      • → 障害の連鎖も起きにくい、ちゃんと縮退運行になりやすい
      • → 復旧もクイック
    • よくある Circuit Breaker の「タイムアウトが頻発したらサーキットオープン」ではない

サーキットブレーカーの難しいところ

  • パラメータ調整が手間
    • EnvoyのCircuit Breakerではバックエンドへの 最大接続数, 最大リクエストペンディング数, 最大リクエスト数 (HTTP/2), リトライ回数 の設定が可能ですが、バックエンドの処理可能なワークロードに応じて調整する必要があり、手間
      • 例: 値を低く設定すると、バックエンドの遊び・無駄があるのにレスポンスを返せない
      • 例: 値を高く設定すると、処理できない量のリクエストがバックエンドに流れて徐々にレスポンス悪化 or ノックアウトにつながる

詳細・補足

サーキットブレーカーがないとき

Total OK KO % KO
23249 14634 8615 37%
Error Count Percentage
status.find.is(200), but actually found 502 5595 64.945 %
j.u.c.TimeoutException: Request timeout to localhost/127.0.0.1:8080 after 1000 ms 2909 33.767 %
j.i.IOException: Connection reset by peer 100 1.161 %
o.a.e.RemotelyClosedException: Remotely closed 11 0.128 %

サーキットブレーカーがあるとき

Total OK KO % KO
23249 22750 499 2%
Error Count Percentage
status.find.is(200), but actually found 503 499 100 %

その他

(※ サーキットブレーカーは “リクエストする側” の対策。スロットリングは “リクエストされる側” の対策。という理解 ※)

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?