マイクロサービスに役立つかもしれないlagomのデザイン
lightbend社が作ったマイクロサービスアーキテクチャ向けフレームワーク
マイクロサービスアーキテクチャ
- 2014/3にThoughtWorks社が提唱
- 小さいサービスを組み合わせて1つのアプリケーションを構築
MSAの利点
- 異なるチームで独立して開発
- コミュニケーションコストを抑える
- サービスごとに異なる技術
- サービスの特性にあった技術
- デプロイの影響範囲を小さく出来る
- 新機能や修正を早くリリースできる
- 障害を一部のサービスにとどめる
- 全体の可用性を高める
MSAの注意点
- 分散コンピューティングの落とし穴
- ネットワークは信頼できる
- レイテンシはゼロ
- 帯域幅は無限
- トランスポートコストはゼロ
- 障害点が増えて可用性が下がる
- オーバーヘッドが増えてレイテンシが大きくなる
- 大規模になるほどこの問題は目立つ→最小化したい
この問題に立ち向かうのがLagom
- リアクティブなマイクロサービス
- リアクティブを達成するための様々な道具を備える
- リアクティブシステムの性質
- 弾力性
- レジリエンス
- 即応性
- メッセージ駆動
- 道具をかかえていること
- 非同期/ノンブロッキングAPI
- シャーディングによるステートフルなアーキテクチャ
- 分散型の永続化機構
- circuit breaker
Lagomを見習ってみよう
非同期/ノンブロッキングAPI
- レイテンシを小さく
影響を受けにくくする
非同期にAPIを呼び出す − 1/5の時間で応答できる
- ブロックしてタスクを実行
- 待っている間もスレッドを専有する
相手が応答しないときに大量のスレッドを消費すること
デメリット
- 同期/ブロッキングAPIのデメリット
- 非同期/ノンブロッキングAPIのデメリット
- 特殊な書き方 学習コスト
- スレッドセーフな実装になるよう注意
- Lagomでは
- 外部サービス/DB操作のAPIはすべて非同期/ノンブロッキング
- Lagomを使わないで実現する方法
- http
- Play WS API
- Gigahorse(Scala)
- DB
- Java Driver for Apache Cassandra
- postgre-async mysql-async(Java)
- http
sharding
- 負荷分散の手法
- 単一障害点がないので高い可用性
- Lagomでは単体のサービスをスケールするときにつかう
Entity
- サービスの現在の状態を分散して持つ
- 状態はオンメモリで管理
- 状態をDBに問い合わせる必要がない
具体的なイメージ
- Chirper
- FriendEntityが実装
- FriendEntity
- User IDごとにつくられる
- ユーザー名/フォローしているユーザーのリストを状態としてもつ
Sharding
- EntityはShardというグループにわけられる
- Shardはノードに配置
- EntityをIDで識別出来るようにしておくこと
- メッセージを指定しておけば、どのShardRegionに送ってもそのIDをもつEntityに届く
障害時 べつのノードにShardが移動(復元する)
- →Entityの実装に集中できる
Lagomを使わんかったら Akka cluster shardingを使って実現する
LagomがReactiveを達成する道具
- 分散型の永続化機構
ES
- Lagomの永続化機構
- CQRSとイベントソーシングをつかう
- ES: イベントの永続化
- イベントをデータストアにINSERTしていくこと − entityの状態が失われた場合はイベントを再生して状態を復元する
イベントはイミュータブル
デメリット
- データ集計コスト
- CQRSで解決
CQRS
- コマンドクエリ責務分離
コマンドとクエリを分離できること
デメリット
- 読み込み書き込みで完全な一貫性を保てない
- 十分な時間がたつと整合性がとれる(結果整合性)
- 一時的に一貫性が取れてなくても問題ないビジネスやシステムを設計すること
- Entityをまたがる集計などを行うのに遣える
- その日の振込金額の合計
Circuit Breaker
- 外部サービスの障害時に、即時にエラーを返す仕組み
- 電子工学では電流が流れ過ぎるときに即座に電流を遮断する仕組み
- Close 回路が閉じた状態で通信
Open 回路が開いた状態で遮断
close: 外部サービスへリクエスト
- open: すぐにエラーを返す
- half-open: リクエストを試す
- リクエストが成功したらcloseに戻る
- closeのときは通信できる
- 障害が起きるとFailureCountがはじまる
- FailureCountのしきい値にたっすると、リクエストを通さなくなる
- 一定時間がたつと一時的にリクエストを通すこと
- 正常に戻るとopenになりリクエストを通すようになる
- 障害の連鎖を食い止めることができる
- 複数のサービスが連携してリクエストを処理
- 何らかの障害→依存するサービスも負荷があがる
まとめ
- モノリシックなシステムを単純に分割するだけでは可用性やパフォーマンスの問題をかかえる
Lagomはそれを解決する手がかりになるかも
Lagomは使い物になるのか
- Javaフレームワークとしては導入障壁が高い
- 導入実績がない
- バグを踏む可能性が高い
- 非同期や関数型のプログラミングパラダイム
- リアクティブな設計にはなるかも