$30 off During Our Annual Pro Sale. View Details »

信頼性と柔軟性向上のためのマイクロサービスのリアーキテクティング/architecture-redesign-of-microservices-for-improved-reliability-and-flexibility

 信頼性と柔軟性向上のためのマイクロサービスのリアーキテクティング/architecture-redesign-of-microservices-for-improved-reliability-and-flexibility

長年運用してきたマイクロサービスが成長して複雑になったときに、管理、システム両方のアーキテクチャのリデザインを行い、信頼性と柔軟性が高いマイクロサービスを構築するための方法を事例ベースで共有します。

以下イベントでの登壇資料です。
https://event.shoeisha.jp/devsumi/20230727

hirai.kazushi

July 27, 2023
Tweet

More Decks by hirai.kazushi

Other Decks in Technology

Transcript

  1. 信頼性と柔軟性向上のための
    マイクロサービスのリアーキテクティング
    Kazushi Hirai

    View Slide

  2. ⾃⼰紹介
    l 所属︓
    l LINE Fukuoka 株式会社
    l 開発1室 Kチームマネージャ
    l サーバサイドエンジニア
    l 興味︓
    l 家族(娘、息⼦), 体を動かすこと, マラソン
    l Twitter: @hkazushi0627
    ฏҪ Ұ࢙
    ,";64)*)*3"*

    View Slide

  3. アジェンダ
    l 背景
    l マイクロサービス運⽤の問題
    l リア―キテクチャの進め⽅
    l リア―キテクチャのパターン

    View Slide

  4. 背景
    l 担当プロダクト
    l 技術スタック
    l システムアーキテクチャ
    l プロダクトの歴史

    View Slide

  5. LINE STORE
    担当プロダクト
    LINE STORE
    スタンプショップ 着せかえショップ オートサジェスト おすすめスタンプOA

    View Slide

  6. LINE STORE
    技術スタック
    l 開発⾔語︓
    l Java, Kotlin (JVMで動作する⾔語)
    l フレームワーク︓
    l Spring Boot
    l Armeria/Central Dogma/Decaton(LINE OSS)
    l ストレージ︓
    l MySQL, MongoDB, Elasticsearch, Redis
    l インフラストラクチャ︓
    l Verda (プライベートクラウド)
    l VM(仮想マシン), Kubernetes

    View Slide

  7. LINE STORE
    システムアーキテクチャ
    l LINE全体が⼤きなマイクロサービス
    l チームの構造にあわせて、マイクロサービスを構成
    l 逆コンウェイの法則
    l 各チーム内でもマイクロサービスで運⽤
    LINE全体
    Shopのマイクロサービス

    View Slide

  8. 歴史 – 2011年
    2012
    スタンプショップ
    リリース
    2013
    LINE STOREリリース
    2014
    LINE着せかえ
    LINEクリエイターズスタンプ
    2017
    年賀キャンペーン開始
    LINE公式アカウントからの
    おすすめスタンプ⾃動配信
    2018
    LINE絵⽂字
    2019
    LINEスタンプ プレミアム
    2020
    メッセージスタンプ
    LINEスタンプ プレミアム
    デラックスコース
    2021
    LINEスタンプ プレミアム
    台湾、インドネシア
    LINEアニメーション絵⽂字
    2011
    LINEリリース
    2022
    LINEスタンプ プレミアム
    LINE Music
    LINEMO バンドル
    l サーバサイドエンジニア︓10⼈未満
    l エンジニアのチーム数︓2 (プロダクトチーム)
    l マイクロサービスのコンポーネント数︓3
    サービスローンチ当初の構成

    View Slide

  9. 歴史 – 現在
    2012
    スタンプショップ
    リリース
    2013
    LINE STOREリリース
    2014
    LINE着せかえ
    LINEクリエイターズスタンプ
    2017
    年賀キャンペーン開始
    LINE公式アカウントからの
    おすすめスタンプ⾃動配信
    2018
    LINE絵⽂字
    2019
    LINEスタンプ プレミアム
    2020
    メッセージスタンプ
    LINEスタンプ プレミアム
    デラックスコース
    2021
    LINEスタンプ プレミアム
    台湾、インドネシア
    LINEアニメーション絵⽂字
    2011
    LINEリリース
    2022
    LINEスタンプ プレミアム
    LINE Music
    LINEMO バンドル
    現在の構成
    2023 現在
    l サーバサイドエンジニア︓30⼈以上
    l エンジニアのチーム数︓6以上 (プロダクト・フィーチャーチーム、SRE)
    l マイクロサービスのコンポーネント数︓80以上

    View Slide

  10. モノレポ
    l すべてのコンポーネントを1つのGitHubリポジトリで管理
    l メリット︓
    l 横断したコンポーネントの開発
    l 共通モジュールの構成のしやすさ
    l ライブラリやフレームワークのバージョンを統⼀
    l デメリット︓
    l コンポーネント数が増えてくると、可視性が低下、
    管理が複雑化
    l ビルド、CIの遅延
    l 意図しないバージョンアップによる不具合、障害の発⽣
    Component A
    Component B
    Component C
    Repository

    View Slide

  11. マイクロサービス運⽤の問題
    l コンポーネント数の過多
    l コンポーネントのモノリス化
    l コンポーネントのパフォーマンス、信頼性低下

    View Slide

  12. コンポーネント数の過多
    l 問題︓
    l マイクロサービスやコードベースの学習が困難
    l それぞれのコンポーネントがどのプロダクト、機能を担当するのか不明確
    l 各コンポーネントの担当者が不明確
    l コンポーネントについて質問したい時、
    何か変更を⾏ってソースレビューしてほしいとき、だれが適切なのか︖
    l 既存メンバーであっても、よくわかってないケースが多い

    View Slide

  13. コンポーネントのモノリス化
    l 問題︓
    l 開発やリリースの⼿軽さから、既存のコンポーネントに
    責務が異なる機能が追加される
    l モノリシックで、⾊々な機能をもったゴッドコンポーネントが発⽣
    l モノリシックなコンポーネントは、機能や依存関係が複雑
    l 開発、テスト、デプロイメントも複雑化
    l 単⼀障害点になり、信頼性が低下する可能性

    View Slide

  14. コンポーネントのパフォーマンス、信頼性低下
    l 問題︓
    l マイクロサービスを⻑期間運⽤していると、初期に想定していた
    キャパシティと実際のデータ数やデータ量が乖離する場合がある
    l 要因︓
    l ユーザ数の増加や需要の変化
    l ストレージのデータの増加
    l 結果︓
    l 特定のコンポーネントで、レイテンシ・パフォーマンスの低下
    エラー数の増加
    l 問題が継続すると、マイクロサービス全体が不安定になり
    信頼性が低下

    View Slide

  15. マイクロサービス運⽤の問題
    l コンポーネント数の過多
    l コンポーネントのモノリス化
    l コンポーネントのパフォーマンス、信頼性低下
    管理・システム両⽅のリアーキテクチャで
    信頼性が⾼い、かつ柔軟なマイクロサービスを構築する

    View Slide

  16. リアーキテクチャの進め⽅
    l コンポーネントドメインの導⼊
    l コードベース上でドメインを表現
    l コードオーナーの導⼊
    l コンポーネントドメインの定義⽅法

    View Slide

  17. コンポーネントドメインの導⼊
    l コンポーネントを論理的にグルーピングする
    l グループ = コンポーネントドメイン
    l ハイレベルな図を⽤いることで、シンプルになり全体の学習コストが下がる
    ドメイン図(ハイレベル)
    コンポーネント図(詳細)

    View Slide

  18. コードベース上でドメインを表現
    l リポジトリの階層で、ドメインとコンポーネントの関係を表現
    l リポジトリのトップレベル = ドメイン
    l トップレベル配下 = ドメインに含まれるコンポーネント
    store/
    + store-server
    + store-cms
    + store-decaton
    shop/

    subscription/

    リポジトリの構成
    ドメイン
    コンポーネント

    View Slide

  19. コードオーナーの導⼊
    l ドメイン単位でコードオーナーを設定して、担当者を明確にする
    l GitHubであれば、テキストファイルにコードオーナーを設定できる
    l プルリクエスト作成時に、コードオーナーが⾃動でレビューワーに設定
    store/
    + store-server
    + store-cms
    + store-decaton
    shop/

    subscription/

    /store/ @kazushi-hirai @xxx @yyy
    /shop/ @aaa @bbb
    /subscription/ @ccc @ddd

    リポジトリの構成 .github/CODEOWNERS プルリクエスト

    View Slide

  20. コンポーネントドメインの定義⽅法
    1. 各コンポーネントの役割、責務を明確にする
    l 複数の責務を持っているコンポーネントがあれば、分割の候補に加える
    l 過度に分割しすぎると、コンポーネントの数が増え、複雑さが増すので注意が必要
    2. ビジネス機能の関連性でコンポーネントをグルーピング = ドメインを定義
    課題 どのような単位、ルールでドメインを定義するのか︖

    View Slide

  21. コンポーネントドメインの定義⽅法
    l ドメインが所有するデータやストレージを明確にする
    l ドメイン内のコンポーネントのみが、所有するストレージに直接アクセスに制限
    l メリット︓
    l 内部・外部の依存関係の明確化
    l セキュリティ対策やアクセス制御などの追加が容易
    l ストレージ変更時・障害時の影響範囲が明確で、円滑に対応できる

    View Slide

  22. 課題 複数ドメインでストレージを共有している場合はどう対応するか︖
    コンポーネントドメインの定義⽅法
    l リアーキテクチャが必要
    l ⾮所有ドメインからは公開API経由でデータにアクセス
    l データベースをドメインごとに分割
    複数ドメインでストレージを共有
    リアーキテクチャ
    データベース分割
    公開API経由に変更

    View Slide

  23. リア―キテクチャのパターン
    l ⾮同期メッセージングアーキテクチャ
    l CQRS (Command Query Responsibility Segregation)

    View Slide

  24. ⾮同期メッセージングアーキテクチャ
    l 送信者と受信者は直接通信を⾏わず、メッセージングキューを介して
    データをやりとりする
    l メリット︓
    l 応答性の向上︓送信者がメッセージを送ると、直ちに応答が返る。
    結果を待たない。
    l 疎結合・独⽴性︓メッセージキューにデータが⼀時保存されるので、
    受信者側でリトライ処理やレートリミットが可能 = 信頼性の向上

    View Slide

  25. KafkaとDecaton
    l Apache Kafka
    l 分散メッセージングシステム
    l ⾼い信頼性・スケーラブル
    l LINE共通のKafkaクラスタが使⽤できる
    l Decaton
    l Kafka Consumerライブラリ
    l LINEのOSS https://github.com/line/decaton
    l パーティションをマルチスレッドで同時に処理
    l リトライ、レートリミッター機能が標準装備で、別途開発する必要がない

    View Slide

  26. ⾮同期メッセージングアーキテクチャの活⽤例
    l 活⽤例︓LINE公式アカウントからのメッセージ配信
    l LINEのMessaging APIを使って、アプリケーションからメッセージを配信
    l メリット︓
    l スケーラブルで、信頼性の⾼いサービスの構築
    l エラー発⽣時のリトライとレートリミットへの対策
    Consumer(受信者)は
    Decatonを使って開発
    リトライ⽤トピック
    送信者

    View Slide

  27. ⾮同期メッセージングアーキテクチャの活⽤例
    パーティション毎にQPSを設定
    Messaging APIのレートリミット
    (2,000QPS) への対策
    最⼤30分のエラーに
    耐えられるように設定
    リトライ間隔と
    最⼤リトライ回数を設定
    課題 エラー発⽣時のリトライとレートリミットへの対策

    View Slide

  28. 開発を⾏う上で⼯夫した点
    l 各コンポーネントの役割を明確にして、機能を実装
    Producer(送信者)
    l Kafkaにメッセージ送信
    l LINEメッセージのデータ(JSON)の作成
    Consumer(受信者)
    l Messaging APIのコール
    l リトライ・レートリミット
    配信するLINEメッセージのデータに新規追加や変更が発⽣しても、
    Producerのみの開発、デプロイで対応可能 = Consumerの再利⽤性が向上
    メリット

    View Slide

  29. CQRS
    l CQRS = Command Query Responsibility Segregation
    l データ更新(コマンド)とデータ取得(クエリ)を分離、別のモデルとして扱う
    l CQRSを使って、コマンドの役割を持つコンポーネントとクエリの役割を持つ
    コンポーネントで、マイクロサービスを構成する
    l メリット︓
    l コマンドとクエリに対して、異なるスケーリングやアーキテクチャの適⽤が
    可能

    View Slide

  30. CQRSの活⽤例
    l 活⽤例︓スタンプのデータ管理
    l クエリのクライアントはLINEのユーザ、コマンドのクライアントはスタンプ制作者
    l コマンド数よりも圧倒的にクエリー数が多い
    l クエリのパフォーマンス向上のため、Elasticsearch(Read Storage)とRedis(Cache)を使⽤
    l MySQLとElasticsearchはバッチ処理で⾮同期にデータ同期
    登録完了から参照可能までに遅延が
    発⽣するが、機能要件として許容

    View Slide

  31. CQRSの活⽤例
    l 活⽤例︓あけおめスパイクへの対策
    l 新年0時のタイミングで、毎年クエリ数のスパイクが発⽣する
    l 対策として、Elasticsearchを⼀定期間デュアル構成にして負荷分散
    1/1の0時あたりのRPS︓
    コマンドのアーキテクチャ変更なしに
    クエリ側をより柔軟に変更可能
    メリット

    View Slide

  32. CQRSの活⽤例
    l 活⽤例︓データの同期に⾮同期メッセージングアーキテクチャを適⽤
    l リアルタイムに同期することで、参照可能までの遅延を⼩さくする
    l Kafkaのトピックを公開して、スタンプ作成通知を他のチームでも受信可能
    MySQLに登録完了後、
    Kafkaにメッセージを送信
    Elasticsearchの同期を
    リアルタイムに実施

    View Slide

  33. 発表の流れ
    まとめ
    l コンポーネント数過多による複雑さを解消するために、
    コンポーネントドメインを導⼊
    l コードベースの階層化でドメインを表現
    l コードオーナーを設定して担当者を明確化
    l コンポーネントやドメインの役割・責務を明確にして、
    コンポーネントのモノリス化を防ぐ
    l ⾮同期メッセージングアーキテクチャやCQRSを活⽤して、
    信頼性⾼い、かつ柔軟なマイクロサービスを構築

    View Slide

  34. THANK YOU!

    View Slide

  35. マイクロサービスを安全にリリース、運⽤する⽅法
    l テスト
    l E2Eテストの⾃動化
    l ミラーリクエストを使ったパフォーマンステスト
    l リリース
    l カナリアリリース
    l パーセンテージリリース
    l 監視
    l ダッシュボードの整備
    l 分散トレーシングの活⽤

    View Slide

  36. E2Eテストの⾃動化
    l リアーキテクチャでは基本、プロダクトの表⾯的な機能は変更されない
    l 機能が変わっていないこと、壊れていないことをリグレッションテストで担保
    l E2E⾃動化テストの整備は⼈的リソースを節約できて、より効率的にテストを実施が可能
    Seleniumや商⽤のテスト⾃動化
    サービスを使⽤して、
    ⾃動化テストを整備

    View Slide

  37. ミラーリクエストを使ったパフォーマンステスト
    課題
    リア―キテクチャ後のマイクロサービスに対して、パフォーマンステストしたいが
    負荷テストツールでは、実際のユーザのリクエストを再現することは難しい
    そのため、プロダクション環境にリリースして監視するケースが多い
    l Nginxのミラーリング機能を使⽤して、新コンポーネントに複製されたリクエストを送る
    l 旧新コンポーネントの負荷やパフォーマンスを⽐較して、問題ないかを監視する
    ミラーリクエストは元のリクエストを
    ブロックしないので、既存のサービス
    には影響しない

    View Slide

  38. カナリアリリース
    l デプロイツールを使って、サーバを段階的にリリースする(1台→数台→すべて)
    l 問題があれば、変更をロールバックする
    l ⼿動作業が必要であるが、⽐較的簡単でリスク管理も適切に実施

    View Slide

  39. パーセンテージリリース
    l 処理の切り替えをパーセンテージを指定することでリリースする(1%→10%→100%)
    l あらかじめアプリケーションに対して、この制御の実装が必要
    l コストがかかるため、⼤規模な機能・変更のリリース時に使⽤するか検討
    処理切り替えのパーセンテージは
    構成管理サーバで管理
    ex. Central Dogma

    View Slide

  40. Central Dogmaの活⽤
    l Central Dogma
    l サービス構成管理リポジトリ
    l LINEのOSS https://line.github.io/centraldogma/
    l 設定ファイルを可⽤性⾼く、サーバ上でバージョン管理
    l GitとZookeeperベースのフレームワーク
    l クライアントをアプリケーションに組み込んでおくと、リアルタイムで
    設定値を⾃動で同期
    l 設定ファイルをGitHub上で管理可能

    View Slide

  41. ダッシュボードの整備
    l マイクロサービスのすべてのコンポーネントの状態を可視化
    l リアーキテクチャに伴うエラーや負荷の増加、パフォーマンスの低下も
    早期に発⾒

    View Slide

  42. 分散トレーシングの活⽤
    l マイクロサービス上でリクエストがどのコンポーネント間で伝播し、
    処理されたかを可視化
    l マイクロサービスのトレーサビリティの確保に有効
    l リア―キテクチャ時の調査や効率性の検討上での材料としても有効

    View Slide

  43. Armeria
    l JVM, Netty ベースのフレームワーク
    l LINEのOSS https://armeria.dev/
    l マイクロサービス(サーバ, クライアント)を構築する上での機能を提供
    l Non-Blocking I/O
    l HTTP/2
    l RPC(Thrift, gRPC), RESTサーバ/クライアント, GraphQL
    l Spring Boot, Spring MVCとの統合
    l Micrometerによるメトリクス収集
    l Zipkinによる分散トレーシング
    l クライアントサイドロードバランシング
    l ⾃動リトライ、レイトリミッター、サーキットブレーカー

    View Slide