あなたのラムダ失敗をしてください!使用してカオス工学あなたのServerlessアプリケーションの弾力性を向上させる.


Resilience is the ability to recover from or adjust easily to adversity or change.


一般に、ソフトウェア工学では、あなたのシステム/アプリケーションがそのコンポーネントのうちの1つで失敗に耐えることができて、それにかかわらず働くことができるということを意味します、そして、結局、合理的な方法と許容できる期間で回復します.

Chaos Engineering is the discipline of experimenting on a system in order to build confidence in the system’s capability to withstand turbulent conditions in production. wikipedia


……それは私たちの理解にあまり増しません.
システムに関する実験は何を意味しますか?どうやって実験するの?

Even when all of the individual services in a distributed system are functioning properly, the interactions between those services can cause unpredictable outcomes.
Principle of chaos


それは主に主要な側面です.各コンポーネントは、独自に非常によく動作する可能性があります.我々は、ユニットテスト、統合テスト、E 2 Eテストを持っているが、真実は、特に分散システムでは、それは非常にいくつかの失敗の相互作用の結果を予測するのは難しいことができます.

Unpredictable outcomes, compounded by rare but disruptive real-world events that affect production environments, make these distributed systems inherently chaotic.
Principle of chaos


ああ!得た!
  • 破壊的な出来事を予想するのはとても難しい.
  • 分散システムは、それらの可動部分のため、複雑である、
  • は、コードが時間
  • の間、乱雑になるのは避けられないです
    それがカオス工学である理由!

    まあ本当に!

    何が本当にカオス工学ですか?


    Chaos engineering is all about asking: “What if?” (Emrah Samdan)

  • 私のラムダが依存しているサードパーティAPIが非常に遅いか完全に手に負えないならば、どうですか?
  • 我々のDynamoDBテーブルスループットが超えているかどうか.
  • 我々の子午線のうちの1つが絞られるならば、どうですか?
  • 何らかのキャッチされた例外が発生した場合、どうなりますか?
  • あなたがソフトウェア工学の長い十分な経験をするならば、あなたはそれを知っています.
    したがって、我々はシステム全体、異常行動に現れる前に、弱点を特定する必要があります.我々は準備する必要があります、我々は何が起こるか、そして、我々のシステムがどう反応するかについて信頼を構築する必要があります.
    カオス工学は、目的に向かって物事を壊すことだと言う人もいるかもしれない.ある程度までは本当です.なぜなら、我々はシステムにいくつかのカオスを追加し、それを壊すために管理することができますので、我々はその後、それを修正する方法を見つけることができる/または少なくとも少なくとも破壊的なイベントの爆発半径を最小限にしようとする.

    どのような爆発半径も意味?それは意味します:何かが働くのを止めてください、そして、私たちはそれについて多くのことをすることができません.あなたのアプリケーション全体をクラッシュさせてください!

    カオスに秩序をもたらす5つの小さなステップ


    そのためには、
  • 我々のアプリケーションの定常状態を定義します.(万事がうまくいったら、どう振舞うか)
  • は、制御および実験グループ
  • の両方の定常状態について仮説を立てる
  • は現実的な失敗を投げます
  • は、結果を観察します(何が起こったかについて、我々が起こると思っていたものと比較して)
  • 必要に応じてコードベース/インフラストラクチャを調整します(結果を使用してシステムに作用し、弾力的になるように).
  • カオス工学実験とモニタリングを実行するためのツールはたくさんあります.そのうちの1つはGremlinですが、いくつかの場合、特に無サーバとラムダでは、そのようなテストを調整するのは簡単ではありません.
    我々は我々のアプリケーションで使用を開始Failure-Lambda、簡単にあなたのラムダにいくつかのカオスを注入することができますNPMのモジュールであり、どのようにあなたのServerlessシステムがどのように反応するかをテストすることができます.
    私たちは、ラムダが私たちのコードに本当に依存しない失敗でどのようにふるまうかを証明するのが非常に簡単であるとわかりました.
    確かに、コード内のすべてのエッジのケースと例外を処理している可能性があります、nullポインタ、DynamoDB writeconditions拒否、およびその他のビジネスロジックエラー.しかし、まだあなたのコントロールの下ではない多くの多くがあります:サードパーティのAPI、潜時、ディスクスペース、タイムアウト.
    これらの問題は非常にまれであるかもしれません、しかし、彼らは必然的に起こります.それで、我々は準備されなければなりません.
    我々は適切なリトライメカニズムを持っていますか?我々のラムダの可能性?
    FailUREambdaを使用すると、ラムダの故障がどのようにシステムに影響を与えるのかを簡単にテストすることができます.また、Gunnarは最近、彼のモジュールを使用する方法と、サンプルの無制限のアプリケーションに対する影響をどのように示しているかを示しています.
    repo
    使い方はとても簡単です.ちょうどそれを使用してハンドラーをラップし、SSMパラメータを介してしたいカオスの種類と周波数を設定します.
    // in failure-config.json
    {
      "isEnabled": true,
      "failureMode": "latency",
      "rate": 1,
      "minLatency": 3000,
      "maxLatency": 10000,
      "exceptionMsg": "Everything is broken",
      "statusCode": 404,
      "diskSpace": 100,
      "denylist": ["s3.*.amazonaws.com", "dynamodb.*.amazonaws.com"]
    }
    
    // from CLI 
    aws ssm put-parameter --name your-failure-injection-config  
    --value "$(cat failure-conf.json)" --type String --overwrite
    
    
    特定のサードパーティのAPIをブロックしますか?denylistに追加し、failuremodeをdenylistとして設定します
    いくつかのランダムな遅延問題をスローしますか?failuremodeをレイテンシとして設定する
    すべてのカスタムエラーを破るにしますか?例外を設定し、例外を指定する
    次に、アプリケーションで地獄を解き放つ参照してください.(うまくいけない)

    いくつかのさらなるアイデアと改善


    このモジュールは素晴らしいですが、非常に便利ですが、私たちはいくつかの制限を見つけました.

  • ローカル使用のためのLambdAfailureInjectionの設定.私はいくつかの失敗の問題に対処するいくつかの統合テストを書きたかったが、私はSSMの設定に依存する必要があり、それは非常に便利ではなかった.を使用する可能性がある.SSVの代わりにENVファイルを使うと、CIの上で動くことができるいくつかの統合テストを書くことができます、あるいは、ローカルのとき、gitフックとして動くことができます.
  • すべての単一ラムダ起動、SSMから失敗注入構成を要求して、キャッシュが定義されていません(我々が我々が実験をシャットダウンしたいならば、我々が我々のラムダが15分のために活性化された失敗をキャッシュさせたくないので、どうにか、良いです)!
    しかし、実際にラムダを失敗ラッパーで展開する場合は、すべてのSSMリクエストを支払うか、ラッパーなしでラムダを再配備する必要があります.
    コードを変更し、再配備するのを避けるために、ラッパーをラッピングして、ラムダ変数が失敗注入を実行するように設定されている場合にのみ追加しました.
  • const failureLambda = require('failure-lambda')
    const failureWrapper = fn => {
        if (process.env.CHAOS_MODULE_AVAILABLE === 'true') {
            console.log('FailureInjectionModule is available to inject some chaos - configuration comes from SSM MyFailureLambda Parameter'
            )
            return failureLambda(fn)
        }
        return fn
    }
    
    module.exports.handler =  failureWrapper(handlerLogic)
    
    
    私たちはまだenvvariableを編集する必要がありますが、メインハンドラコードを編集したり、再配備するよりも速く、安全であることがわかります.
    ラムダPARAMを編集し、失敗モジュールをアクティブにします(SSMから読み込むように)、CLIを使用できます.
    aws lambda update-function-configuration --function-name my-lambda-under-test --environment <env-as-json>
    
    しかし、残念ながら、このコマンドはすべての環境変数を置き換えますので、常に変更したいものだけでなく、あなたが持っている可能性のあるすべての変数を渡す必要があります.
    CLIを使用して、現在の設定を取得し、それを編集してラムダを更新するか、またはこれらの手順を組み合わせたより良いノードスクリプトを書き込みます(または単に を使用します).
    さあ、コンソールの変数の値を編集しましょう.私たちの旗をChooschen ModuleRangeをFalseからtrueまで利用可能にすることは、我々の実験を走らせます.
    this module
    また、特にDenyListに関して、レート構成について注意する1つの小さなことは、この率が否定されたURLの呼び出しでないラムダ呼び出しに適用されるということです.( SQSのレコードをテストしていて、各レコードのAPIに対するリクエストの50 %だけがブロックされていると予想していました.
    また、いくつかの実験を実行し、模擬失敗の動作にテストを書くために言及する価値がある
    [ DenuRelambdがdenylist機能のために内部的に使用している)
    MITMは真ん中に人間のためにとどまり、ネットワーク接続TCPとHTTP接続を妨害し、模擬することができますライブラリは、あなたのテスト機能に余分な可能性を与える.
    希望が助け
    https://www.npmjs.com/package/mitmによる写真