Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Chatwork で Akka をどうつかっているのか なぜつかっているのか / Why Akka, How Akka in Chatwork

Chatwork で Akka をどうつかっているのか なぜつかっているのか / Why Akka, How Akka in Chatwork

hayasshi

March 05, 2021
Tweet

More Decks by hayasshi

Other Decks in Programming

Transcript

  1. 2021/03/05
    第6回Reactive System Meetup in 西新宿
    Chatwork株式会社
    プロダクト本部 サーバーサイド開発部(Scala)
    林 大介
    Chatwork で
    Akka をどうつかっているのか
    なぜつかっているのか

    View full-size slide

  2. 自己紹介
    - 林大介
    - @hayasshi_ (Twitter)
    - hayasshi (その他)
    - Chatwork プロダクト本部 サーバーサイド開発部 Scala チーム・マネージャー
    - 最近の悩み
    - 🌲✨ 家の中でもマスク必須の生活 😷
    2

    View full-size slide

  3. はじめに Akkaとは
    Akka のドキュメント冒頭にはこのように記載されています。
    分散システムを構築するためのツールキット。
    分散システムにおける、アプリケーションやシステム間の信頼性を高めるための
    設計の考え方や、それが反映されたツール、コンポーネントが用意されています。
    3
    Welcome to Akka, a set of open-source libraries for designing scalable, resilient systems that span processor cores and networks.
    Akka allows you to focus on meeting business needs instead of writing low-level code to provide reliable behavior, fault tolerance, and high performance.
    Akka は、プロセッサコアとネットワークにまたがるスケーラブルで回復力のあるシステムを設計するためのオープンソースのライブラリです。
    Akka を使用することで、信頼性の高い動作、耐障害性、高性能を提供するための低レベルのコードを書く代わりに、ビジネスのニーズを満たすことに集中することが
    できます。

    View full-size slide

  4. おはなしすること
    1. Circuit Breaker
    2. Supervision
    3. Monitoring
    4. まとめ
    4

    View full-size slide

  5. 01
    Circuit Breaker

    View full-size slide

  6. Circuit Breaker とは
    訳すると 遮断器、ブレーカー 。
    電力回路におけるものと同様、システムに負荷がかかった際に、負荷側を保護し、上流
    (呼び出し)側への事故波及を防止するために設置するパターン。
    Akka のほかにも、Netflix の Hystrix や、LINE の Armeria にも実装されている。
    (余談ですが、Hystrix は開発が終了し、Resilience4j に代替されるようです)
    マイクロサービス・アーキテクチャでもよく使われるパターン。
    - https://martinfowler.com/bliki/CircuitBreaker.html
    - https://microservices.io/patterns/reliability/circuit-breaker.html
    6

    View full-size slide

  7. Circuit Breaker とは
    Akka の実装は、akka.pattern.CircuitBreaker (ドキュメント)
    Web アプリケーションの場合、AkkaHTTP の onCompleteWithBreaker Directive と組
    み合わせて、エンドポイント単位での設置が可能。
    7

    View full-size slide

  8. Chatwork での問題
    あるシステム間の連携で、サービスBが利用する分散ストレージの一部に負荷がかかる
    ことがあり、その間その部分へのアクセスが遅くなり、タイムアウトが発生。
    同期的に呼び出していたサービスAも、リクエストの待ち状態が増え、処理プロセスが
    埋まり、システム全体のレスポンスタイムが遅くなる自体に☁
    いわゆる カスケード障害 が定期的に発生する状態だった。
    8
    サービスB
    サービスA

    View full-size slide

  9. Chatwork での問題
    サービスBの AkkaHTTP エンドポイントに Circuit Breaker を設定し、障害が発生した
    場合に素早くエラーを返すことで、サービスAのプロセスの詰まりを回避し、カスケー
    ド障害が発生しないようにした。
    (そもそものサービスAのタイムアウト値の調整や、エラーの場合のリトライやユーザー
    インタラクションの検討もおこなった)
    9
    サービスB
    サービスA

    View full-size slide

  10. さらなる改善
    エンドポイント単位での Circuit Breaker の設置をおこなったが、
    たとえば分散ストレージのホスト単位で設置することができれば、
    障害が発生しているホストへのアクセスのみを遮断することができ、
    更にエラーの範囲を限定することができる。
    どの単位で Circuit Breaker を設置するか、できるかを検討したい。
    10

    View full-size slide

  11. 02
    Supervison

    View full-size slide

  12. Supervision とは
    アクターは、ActorSystem を頂点とする、ツリー状のヒエラルキーを構築する。
    処理をおこなうアクターで想定しない失敗がおこった際に、そのアクターを監督する親
    アクター(Supervisor)がその解決をおこなう。
    これにより、処理をおこなうアクターでは、ビジネスロジック(要求の検証や想定される
    失敗を含む)のみを取り扱うことができる。
    12
    エスカレーション
    戦略にもとづいた
    対応

    View full-size slide

  13. Supervision とは
    解決の戦略(Supervision Strategy)
    - Resume
    - Restart
    - Stop
    - Escalate
    処理中のメッセージは失われることに注意が必要。
    AkkaActors におけるデフォルトの戦略が、classic と typed で変更されているので
    注意が必要。( classic = Restart, typed = Stop )
    https://doc.akka.io/docs/akka/current/typed/fault-tolerance.html
    https://speakerdeck.com/hayasshi/akka-typed-typesafe-messaging?slide=39
    13

    View full-size slide

  14. Chatwork での利用例
    ミドルウェアとのネゴシエーションなど、複雑な状態管理と処理が必要な部分
    あるミドルウェアを扱うに当たり、初期の接続シーケンスやその後の状態管理、またデータ
    を利用した別の処理など、複数の処理が非同期におこなわれるコンポーネントがある。
    状態管理やデータ処理などを、適切な単位の責務に分割し、ヒエラルキーを設計し、各責務
    ごとに想定されないエラーが発生した場合の振る舞いを定義した。
    各処理の依存や関連も含め、それらをアクタープログラミングで表現することで、適切にビ
    ジネスロジックと想定外の失敗対処を分離することができた。
    14

    View full-size slide

  15. Chatwork での利用例
    ずっと動かしておく処理(ストリーム処理)の想定外エラー時の再起動に利用
    Kafka からメッセージを取得して処理し続けるストリームアプリケーションにおいて、
    処理の途中で問題が発生した場合に、ストリーム全体を再起動し、再度そのメッセージを取
    得、処理したい(リトライしたい)要求があった。
    これに対し、AkkaStreams の Supervision Strategy の Restart 戦略は、そのメッセージを
    ドロップして各ステージを再起動した上で再開するため、要求と合わなかった。
    そのため、AkkaActors のアクター内で AkkaStreams の Graph を実行し、再起動のハンド
    リングを AkkaActors の戦略に移譲し、要求を満たした。
    ※なお、最近(2~3年前から)は RestartSource なるものがあるので、それで代替できます。
    15

    View full-size slide

  16. 03
    Monitoring

    View full-size slide

  17. Monitoring の重要性
    アプリケーションが正しく動作しているか、リソースをどれくらい消費しているか、障害時
    にボトルネックになったのはどこかなど、アプリケーションを観察することは重要。
    - アプリケーション・ログ
    - アプリケーション・メトリクス
    これらをつかってエラーや障害の検知、その原因調査、またパフォーマンス・チューニング
    がおこなわれることが多い。
    Chatwork では、JVM や Akka に関するメトリクスは Kamon をつかって収集している。
    17

    View full-size slide

  18. JVM や Akka, Play のメトリクスを自動/半自動で収集。(カスタムメトリクスも可能)
    各形式向けの Reporter で多彩な出力が可能。※APM の機能もありますが割愛
    ライブラリの依存を加え、設定と起動時に初期化するだけで、
    下記のような各種メトリクスを自動/半自動で収集。
    18
    JVM ヒープ使用量や、GC 時間、メモリの各領域の使用量
    全体のスレッド数や、各スレッドプールのアクティブスレッド数
    Akka メールボックスのメッセージ滞留量、メッセージ処理速度
    Dispatcher のアクティブスレッド数
    Play, AkkaHTTP エンドポイント単位の処理量や処理時間(レイテンシ)

    View full-size slide

  19. Chatwork での利用
    Chatwork では、datadog-reporter をつかって収集されたメトリクスを Datadog に送信
    し、可視化している。
    これらを、Akka をつかっているアプリケーションの障害時の原因調査や、パフォーマンス・
    チューニングの参考情報としている。
    19

    View full-size slide

  20. 04
    まとめ(ポエム)

    View full-size slide

  21. アプリケーションの信頼性を向上させるのは異常や障害への考慮
    Scala の Option や Either, Try などと同様、問題が発生する可能性を明らかにし、それ
    に対する振る舞いを決めることが第一歩になる。
    リアクティブ宣言の中にも記載がある。
    - 即応性とは使い勝手と実用性の基盤だが、しかしそれだけではなく、問題が素早く
    検出され効果的に対処できることを意味する。
    - システムは障害に直面しても即応性を保ち続ける。
    Akka は異常や障害に対する考え方と、それに対応するためのツールが整っている。
    21

    View full-size slide

  22. アプリケーションの信頼性を向上させるのは異常や障害への考慮
    異常に対する振る舞いは、1人で決められないことが多い。
    - 隣の部署のサービスとの連携
    - サービスのふるまいとしての PO の判断
    - その他ステークホルダー
    信頼性の高いシステムを一発でつくるのは難しい。
    日々のモニタリング、エラーや異常、障害の検知を通しての改善を継続する。
    信頼性の高いシステムを構築することが、エンジニアリングの腕の見せどころ 💪
    22

    View full-size slide

  23. 働くをもっと楽しく、創造的に

    View full-size slide