Slide 1

Slide 1 text

マイクロサービス移行を仕上げる Last one mile 2021/11/13 Kenta Moriwaki

Slide 2

Slide 2 text

期待値調整 ● マイクロサービスを使ったシステムで、モノリスで動いていたサー ビスの一部分を置き換えました ● マイクロサービスへはこのように移行すべきだ、という発表ではな いです ● Goの内部実装の話は少ないです:bow:

Slide 3

Slide 3 text

今日話したいこと ● Goを使ってマイクロサービスの運用を始めた、事例ベースの話です ● 元となる設計思想や基本的なサービスはすでに存在していて、プロダ クションに出す手前あたりで自分はジョインしました ● 本番運用するにあたり工夫した点や悩んだ点など共有したいです

Slide 4

Slide 4 text

自己紹介 森脇健太 Retty株式会社 エンジニアリング部門 ソフトウェアエンジニア バックエンドとフロントエンド書いています 南インドやネパールのカレーが好きです

Slide 5

Slide 5 text

アジェンダ ● 背景 ● 本番導入に向けて必要なこと ● こんなことがありました ● まとめ

Slide 6

Slide 6 text

背景 Rettyが提供している主なページ ● 店舗ページ ○ レストランの情報など ● 店舗リストページ ○ 検索結果など、店舗のリスト 店舗ページ 店舗リストページ

Slide 7

Slide 7 text

背景 既存のサービスの問題 ● ビジネスロジックが散らばった10年もののPHPシステム ● 大規模なアクセスを支えるためのキャッシュが厚く、情報が反映され るタイミングが読めない ● 過去に単一のサービスでバックエンドを作り直そうとしたが、重複し たロジックが残ったりして苦しかった前例があった マイクロサービスをベースとした、 リアーキテクチャが3年ほど前から進行中

Slide 8

Slide 8 text

背景:リアーキテクチャへの道筋① モノリス → Adapterサービス → BFF → Frontendの形をまず用意

Slide 9

Slide 9 text

背景:リアーキテクチャへの道筋② Adapterの主要一部(レストラン情報を返すサービス)を置き換える

Slide 10

Slide 10 text

背景:リアーキテクチャへの道筋③ Adapterを少しずつ別のアプリケーションに置き換える

Slide 11

Slide 11 text

今回の話のスコープ 途中まで進んでいたAdapterの置き換え作業 サービスからモノリスの依存を外し、本番に出した話です

Slide 12

Slide 12 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 13

Slide 13 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 14

Slide 14 text

モノリスからの脱却 サービスの分割単位は.protoファイルで定義 Adapterサービスは複数サービスを兼任していた

Slide 15

Slide 15 text

マイクロサービス多すぎ問題 Adapterから切り離すサービスが多いわりに..... ● サービスそれぞれが小さい ● 参照系の機能しか持たない ○ 提供しているサービスの性質上、参照>>>更新 それぞれを別のインスタンスで動かすのはまだ早すぎるのでは?

Slide 16

Slide 16 text

miscellaneous(その他)サービス 小さな参照系のサービスをまとめる 別々のインスタンスで動かし、独立したデプロイの利点がまだない ● チームごとに担当サービスがある、という組織構造ではなかった .protoファイルの存在により切り出しの粒度がわかっていた ● 大きいサービスは独立、小さいものはmiscellaneousサービスに入れる といった判断が実装前に判断できた ● サービスは他のサービスのコードに依存しないようにして、いつでも 分離できるようにした

Slide 17

Slide 17 text

サービスの全体図

Slide 18

Slide 18 text

サービスの全体図

Slide 19

Slide 19 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 20

Slide 20 text

認証周りの話 ユーザーがログインしているかどうかでサービスが返す情報を分けたい ログイン情報を扱うセッションサービスはすでに存在し、モノリスから 利用していた

Slide 21

Slide 21 text

認証周りの話 マイクロサービスを跨いでセッションを保持する主なパターン ● 独立型 ● 中央集権型 ● 分散型 ● ゲートウェイ分散型 中央集権型とゲートウェイ分散型の2択に絞られた マイクロサービス時代のセッション管理 https://engineer.retty.me/entry/2019/12/21/171549

Slide 22

Slide 22 text

中央集権型 ユーザーの認証情報を 持ったセッションサービ スを、各サービスがそれ ぞれ問い合わせる ● Revokeが簡単 ● 可用性が必要

Slide 23

Slide 23 text

ゲートウェイ分散型 BFFのようなGatewayで セッションサービスを問 い合わせ、認証情報を JWTで受け取る 各サービスはJWTを受け 取り、各自で検証する

Slide 24

Slide 24 text

ゲートウェイ分散型 ● 可用性が必要なのは 変わらず ● 認証情報を使うたび にセッションサービ スを叩く必要がない ので負荷は減る 今後の負荷の可能性を考 えてこちらを採用するこ とに

Slide 25

Slide 25 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 26

Slide 26 text

どう本番に出していくか ミニマムな形で本番に出す 特定契約の店舗ページのみを切り替える ストラングラーパターンを使う ● 特定店舗の場合はマイクロサービス 群を利用したシステムへ、それ以外 は既存のシステムへ、といった形で 振り分ける

Slide 27

Slide 27 text

モノリスか新しいサービスかを振り分けるサービス リクエストルーター(echoを使ったシンプルなシステム) 既存システム マイクロサービス群 を利用したシステム リクエストされたURLを もとに振り分け 10店舗 → 25店舗 → 100店舗…と徐々に広げながら負 荷に耐えうるかを見ていった

Slide 28

Slide 28 text

リクエストルーター リクエストされたURLパスを 正規表現でチェックして、新 しいサービスへと振り分ける ● 該当のページのURL ● それ特有のAPIのURL ● フロントエンドで必要な URL(/_nuxt/ etc...)

Slide 29

Slide 29 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 30

Slide 30 text

本番導入に向けて必要だったこと ● モノリスからの脱却 ● ログインユーザーのための認証基盤との連携 ● 本番へのリリース方針を決める

Slide 31

Slide 31 text

こんなことがありました ● ファイルディスクリプタの枯渇という落とし穴 ● 対象店舗が更新されない

Slide 32

Slide 32 text

こんなことがありました ● ファイルディスクリプタの枯渇という落とし穴 ● 対象店舗が更新されない

Slide 33

Slide 33 text

ファイルディスクリプタの枯渇という落とし穴 本番に出して一ヶ月ほど経ち、その他サービスのうちの一つのエラー レートが上昇 socket: too many open files ● ファイルディスクリプタが枯渇していた

Slide 34

Slide 34 text

ファイルディスクリプタの枯渇という落とし穴 https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html

Slide 35

Slide 35 text

ファイルディスクリプタの枯渇という落とし穴 https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html

Slide 36

Slide 36 text

ファイルディスクリプタの枯渇という落とし穴 Amazon ECSのデフォルトのリソース制限に引っかかっていた -> ulimitを増やして解決 一つのアプリケーションにサービスを詰め込んでいった結果、当初の想 定以上にDBアクセスが増えてしまっていた。

Slide 37

Slide 37 text

こんなことがありました ● ファイルディスクリプタの枯渇という落とし穴 ● 対象店舗が更新されない

Slide 38

Slide 38 text

対象店舗が更新されない 振り分け対象の店舗はS3に格納し、リクエストルーターで定期的に取得

Slide 39

Slide 39 text

対象店舗が更新されない

Slide 40

Slide 40 text

対象店舗が更新されない 「*」デリファレンスされてる?? 新しい構造体なので、 tickerのチャネルを待ち受けて いるゴルーチンは存在してい ない......

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

対象店舗が更新されない

Slide 43

Slide 43 text

まとめ 紆余曲折ありましたがマイクロサービスを本番に出して運用することが できています ● 本番に出すことで初めてわかるようになる問題があるので、 実際に運用してみることは重要と再認識しました モノリスをマイクロサービスにする過程で、モジュラモノリスという選 択もしました ● 状況によっては分割しない、という選択もありだと思います ● その時々に合ったもので、必要なら他のものに変更しやすいアーキテ クチャを選んでいきたいです

Slide 44

Slide 44 text

No content