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

2b3d68169a23966b99cfc481e40e6593?s=128

hayasshi

March 05, 2021
Tweet

Transcript

  1. 2021/03/05 第6回Reactive System Meetup in 西新宿 Chatwork株式会社 プロダクト本部 サーバーサイド開発部(Scala) 林 大介 Chatwork

    で Akka をどうつかっているのか なぜつかっているのか
  2. 自己紹介 - 林大介 - @hayasshi_ (Twitter) - hayasshi (その他) -

    Chatwork プロダクト本部 サーバーサイド開発部 Scala チーム・マネージャー - 最近の悩み - 🌲✨ 家の中でもマスク必須の生活 😷 2
  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 を使用することで、信頼性の高い動作、耐障害性、高性能を提供するための低レベルのコードを書く代わりに、ビジネスのニーズを満たすことに集中することが できます。
  4. おはなしすること 1. Circuit Breaker 2. Supervision 3. Monitoring 4. まとめ

    4
  5. 01 Circuit Breaker

  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
  7. Circuit Breaker とは Akka の実装は、akka.pattern.CircuitBreaker (ドキュメント) Web アプリケーションの場合、AkkaHTTP の onCompleteWithBreaker

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

    サービスB サービスA
  9. Chatwork での問題 サービスBの AkkaHTTP エンドポイントに Circuit Breaker を設定し、障害が発生した 場合に素早くエラーを返すことで、サービスAのプロセスの詰まりを回避し、カスケー ド障害が発生しないようにした。

    (そもそものサービスAのタイムアウト値の調整や、エラーの場合のリトライやユーザー インタラクションの検討もおこなった) 9 サービスB サービスA
  10. さらなる改善 エンドポイント単位での Circuit Breaker の設置をおこなったが、 たとえば分散ストレージのホスト単位で設置することができれば、 障害が発生しているホストへのアクセスのみを遮断することができ、 更にエラーの範囲を限定することができる。 どの単位で Circuit

    Breaker を設置するか、できるかを検討したい。 10
  11. 02 Supervison

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

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

  15. Chatwork での利用例 ずっと動かしておく処理(ストリーム処理)の想定外エラー時の再起動に利用 Kafka からメッセージを取得して処理し続けるストリームアプリケーションにおいて、 処理の途中で問題が発生した場合に、ストリーム全体を再起動し、再度そのメッセージを取 得、処理したい(リトライしたい)要求があった。 これに対し、AkkaStreams の Supervision

    Strategy の Restart 戦略は、そのメッセージを ドロップして各ステージを再起動した上で再開するため、要求と合わなかった。 そのため、AkkaActors のアクター内で AkkaStreams の Graph を実行し、再起動のハンド リングを AkkaActors の戦略に移譲し、要求を満たした。 ※なお、最近(2~3年前から)は RestartSource なるものがあるので、それで代替できます。 15
  16. 03 Monitoring

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

    Chatwork では、JVM や Akka に関するメトリクスは Kamon をつかって収集している。 17
  18. JVM や Akka, Play のメトリクスを自動/半自動で収集。(カスタムメトリクスも可能) 各形式向けの Reporter で多彩な出力が可能。※APM の機能もありますが割愛 ライブラリの依存を加え、設定と起動時に初期化するだけで、

    下記のような各種メトリクスを自動/半自動で収集。 18 JVM ヒープ使用量や、GC 時間、メモリの各領域の使用量 全体のスレッド数や、各スレッドプールのアクティブスレッド数 Akka メールボックスのメッセージ滞留量、メッセージ処理速度 Dispatcher のアクティブスレッド数 Play, AkkaHTTP エンドポイント単位の処理量や処理時間(レイテンシ)
  19. Chatwork での利用 Chatwork では、datadog-reporter をつかって収集されたメトリクスを Datadog に送信 し、可視化している。 これらを、Akka をつかっているアプリケーションの障害時の原因調査や、パフォーマンス・

    チューニングの参考情報としている。 19
  20. 04 まとめ(ポエム)

  21. アプリケーションの信頼性を向上させるのは異常や障害への考慮 Scala の Option や Either, Try などと同様、問題が発生する可能性を明らかにし、それ に対する振る舞いを決めることが第一歩になる。 リアクティブ宣言の中にも記載がある。

    - 即応性とは使い勝手と実用性の基盤だが、しかしそれだけではなく、問題が素早く 検出され効果的に対処できることを意味する。 - システムは障害に直面しても即応性を保ち続ける。 Akka は異常や障害に対する考え方と、それに対応するためのツールが整っている。 21
  22. アプリケーションの信頼性を向上させるのは異常や障害への考慮 異常に対する振る舞いは、1人で決められないことが多い。 - 隣の部署のサービスとの連携 - サービスのふるまいとしての PO の判断 - その他ステークホルダー

    信頼性の高いシステムを一発でつくるのは難しい。 日々のモニタリング、エラーや異常、障害の検知を通しての改善を継続する。 信頼性の高いシステムを構築することが、エンジニアリングの腕の見せどころ 💪 22
  23. 働くをもっと楽しく、創造的に