Slide 1

Slide 1 text

マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか joker1007 (Repro株式会社) Rails Tokyo 02 1

Slide 2

Slide 2 text

自己紹介 橋立友宏 (@joker1007) Repro株式会社 チーフアーキテクト 元々はRailsエンジニアだったが、最近は Javaばかり書いている 日本酒とクラフトビールが好き 2

Slide 3

Slide 3 text

Asakusaから来ました 3

Slide 4

Slide 4 text

Kaigi on Railsで登壇しました https://speakerdeck.com/joker1007/jin-gai-meteservicekurasunituitekao-eru- arurailskai-fa-zhe-no10nian 今回はもうちょっと個別の事例の話をします。 4

Slide 5

Slide 5 text

最近の仕事 チーフアーキテクトとして、サービス全体の中長期的な技術選定、設計アドバイス、全体アー キテクチャのデザインなどをしている。 5

Slide 6

Slide 6 text

Reproの事業 マーケティングオートメーションサービスを提供している。 マーケティングオートメーションとは、 ユーザーの行動を分析・分類し 複数のチャネルで適切なキャンペーンを配信することで 顧客とエンドユーザーのコミュニケーションを支援する SaaS事業だけでなく、サービスグロースの総合的な支援も提供しています。 6

Slide 7

Slide 7 text

Reproでは大体5〜6年ぐらい前からマイクロサービス 化に舵を切ってシステムを分割してきた。 マイクロサービスが語られる様になってしばらく経っ たが、やってみて実際どうだったのか?という話は余 り無いと思うのでその辺りを話していきたいと思う。 余談だが、最近Twilioがマイクロサービス上手くいかなかったので止めた、という記事を書い ていた。 https://www.twilio.com/en-us/blog/developers/best-practices/goodbye- microservices かなり近い領域の話ではあるが、それはダメなんでは?と思うことも色々あった。 7

Slide 8

Slide 8 text

最初に結論から ここ5年ぐらいの活動と現状を振り返ってみて、一定の成功を得たと認識している。 得たもの 複雑かつ重要度の高いコンポーネントの分離・安定化 開発速度の向上 スケーラビリティの向上、必要な範囲の局所化 パフォーマンスの向上 8

Slide 9

Slide 9 text

そもそもの背景や成り立ちについて Excuse: 教科書的なやり方と違うけどなんとかなった、という割と身も蓋もな い話が含まれます。そのままでは参考にならないかもしれません 9

Slide 10

Slide 10 text

組織的な要請ではなくアーキテクチャが先 よく言われるやり方: 逆コンウェイ戦略によって、組織構造を先にデザインしてからアーキテ クチャに疎結合化に至る様なフォースを与える。 自分の戦略: これと逆でアーキテクチャから先に作った。 10

Slide 11

Slide 11 text

なぜこれで形に出来たのか 端的に言えば全体の8割ぐらいを自分が作って、自分と距離の近いチームで運用する箇所をじ わじわ増やしていったから。 現在10を越えるマイクロサービスがあるが、その大半を自分一人で設計し初期構築している。 運用フェーズに入ってからも初期は自分一人で大半のオンコールを受けてた。 (段階的にキャッチアップしてもらって、今はその状況は脱却済み) つまり個人の腕力でなんとかしたというのが現実。 11

Slide 12

Slide 12 text

事業ドメインとの相性 自分の中で事業ドメインとアーキテクチャの方向性を考えた時にある程度自信があった。 エンドユーザーの行動ログを受け取って、出来る限り素早く集計・分類し、コン テンツ配信に繋げる 大抵の処理は非同期かつエンドユーザーに見えない形で行われる データ量が多く高いスケーラビリティが求められる 最終的なコンテンツは多様なチャネルによって配信される トランザクションで守る範囲は限定的 これらの特性を考慮すると、イベント駆動のストリームパイプライン構築が合理的だと考え た。 12

Slide 13

Slide 13 text

イベント駆動マイクロサービスの利点 システム間の独立性が高くサービス追加が容易 -> 配信チャネルごとのワーカー管 理・新規開発の効率向上 スケールアウトの親和性が高い -> 大量のデータ入力に対応 準リアルタイム処理への親和性が高い -> スピーディな集計と分類 非同期処理が基本 -> エンドユーザーにレスポンスを返す必要が無いケースと相性 が良い 13

Slide 14

Slide 14 text

組織構造が後から変化 しばらくアーキテクチャ先行で分離とコンポーネントグループを構築して維持してきたこと で、 最終的に組織構造がそちらに合う様に変化してきた。 現時点では組織構造とアーキテクチャはそこまで乖離していない形に落ち着いたと思う。 14

Slide 15

Slide 15 text

ここまでのまとめ 事業ドメインへの理解を深め、アーキテクチャ転換に自信を得た ある程度の強権を発動して腕力でマイクロサービス化を推進 現実としてコンウェイの法則に影響は受けているが、逆コンウェイ戦略がそんな に有効かというと個人的には微妙な印象 15

Slide 16

Slide 16 text

道程の中で意識した理屈 全体の推進として理屈を無視しているところはあるが、システム分割を進める上で守っておか ないとまずいと認識していたことは多い。 16

Slide 17

Slide 17 text

結合と変更範囲のコントロール 原則: あるサービスは他のサービスと独立して変更できなければならない もちろん現実として無理な時はあるが、大抵の変更はこうでなければならない。 特に分離元のRailsアプリケーションの変更に影響を受ける訳にはいかない。 17

Slide 18

Slide 18 text

非常に参考になる本が 登場 読んで改めて言語化して認識できたこと 重要なことは予期せぬ変更の波 及をコントロールすること 結合強度 x 距離 x 変更頻度 の 次 元によって安定度が評価できる モジュール間の結合のパターン と特性 ソフトウェア設計の再帰的な性 質 当時はこの本は無かったが意識していた 18

Slide 19

Slide 19 text

スキーマ管理の徹底 マイクロサービスは必然的にサービス間のやり取りをRESTやgRPCなどのAPIやメッセージに 頼ることになる。 転送メッセージのスキーマが正しいなら正しく動くという規約を維持することが重要。 それ以上結合強度が上がると、別々のシステムを同時に変更しデプロイするという作業が頻発 する可能性が上がる。 先の本の言葉を借りれば、コントラクト結合かモデル結合に結合強度を抑える。 そのために重要なのがスキーマ管理の仕組み。 19

Slide 20

Slide 20 text

Schema Registryの活用 大半のスキーマは独立したリポジトリに配置し、特定のサービスに所属させない 共通の基盤として扱う。 Schema Registryサービスを立て、各サービスは自分が必要なスキーマをレジスト リから取得可能にする。 Schema Registryの機能で互換性のチェックを行い、後方互換性を壊す変更を拒 否しスキーマの変更がサービスに与える影響を予測しやすくする。 各サービスにライブラリとして組込む場合もあるため、社内で利用している主要言語のパッケ ージも作ってある、 20

Slide 21

Slide 21 text

コアドメインを先にやる しばしば聞く話では認証基盤などを分割してマイクロサービスにしているケースはよくある。 これは事業戦略上の必要性もあると思うが、責務が明確なのでやり易さもある。 しかし、マイクロサービスアーキテクチャによって開発体験にインパクトを与えるなら、業務 ドメインにおいて重要で価値が高い箇所に目を向けるべきだと思う。 難しいところが乗り越えられれば、後の分割作業は経験によって予測可能になる。 21

Slide 22

Slide 22 text

完全に乗せ替えるまで先に進まない あるドメインを分離して別サービスとして立て直すことを決めたなら、それをやり切るまで可 能な限り作業を止めない。 新・旧両方ある状態はほとんどの場合で旧バージョンだけより辛い。やり切るまでプラスの成 果は来ないと覚悟する。 22

Slide 23

Slide 23 text

依存関係のコントロール データの流れ、処理の流れを一つの方向にまとめる。 イベントとユーザー情報の入力が起点なので、そこに起因する動きを逆戻りさせ ない。 上流と下流が処理の中で入れ替わる様なことをしない。 複雑な処理は、終端から発生した完了イベントを再度入力することで実現する 全体を大きなイベントループとして構成する 23

Slide 24

Slide 24 text

オブザーバビリティの重要性 マイクロサービス化に伴ってシステムの全体像は確実に把握が難しくなる。 対抗する手段としてオブザーバビリティの重要性が高くなる。 構築当初からサービスが適切に動いているか、処理が遅延していないかを測定するメトリック は取っていて運用開始前にアラートモニタも整えた。 分散トレーシングはしばらく経ってから導入したが、きっちりトレースが繋がって全体像が把 握できる様に作り込まないと効果が薄くなるので、ある程度時間を取って一気に導入を進め た。 OpenTelemetryが洗練されてきて分散トレーシングを取得するのは昔より容易になってい る。 今後も確実に必要になるのでキャッチアップをオススメする。 24

Slide 25

Slide 25 text

サービスマップの例 25

Slide 26

Slide 26 text

可能な限り非同期に 同期処理は結合強度を上げ、サービス間を跨ぐ時に変更を難しくする。 同期処理は出来る限り同一サービス(同一チームでデプロイ責任が取れる範囲)内に留めてお く。 Reproの場合は重要なトラフィックの大半がユーザーへの応答を必要としないので、この辺り は相性が良かった。 26

Slide 27

Slide 27 text

一方で、今のところ諦めている理屈 もちろん上手くいっていないことも存在する。 27

Slide 28

Slide 28 text

データベース分割できてない 各サービスが触るデータベースをきっちりインスタンスレベルで分けていない。 但し、書き込みの責任だけはシングルポイントになる様にきっちり守っている。 読み込みに関しては過渡期(もう5年経ってるが……)として許容している。 段階的にDebezium(CDC)を利用してこちらもイベント駆動のメッセージとして処 理できる様に移行しつつあるが、まだ道半ば。 実際、大体の主要な開発案件の方針を自分が一旦レビューしてるのでなんとか守れているとい う現実がある。 (なので余り大丈夫ではない。多分目を離すと危ない。 ) 28

Slide 29

Slide 29 text

解消しきれていないトレードオフ 29

Slide 30

Slide 30 text

変更波及を抑え切れない 根本的に新しいことをやるなら、広い範囲に渡って複数のコンポーネントを修正 しなければならないこともしばしば。 なんとかデプロイ自体が余りブロック要因にならない程度には独立して作業出来 ている しかし、各チーム間で協調してスケジュールを合わせなければならないし、進捗 のボトルネックをコントロールしづらいことも多い → スケジュール遅延に繋がる 30

Slide 31

Slide 31 text

統合テストが非常に難しい Kafkaを中心にした分散ストレージ系のミドルウェア、AWSのコンポーネントに大 きく依存しているので機械的にテストするのがとても難しい サービス境界自体を出来る限り明確にしてスキーマとメッセージの期待が満たさ れているかで判断し、各コンポーネントの中でテストされていると信じるしかな い サービス内部のテストはきっちり書く 後は手動で動作確認する受け入れテストに依存、但し問題が起きると工程が多い のでどこが原因か特定するのにコツや知識が要る ただ、これでも以前よりはプラスになっている状況。 31

Slide 32

Slide 32 text

最後に Railsの世界でこれからそういうことをやるなら、い きなりマイクロサービスはかなりの自信が無い限りオ ススメしない。 今日話した理屈はモジュラーモノリスにも通用すると 思う。 自分は今モジュラーモノリスで仕事をしてないが、これからやるなら次の様なことを意識す る。 32

Slide 33

Slide 33 text

コンポーネント境界のI/Fを定義する packwerkでパッケージへの依存はチェックできるが、それとは別にモジュールの外からの呼 び出しを受け付ける箇所を明確にする。 ただ依存関係をチェックするだけで設計が洗練される訳ではない。 外から触っていいのは基本的にコントローラー、サービス、ジョブ辺りだと思う。 モデルのメソッドを直接呼ぶのは警戒した方が良い。 外部との接点には型を書く。 I/Fの破壊に気付き易くなるし、ドキュメント・補完で利用方法をガイドできる。 コントローラー呼び出しを挟むならスキーマ管理機構は必須。 この辺り、モジュラーモノリスでもマイクサービスでもやる事は余り変わらない。 33

Slide 34

Slide 34 text

デプロイ速度、CI速度の改善 マイクロサービスの大きな利点の一つは、開発の並列性の高さ。 モジュラーモノリスで同様に開発進捗の競合を起こしにくくするには、以下の様なこともやっ ておきたい。 CI実行の高速化(範囲の限定やマージフローの改善なども) 日常の開発ペースに直結する エージェントコーディングで更に重要度が増してるかも デプロイの高速化 フィーチャーフラグの活用 要は現代的な開発フローをちゃんと洗練させる。 34

Slide 35

Slide 35 text

所感と成功要因のまとめ 所感: 解消しきれていないトレードオフがあるとはいえ、割と上手くマイクロサービスやれて いるという実感はある。 成功要因: ビジネスドメインの親和性 自分の時間を投資させてもらえた 時間をかけて安定性を向上させる活動 妥協の中でも守るべきことをちゃんと考えた 変更の波及をコントロールするための結合のやり方を考えた 初期構築時点で運用のために必要なものは作り込む 35

Slide 36

Slide 36 text

そして、この本とても 良いのでオススメ 今日の話の様なサービス分割の際に、考 えるための軸や定量的な評価方法を示し てくれる。 36

Slide 37

Slide 37 text

ご静聴ありがとうございました そして、皆の事例も聞きたい 37