Lagom で学ぶ
Reactive
Microservices Architecture
© 2016 TIS Inc.
1 / 92
私は何者?
根来 和輝 Negoro Kazuki
TIS株式会社 生産技術R&D室
Reactive System に関する技術検証・コンサル
Lightbend Reactive Platform
Scala / Akka / Play framework
@negokaz  negokaz
© 2016 TIS Inc.
2 / 92
今日話したいこと
Microservices の開発に役立つかもしれない 
Lagom のデザインについて
コードはあまり出てきません
© 2016 TIS Inc.
3 / 92
Lagom とは?
Lightbend社が3月にリリースした
Microservices Architecture 向けフレームワーク
内部 API は Java
コンセプトは Reactive Microservices Architecture
© 2016 TIS Inc.
https://www.lightbend.com/lagom
Reactive Microservices Architecture (O Reilly)
4 / 92
Microservices Architecture?
2014年3月に ThoughtWorks社 の Martin Fowler
によって提唱された
小さいサービスを組み合わせて
一つのアプリケーションを構築するスタイルのこと
システムを細かく分割することにより
様々な利点が得られる
(長いので以降は MSA と略します)
© 2016 TIS Inc.
5 / 92
MSAの利点
異なるチームで独立して開発できる
コミュニケーションコストを抑えることができる
サービスごとに異なる技術が使える
サービスの特性に合った技術を採用できる
デプロイの影響範囲を小さくできる
新機能や修正を早くリリースできる
障害を一部のサービスに留めることができる
全体の可用性を高めることができる
© 2016 TIS Inc.
6 / 92
MSA化の注意点
© 2016 TIS Inc.
7 / 92
MSA化の注意点
MSAにすると 分散システム になる
© 2016 TIS Inc.
8 / 92
分散コンピューティングの落とし穴
分散システムを開発するときに
想定してしまいがちな誤った前提
ネットワークは信頼できる。
帯域幅は無限である。
レイテンシはゼロである。
トランスポートコストはゼロである。
(一部抜粋)
© 2016 TIS Inc.
Wikipedia - 分散コンピューティングの落とし穴
9 / 92
つまり
モノリシックなシステムを単純に分割するだけでは
障害点が増えて可用性が下がる
オーバーヘッドが増えてレイテンシが大きくなる
大規模になるほど、この問題が目立ってくる
© 2016 TIS Inc.
10 / 92
つまり
モノリシックなシステムを単純に分割するだけでは
障害点が増えて可用性が下がる
オーバーヘッドが増えてレイテンシが大きくなる
大規模になるほど、この問題が目立ってくる
この問題を最小化したい
© 2016 TIS Inc.
11 / 92
この問題に立ち向かうのが Lagom
Lagom は Reactive な Microservices
を目指すフレームワーク
Reactive を達成するための様々な道具を備えている
その道具を用いることで
可用性
応答速度
(さらにもう一歩進んで) スケーラビリティ
を上げることができる
© 2016 TIS Inc.
12 / 92
Reactive のおさらい
© 2016 TIS Inc.
リアクティブ・アーキテクチャ ~大規模サービスにおける必要性と課題~
13 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
© 2016 TIS Inc.
14 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
これらは、Lagom でしか適用できないというものではない
MSAの開発で汎用的に使えるデザインパターンに近い
© 2016 TIS Inc.
15 / 92
Lagom を見習ってみよう!
© 2016 TIS Inc.
16 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
© 2016 TIS Inc.
17 / 92
なぜ必要か?
レイテンシを小さくする
外部サービスの障害時に影響を受けにくくする
© 2016 TIS Inc.
18 / 92
同期的にAPIを呼び出す
応答に100msかかるAPIを5つ呼び出すと...
API a
API b
API c
API d
API e
API
100ms
100ms
100ms
100ms
100ms
500ms
© 2016 TIS Inc.
19 / 92
非同期にAPIを呼び出す
応答に100msかかるAPIを5つ呼び出すと...
API a
API b
API c
API d
API e
API
100ms
100ms
© 2016 TIS Inc.
20 / 92
非同期にAPIを呼び出す
応答に100msかかるAPIを5つ呼び出すと...
API a
API b
API c
API d
API e
API
100ms
100ms
© 2016 TIS Inc.
1/5 の時間で応答を返せる!
21 / 92
ブロックしてタスクを実行する
待っている間もスレッドを専有する
Thread
Thread
SERVICE b
SERVICE a
bloking
© 2016 TIS Inc.
22 / 92
ノンブロッキングでタスクを実行する
待っている間は別のタスクを処理できる
Thread
Thread
SERVICE b
SERVICE a
© 2016 TIS Inc.
23 / 92
ブロックしてタスクを実行する
相手が応答しないとき大量のスレッドを消費する
© 2016 TIS Inc.
24 / 92
ブロックしてタスクを実行する
相手が応答しないとき大量のスレッドを消費する
© 2016 TIS Inc.
25 / 92
ノンブロッキングでタスクを実行する
相手が応答しなくてもスレッドの消費を抑えられる
Thread
Thread
SERVICE b
SERVICE a
☓
© 2016 TIS Inc.
26 / 92
非同期/ノンブロッキング API の
デメリット
同期/ブロッキング API
Response b = serviceB.request();
Response a = serviceA.request();
Integer responseSize = a.size + b.size;
doSomething(responseSize);
© 2016 TIS Inc.
27 / 92
非同期/ノンブロッキング API の
デメリット
非同期/ノンブロッキング API
CompletionStage<Response> a = serviceA.request();
CompletionStage<Response> b = serviceB.request();
CompletionStage<Integer> responseSize =
a.thenCombine(b,
(resA, resB) -> resA.size + resB.size));
responseSize.thenAccept(size -> doSomething(size));
© 2016 TIS Inc.
Java SE 8 API - CompletionStage<T>
28 / 92
非同期/ノンブロッキング API の
デメリット
非同期 API の扱いに慣れるのに学習コストが必要
スレッドセーフな実装になるよう注意する必要がある
© 2016 TIS Inc.
29 / 92
Lagom では
外部サービスの呼び出しやDBの操作をするようなAPIは
全て非同期/ノンブロッキング
© 2016 TIS Inc.
30 / 92
Lagom を使わずに実現する方法
HTTP
Play - WS API (Java/Scala)
Gigahorse (Scala)
DB
Java Driver for Apache Cassandra
postgresql-async & mysql-async (Java)
© 2016 TIS Inc.
31 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
© 2016 TIS Inc.
32 / 92
Sharding?
負荷分散の手法の一つ
単一障害点がないため高い可用性を実現できる
Lagomでは単体のサービスをスケールするのに利用される
Entity を分散させて負荷を分散する
© 2016 TIS Inc.
33 / 92
Entity?
Entity がサービスの現在の状態を分散して持つ
状態は オンメモリで管理され、
DB にバックアップされる
状態を DB に問い合わせる必要がない
レイテンシを抑えられる
Entity には位置透過性があり、ノード間を移動できる
ノードやネットワークに障害があっても復旧できる
© 2016 TIS Inc.
34 / 92
例えば?
Lagom の公式サンプルアプリ Chirper では
FriendEntity が実装されている
FriendEntity
User ID ごとに作られる
ユーザー名、フォローしているユーザーのリストを
状態として持つ
© 2016 TIS Inc.
35 / 92
Sharding?
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
© 2016 TIS Inc.
Entity は Shard というグループに分けられる
36 / 92
Sharding?
Node
Node
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
© 2016 TIS Inc.
Shard は Node(サーバ) に配置される
37 / 92
Sharding?
Node
Node
ShardRegion
shard
Entity
Entity
shard
Entity
Entity
ShardRegion
shard
Entity Entity
© 2016 TIS Inc.
Shard は Node ごとに ShardRegion というグループになる
38 / 92
Sharding?
Node
Node
ShardRegion
shard
Entity
Entity
shard
Entity
Entity
ShardRegion
shard
Entity Entity
ID
© 2016 TIS Inc.
各 Entity を ID で識別できるようにしておくと
39 / 92
Sharding?
Node
Node
ID
ShardRegion
shard
Entity
Entity
shard
Entity
Entity
ShardRegion
shard
Entity Entity
ID
© 2016 TIS Inc.
メッセージで ID を指定しておけば、どの ShardRegion
に送ってもその ID を持つ Entity に届く
40 / 92
Sharding?
Node
Node
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
© 2016 TIS Inc.
もしも…
41 / 92
Sharding?
Node
Node
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
© 2016 TIS Inc.
Node に障害が起きたら
42 / 92
Sharding?
Node
Node
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
shard
Entity Entity
shard
Entity Entity
© 2016 TIS Inc.
別のノードに Shard が移動 (復元) する
43 / 92
Sharding?
Node
Node
shard
Entity
Entity
shard
Entity
Entity
shard
Entity Entity
shard
Entity Entity
© 2016 TIS Inc.
新しいノードを追加すると
44 / 92
Sharding?
Node
Node
shard
Entity Entity
shard
Entity
Entity
shard
Entity
Entity
shard
Entity Entity
© 2016 TIS Inc.
シャードが分散(リバランス)される
45 / 92
Lagom では
この仕組みは Lagom によって提供される
© 2016 TIS Inc.
46 / 92
Lagom では
この仕組みは Lagom によって提供される
私たちは Entity の実装に集中できる
© 2016 TIS Inc.
47 / 92
Lagom を使わずに実現する方法
Akka - Cluster Sharding (Java/Scala)
© 2016 TIS Inc.
48 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
© 2016 TIS Inc.
49 / 92
分散型の永続化機構
Lagom は Event Sourcing と CQRS による永続化のしくみ
を備えており、データの読み込みと書き込みの両方を
スケールできるようになっている
© 2016 TIS Inc.
50 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
51 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 0 円
52 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 0 円口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 10,000 円
10,000円 振込
53 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 0 円口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 10,000 円
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 8,000 円
10,000円 振込
54 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 0 円口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 10,000 円
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 8,000 円
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 18,000 円
10,000円 振込
10,000円 振込
55 / 92
Event Sourcing?
システムの中で起きたイベントを永続化する
イベントをデータストアに INSERT していく
© 2016 TIS Inc.
口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 0 円口座番号:10の口座を開設
Event Entity State
口座番号: 10, 残高: 10,000 円
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 8,000 円
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 18,000 円
10,000円 振込
10,000円 振込
口座番号:10の口座を開設
Event Entity State
2,000円 引出
口座番号: 10, 残高: 18,000 円
10,000円 振込
10,000円 振込
56 / 92
Event Sourcing?
Entity の状態が失われた場合は、
イベントを 再生 して状態を復元する
イベントは不変(immutable)
ロック不要・複数のノードに分散して書き込める
書き込みをスケールしやすい
キャッシュ・コピー・共有が容易
読み込みをスケールしやすい
データの耐久性を高くできる
© 2016 TIS Inc.
57 / 92
Event Sourcing?
デメリット
データの集計にコストがかかる
© 2016 TIS Inc.
58 / 92
Event Sourcing?
デメリット
データの集計にコストがかかる
CQRS で解決できる
© 2016 TIS Inc.
59 / 92
CQRS?
Command and Query Responsibility Segregation
コマンドクエリ責務分離
コマンド(書き込み)とクエリ(読み込み)を分離する
Command
Query
Command
Query
© 2016 TIS Inc.
60 / 92
CQRS?
Command
Query
Command
Query
書き込み側と読み込み側で
異なるDB・データ構造が使える
別々にスケールできるようになる
Command-Side に Event Sourcing を使い
Query-Side に集計しやすい形で永続化する
© 2016 TIS Inc.
61 / 92
CQRS?
Command-Side
Query-Side
Query
Store
Event
Store
EventProcessor
Service
Polling 
Update State 
Command
Query
API Call 
API Call 
Entity
Entity
Entity
© 2016 TIS Inc.
62 / 92
CQRS?
デメリット
書き込み・読み込みで完全な一貫性を保てない
十分な時間が経つと整合性がとれる (結果整合性)
一時的に一貫性が取れてなくても問題ないよう
ビジネスやシステムを設計する
Entity をまたがる集計などを行うのに使える
例) その日の振込金額の合計
© 2016 TIS Inc.
63 / 92
Lagom を使わずに実現する方法
Akka Persistence + Akka Persistence Query (Java/Scala)
© 2016 TIS Inc.
64 / 92
Lagom が Reactive を達成する道具
非同期/ノンブロッキングなAPI
Sharding によるステートフルなアーキテクチャ
分散型の永続化機構
Event Sourcing + CQRS
Circuit Breaker
© 2016 TIS Inc.
65 / 92
Circuit Breaker とは?
外部サービスの障害時、即座にエラーの応答を返す仕組み
リトライによるネットワーク帯域の無駄遣いが減る
レイテンシを低く抑えられる
障害の連鎖を抑えることができる
Close・Open・Half-Open の状態をとる
© 2016 TIS Inc.
引用: Lagom #Consuming services
66 / 92
Open? Close?
Circuit Breaker はもともと電子工学の言葉
電流が流れすぎているときに電流を遮断する保護回路
Open
Close
Close: 回路が閉じた状態 = 通信できる
Open: 回路が開いた状態 = 通信が遮断されている
© 2016 TIS Inc.
67 / 92
Circuit Breaker のしくみ
Close: 外部サービスへリクエストする
Open: すぐにエラーを返す
Half-Open: リクエストを試す
Open から一定時間で切り替わる
リクエストが成功したら Close に戻る
© 2016 TIS Inc.
引用: Lagom #Consuming services
68 / 92
Circuit Breaker の動き
Close のときは通信できる
© 2016 TIS Inc.
Service Service
Circuit Breaker
Close, FailureCount: 0
69 / 92
Circuit Breaker の動き
外部のサービスに障害が起きて…
© 2016 TIS Inc.
ServiceService
Circuit Breaker
Close, FailureCount: 0
70 / 92
Circuit Breaker の動き
正しくレスポンスが受け取れなくなると FailureCount
のカウントが始まる
© 2016 TIS Inc.
Service Service
Circuit Breaker
Close, FailureCount: 1
71 / 92
Circuit Breaker の動き
外部サービスへリクエストするたびに FailureCount
が増えて
© 2016 TIS Inc.
Service Service
Circuit Breaker
Close, FailureCount: 2
72 / 92
Circuit Breaker の動き
増えて...
© 2016 TIS Inc.
Service Service
Circuit Breaker
Close, FailureCount: 3
73 / 92
Circuit Breaker の動き
FailureCount のしきい値に達すると、Open になって
© 2016 TIS Inc.
Service Service
Circuit BreakerCircuit Breaker
Open, FailureCount: 3
74 / 92
Circuit Breaker の動き
リクエストを通さなくなり、
Circuit Breaker 自身がエラーの応答を返すようになる
© 2016 TIS Inc.
Service Service
Circuit BreakerCircuit Breaker
Open, FailureCount: 3
75 / 92
Circuit Breaker の動き
ある一定時間が経つと、Half-Open になり
一時的にリクエストを通すようになる
© 2016 TIS Inc.
Service Service
Circuit BreakerCircuit Breaker
Half-Open, FailureCount: 3
76 / 92
Circuit Breaker の動き
その時に外部サービスが正常に戻っていると
© 2016 TIS Inc.
Service Service
Circuit BreakerCircuit Breaker
Half-Open, FailureCount: 3
77 / 92
Circuit Breaker の動き
Open になり、リクエストを通すようになる
© 2016 TIS Inc.
Service Service
Circuit BreakerCircuit Breaker
Close, FailureCount: 0
78 / 92
障害の連鎖を食い止める
復数のサービスが連携してリクエストを処理している
© 2016 TIS Inc.
Service
79 / 92
障害の連鎖を食い止める
あるサービスが何らかの障害で過負荷になって
リクエストを処理できなくなった
© 2016 TIS Inc.
Service
80 / 92
障害の連鎖を食い止める
そのサービスに依存するサービスにもリクエストが溜まり
負荷が高くなる
© 2016 TIS Inc.
Service
81 / 92
障害の連鎖を食い止める
さらにそのサービスに依存するサービスにも... (ry
© 2016 TIS Inc.
Service
82 / 92
障害の連鎖を食い止める
Circuit Breaker を使うことによって、
この障害の連鎖を食い止めることができる
© 2016 TIS Inc.
Service
C
B
C
B
CB
C
B
C
B
CB
C
B
C
B
83 / 92
Lagom では
外部へのリクエストは全て Circuit Breaker を通じて行う
Caller
Service
CB
Callee
Service
Caller
Service
C
B
© 2016 TIS Inc.
84 / 92
Lagom を使わずに実現する方法
Netflix - Hystrix (Java)
Akka - Circuit Breaker (Java/Scala)
© 2016 TIS Inc.
85 / 92
まとめ
モノリシックなシステムを単純に分割するだけでは、
可用性やパフォーマンスの問題を抱えることになる。
Lagom のデザインはその問題を解決するための
参考になるかもしれない。
© 2016 TIS Inc.
86 / 92
まとめ
各デザインが改善する非機能要件
デザイン 高可用性 低レイテンシ スケーラビリティ
非同期/ノンブロッキング ○ ○ -
Sharding ○ - ○
Event Sourcing + CQRS ○ ○ ○
Circuit Breaker ○ ○ -
© 2016 TIS Inc.
87 / 92
Lagom は使いものになるのか?(私見)
Javaのフレームワークとしては導入障壁は高い
実績
導入事例がまだ出てきていない
バグを踏む可能性が高い
実装の難しさ
非同期や関数型のプログラミングパラダイム
© 2016 TIS Inc.
88 / 92
Lagom は使いものになるのか?(私見)
Javaのフレームワークとしては導入障壁は高い
実績
導入事例がまだ出てきていない
バグを踏む可能性が高い
実装の難しさ
非同期や関数型のプログラミングパラダイム
ただし、Reactive な設計の参考にはなる
© 2016 TIS Inc.
89 / 92
リアクティブ・システム
コンサルティングサービス
Akka / Play / Scala / 本日ご紹介した設計パターン
POC
設計レビュー
コードレビュー
システム構築
© 2016 TIS Inc.
https://www.tis.jp/service_solution/goreactive/
TIS は Lightbend 社の認定コンサルティングパートナーです
90 / 92
質問ありますか?
© 2016 TIS Inc.
91 / 92
参考資料
Lagom 公式ドキュメント:
https://www.lightbend.com/lagom
Reactive Microservices Architecture (O Reilly)
マイクロサービスアーキテクチャ (O Reilly)
イラスト
いらすとや: http://www.irasutoya.com/
© 2016 TIS Inc.
92 / 92

Lagom で学ぶ Reactive Microservices Architecture @ 第3回Reactive System Meetup in 西新宿