Slide 1

Slide 1 text

Spring Web MVCの マイクロサービス化の経緯と今 Kazushi Hirai

Slide 2

Slide 2 text

⾃⼰紹介 l LINE Fukuoka株式会社 l 開発室 l Communication & Service Integration室 l LINE STORE Dev Teamマネージャー l Twitter: @hkazushi0627 ฏҪ Ұ࢙ ,";64)*)*3"*

Slide 3

Slide 3 text

Agenda l About LINE STORE l Service Architecture l Technical Stacks l History l Problems / Solution

Slide 4

Slide 4 text

About LINE STORE l LINEの各デジタルアイテムを販売する 公式オンラインストア l PC/スマートフォンブラウザ向け l スタンプ/絵⽂字/着せかえの販売 l LINEファミリーサービス(マンガ、占い、LIVE..)、 Gameの⼀次通貨の販売 l LINEスタンプ プレミアム、LINE MUSIC等、 サブスクリプションサービスの加⼊ l 多くの決済⽅法をサポート クレジットカード、LINE Pay、PayPay、 キャリア決済など https://store.line.me

Slide 5

Slide 5 text

Service Architecture スタンプショップ ユーザ情報 着せ替え 絵⽂字 スタンプ 認証認可 メッセージ送信 決済 公式アカウント LINE Music

Slide 6

Slide 6 text

Technical Stack Language Framework Middleware Storage Infrastructure Monitoring Analytics Java / Kotlin Spring Boot Armeria RxJava NGINX / Kafka MySQL / Redis / MongoDB / ElasticSearch Zipkin Prometheus / Grafana Verda (Private Cloud) Virtual / Physical machine Kubernetes

Slide 7

Slide 7 text

Technical Stack - Dependencies Language Framework Java / Kotlin Spring Boot Armeria RxJava l Spring Web (Tomcat) l Spring Security l Spring AOP l Thymeleaf l Lombok l Prometheus (Micrometer) l Armeria-tomcat9 l Armeria-retrofit l Armeria-rxjava l Armeria-brave

Slide 8

Slide 8 text

History 2012 スタンプショップ リリース 2013 LINE STOREリリース 2014 LINE着せかえ LINEクリエイターズスタンプ 2017 年賀キャンペーン開始 LINE公式アカウントからの おすすめスタンプ⾃動配信 2018 LINE絵⽂字 2019 LINEスタンプ プレミアム 2020 メッセージスタンプ LINEスタンプ プレミアム デラックスコース 2021 LINEスタンプ プレミアム 台湾、インドネシア LINEアニメーション絵⽂字 2011 LINEリリース

Slide 9

Slide 9 text

Problems l 年賀イベントやメッセージ⾃動配信によるリクエストスパイク l 複雑なマイクロサービス上でのボトルネック、エラー調査 l カスケード障害 l ⼀つの障害がシステム全体に影響を及ぼす l 複数同時並⾏で開発、テスト、リリースする仕組みが必要 Server Client Development

Slide 10

Slide 10 text

Problems - Server 2021/1/1の0時あたりのRPS︓

Slide 11

Slide 11 text

Problems l 年賀イベントやメッセージ⾃動配信によるリクエストスパイク l 複雑なマイクロサービス上でのボトルネック、エラー調査 l カスケード障害 l ⼀つの障害がシステム全体に影響を及ぼす l 複数同時並⾏で開発、テスト、リリースする仕組みが必要 Server Client Development

Slide 12

Slide 12 text

Solution l 年賀イベントやメッセージ⾃動配信によるリクエストスパイク l 耐えられるアーキテクチャの採⽤ l 複雑なマイクロサービス上でのボトルネック、エラー調査 l メトリクスの収集 l 分散トレーシング Server

Slide 13

Slide 13 text

Armeria https://armeria.dev/ l LINEのオープンソースソフトウェア l Java、Netty ベースのフレームワーク l Non-Blocking I/O l HTTP/2 l RPC(Thrift, gRPC)、RESTサーバ/クライアント l Spring Boot、Spring MVCとの統合 l Micrometerによるメトリクス収集 l Zipkinによる分散トレーシング

Slide 14

Slide 14 text

Armeria – Spring MVC Integration 1. build.gradle に Armeria の dependencies を追加 2. application.yml の変更 l Armeriaのサーバportは、”8080” l Spring MVCのサーバportは”-1”を設定して、⾮公開にする ベース application: Spring MVC (Tomcat)

Slide 15

Slide 15 text

Armeria – Spring MVC Integration 3. Configurationクラスの追加 A) ArmeriaとSpring MVCを連携する TomcatServiceを作成 B) 相対URLが”/”以下のリクエストを TomcatServiceに流す設定 C) TomcatServiceのスレッドプールの作成

Slide 16

Slide 16 text

Armeria – Spring MVC Integration Armeria Spring MVC (Tomcat) Port:8080 ノンブロッキングI/Oで リクエストを受け付ける ブロッキングI/Oで プールされたワーカースレッドで処理する コードに変更なし Web application

Slide 17

Slide 17 text

Armeria – Metrics 3. application.yml の変更 Armeriaがmetricsを公開するendpointの設定 (デフォルト︓/internal/metrics) ベース application: Spring MVC (Tomcat) + Armeria 監視システム︓Prometheus 1. build.gradle に Micrometer registory の dependencies を追加 2. MeterRegistoryのBeanを追加 Metricsを公開するendpointのport設定 (デフォルト︓サーバport)

Slide 18

Slide 18 text

Armeria – Metrics http://xxxx:18080/internal/metrics Spring-boot-actuatorの設定を ⾏っていれば、それも出⼒される Prometheus形式でmetricsが出⼒ Endpoint url:

Slide 19

Slide 19 text

Armeria – Metrics l Armeriaは、Spring MVCの詳細なmetricsを⾃動で取得しない → 個別に実装を追加することで、Controllerごとのrequest数や レイテンシーを取得 実装コード︓

Slide 20

Slide 20 text

Armeria – Metrics MetricsInterceptor preHandle afterCompletion Controller Thymeleaf Request Response View(HTML) method Micrometer Counter Timer 作成 Counterを増やす 時刻の差分をTimerに保存

Slide 21

Slide 21 text

Armeria – Metrics l 個別実装することで、Armeria serverと同じmetricsキーを使⽤することができる。 l Armeriaと同じmetricsキーを使⽤することで、グラフ作成のクエリーやアラートルールを共通化。 あるメソッドの総リクエスト数をカウントするPromQLとグラフ︓ sum by (method) (rate({project="line-store-server-release",__name__="armeria_server_requests_total", exported_service="HomeController"}[1m]))

Slide 22

Slide 22 text

Armeria – Tracing ベース application: Spring MVC (Tomcat) + Armeria トレーシングシステム: Zipkin 1. build.gradle に dependencies を追加 2. Braveのbeanを追加 Zipkinサーバの設定

Slide 23

Slide 23 text

Armeria – Tracing 3. Armeria に Brave⽤デコレータが⽤意されているので、Armeria server/clientに追加 Brave⽤デコレータを追加 4. Zipkin UIで可視化 デコレータ︓ 既存のオブジェクトに新しい能を動的に追加する機能

Slide 24

Slide 24 text

Solution l カスケード障害 l ⼀つの障害がシステム全体に影響を及ぼす l サーキットブレーカーを導⼊ Client

Slide 25

Slide 25 text

Armeria – Cascade failure カスケード障害︓ ✗ ✗ 1. ある1つのバックエンドAPIに障害が発⽣ → レイテンシーが悪化 2. ワーカースレッドのタイムアウトまで待たされる。 → スレッドが枯渇し、全体が遅くなる

Slide 26

Slide 26 text

Armeria – CircuitBreaker サーキットブレーカー︓ ✗ エラー数がしきい値を超えた場合に、 APIにリクエストせず、代理応答 サーキット ブレーカー

Slide 27

Slide 27 text

Armeria – CircuitBreaker サーキットブレーカーの状態管理: Open Closed Half Open エラー数が しきい値を超えた 成功数が しきい値が超えた ⼀定時間経過後 成功数が しきい値が超えなかった

Slide 28

Slide 28 text

Armeria – CircuitBreaker ベース application: Spring MVC (Tomcat) + Armeria 1. CircuitBreakerのdecoratorを作成して、Armeriaのclientに設定 B) CircuitBreakerのルールの作成 C) Metricsの設定 D) しきい値のカスタマイズ A) ClientにCircuitBreakerを追加 https://armeria.dev/docs/client-circuit-breaker

Slide 29

Slide 29 text

Armeria – Client l Armeria client の 機能 l RPC(Thrift, gRPC)、REST APIクライアント l Retrofit との統合 l クライアントサイド ロードバランシング l DNSサービスディスカバリ l Armeria client の Decrator l ⾃動リトライ (RetryingClient) l Rate Limiter (ConcurrencyLimitingClient) l 分散トレーシング (BraveClient) l サーキットブレーカー (CircuitBreakerClient) https://armeria.dev/docs/client-http https://armeria.dev/docs/client-retrofit https://armeria.dev/docs/client-service-discovery

Slide 30

Slide 30 text

Armeria – Client-side load balancing l クライアントサイド ロードバランシング l リクエストするクライアント側で接続先サーバを決定 l 接続先サーバリストの保持が必要 l 動的にサーバリストを更新するため、サービスレジストリを使⽤ l Pros l サーバサイド ロードバランシングと⽐べ、単⼀障害点が少ない l マイクロサービスの構成も簡単になる

Slide 31

Slide 31 text

Armeria - Client-side load balancing Web application Server 1 x.x.x.1 Server 2 x.x.x.2 Server 3 x.x.x.3 Backend API Central Dogma x.x.x.1 x.x.x.2 x.x.x.3 Service registry Backend APIの Server-listを更新 Sync Deployment system Sync ヘルスチェックによって、 停⽌したサーバはリストから除外

Slide 32

Slide 32 text

Armeria – Ramping up strategy l クライアントサイド ロードバランシング l サーバにはデフォルト、ラウンドロビンでアクセス l Armeriaのバージョンアップで、Ramping upの設定が追加 l Ramping up strategy l サービスイン直後のサーバは、weightを2秒ごとに10%ずつ増やしてアクセス l 起動直後のウォームアップによるレイテンシー悪化の影響をうける リクエストの割合を少なくできる ラウンドロビンのときは、 リリース直後のレイテンシーの悪化 Ramping upに変更後、解消

Slide 33

Slide 33 text

Solution Development l 複数同時並⾏で開発、テスト、リリースする仕組みが必要 l トランクベース開発で運⽤ l フィーチャートグルを使って機能ON/OFFを制御

Slide 34

Slide 34 text

Development – Feature toggle l フィーチャートグルをどこに格納すべきか︖ l 設定ファイル l Cons l 環境ごとに切り替えられるが、デプロイが必要 l より細かい単位、特定ユーザや国単位で切り替えたい l Service registoryにフィーチャートグルを格納 l Service registoryには、Central Dogmaを使⽤ フィーチャートグルありのコード:

Slide 35

Slide 35 text

Development – Central Dogma https://line.github.io/centraldogma/ l LINEのオープンソースソフトウェア l Git、Zookeeperベースのフレームワーク l Service configuration repository l HTTP/2 l Versioning control

Slide 36

Slide 36 text

Development – Central Dogma Trustin Lee,「Central Dogma: LINEʻs Git-based highly-available service configuration repository」, https://speakerdeck.com/trustin/central-dogma- lines-git-based-highly-available-service-configuration-repository Central Dogmaのシステム構成図: l GitHub連携 l 設定ファイルをGitHub上で 管理できる l Pull requestを作って、変更を レビューできる l クライアントライブラリ l ほぼリアルタイムに Applicationに変更を反映できる

Slide 37

Slide 37 text

Development – Feature toggle l DSLとして、PlanOutを使⽤ l FacebookがA/Bテスト⽤に開発したフレームワーク l Javaの実装であるPlanOut4jをライブラリとして使⽤ 設定ファイル(YAML) PlanOut4j userId=xxxx isRelease=true country=JP パラメータ user-new-string=true Parse Feature toggle ユーザごとの設定値(IDや国)や 環境ごとの設定値をApplicationから パラメータとして設定

Slide 38

Slide 38 text

Solution Development l 複数同時並⾏で開発、テスト、リリースする仕組みが必要 l トランクベース開発で運⽤ l フィーチャートグルを使って機能ON/OFFを制御 l Central Dogmaを使って、リアルタイムに変更を反映 l PlanOutを使って、より細かい単位でON/OFFを制御

Slide 39

Slide 39 text

Summary l 年賀イベントやメッセージ⾃動配信によるリクエストスパイク l 複雑なマイクロサービス上でのボトルネック、エラー調査 l Armeriaと連携して、可⽤性の⾼いアーキテクチャの構築 l メトリクスの収集、分散トレーシングの導⼊ l カスケード障害 l Armeria clientを使って、サーキットブレーカーを導⼊ l 複数同時並⾏で開発、テスト、リリースする仕組みが必要 l フィーチャートグルを導⼊ l Central Dogmaを使って、リアルタイムに変更を反映 l PlanOutを使って、より細かい単位でON/OFFを制御 Server Client Development

Slide 40

Slide 40 text

関連ドキュメント l Armeria: https://armeria.dev/ l Central Dogma: https://line.github.io/centraldogma/ l Micrometer: https://micrometer.io/ l Zipkin: https://zipkin.io/ l Brave: https://github.com/openzipkin/brave l Planout: https://github.com/facebookarchive/planout l Planout4j: https://github.com/Glassdoor/planout4j