Upgrade to Pro — share decks privately, control downloads, hide ads and more …

メルペイのマイクロサービスの構築と運用 / CloudNative Days Tokyo2019

tjun
July 22, 2019

メルペイのマイクロサービスの構築と運用 / CloudNative Days Tokyo2019

メルペイのマイクロサービスの構築と運用
2019.07.22 に CloudNative Days Tokyo2019 で発表した内容です。
なぜメルペイがマイクロサービスアーキテクチャを選択したか、メルペイのマイクロサービスの構築と運用をどのように行ったか、などを話しました。

tjun

July 22, 2019
Tweet

More Decks by tjun

Other Decks in Technology

Transcript

  1. メルペイにおける
    マイクロサービス 構築と運用
    CloudNative Days Tokyo 2019
    Merpay SRE
    @tjun
    Junichiro Takagi https://speakerdeck.com/tjun/cloudnative-days-tokyo2019

    View Slide

  2. 「マイクロサービス、実際やってみてどう?」に答えたい
    今日 テーマ
    2

    View Slide

  3. メルペイ マイクロサービス概要
    メルペイ マイクロサービス 構築と運用
    課題と今後
    01
    02
    03
    3
    Agenda
    おまけ: 実際に起きた問題を紹介
    04

    View Slide

  4. メルペイ概要
    年 月
    非接触型サービス「 」に対応
    年 月
    複数回 お買い物をあとからまとめて支払える
    「メルペイあと払い」開始
    年 月
    サイトでも「メルペイ」が利用できる
    ネット決済提供開始
    年 月
    大手チェーンや中・小規模店舗で
    ・バーコード決済に対応
    全国135万か所
    iD コード払い
    あと払い ネット決済

    View Slide

  5. メルペイ サービス
    マイクロサービスアーキテクチャ
    40以上 マイクロサービス
    2019 3Qで 1444億円以上を取り扱うメ
    ルカリ 決済基盤(US メルカリ事業も含む数字 )
    200万人以上 利用者
    (メルペイ「電子マネー」 登録を行ったユーザー 累計。
    コード払い 除く )

    View Slide

  6. Why microservice?

    View Slide

  7. Why microservices?
    メルペイ 複数 サービスを短期間で立ち上げるため
    Focus on single service
    各マイクロサービス
    機能に集中して開発
    Independent releases
    独立した開発・リリース
    サイクル
    Team independence
    組織を拡大しながら
    複数 機能を同時に開発

    View Slide

  8. マイクロサービス そ 他 メリット
    Resilience
    障害が局所化すること
    で可用性が高まる
    Scalability & Flexibility
    独立したリソース管理が可能
    ストレージも独立

    View Slide

  9. メルペイ マイクロサービスで
    やっていないこと
    マイクロサービス単位で 自由な技術選択
    自由な技術選択 例 自由な言語、好きなデータベース
    Why?
    ● 共通 ツール・ライブラリを利用することで、開発や運用
    度や品質を高めるため
    ● チーム間 情報共有や人 移動を可能にするため

    View Slide

  10. メルペイ マイクロサービス 現状

    View Slide

  11. アーキテクチャ
    API Gateway
    Authority
    API
    Service X
    API
    Service Y
    Google Cloud Load Balancer
    Service A Service B
    Google Kubernetes Engine
    Service C
    Web
    Service Z
    Cloud
    Spanner
    Project A
    Cloud
    Spanner
    Cloud
    Pub/Sub
    Project B
    Project GKE

    View Slide

  12. API Gateway
    Authority
    API
    Service X
    API
    Service Y
    Google Cloud Load Balancer
    Service A Service B
    Google Kubernetes Engine
    Service C
    Web
    Service Z
    Cloud
    Spanner
    Project A
    Cloud
    Spanner
    Cloud
    Pub/Sub
    Project B
    Project GKE
    共通 GKEクラスタ

    3

    1

    2
 個別 Project

    レイヤーアーキテクチャ


    View Slide

  13. Google Kubernetes Engine
    Kubernetes
    マイクロサービス 実行基盤・オーケストレーション
    - 自己修復性 あるReplication Controller
    - ServiceによるLoad Balancing
    - DeploymentによるRollout/Rollback
    - Horizontal Pod Autoscalerによるスケールアウト
    - Kubernetes 自体 拡張性やエコシステム
    早く構築し、安定して運用するためにGKEを利用

    View Slide

  14. マイクロサービス on
    Google Kubernetes Engine
    すべて マイクロサービスが同じClusterに乗っている
    - Cluster自体 Platform Teamが構築・運用
    - Namespace内を各チームが開発・運用
    Google Kubernetes Engine
    Namespace: service-a
    Container A
    Container A
    Container A
    Namespace: service-b
    Container A
    Container A
    Container B

    View Slide

  15. マイクロサービス on Google Cloud Platform
    ● 1つ マイクロサービスが1つ GCP Projectを持つ
    ● 各 Project 中に Spanner や Pub/Sub などを作成
    ● 権限設定したService Account を Kubernetes Secretに配置
    ● Terraformで管理
    CircleCI
    Project A
    Cloud
    Spanner
    Cloud
    Pub/Sub
    GitHub
    Terraform
    Code Project B
    Cloud
    Spanner Big Query

    View Slide

  16. マイクロサービス 階層構
    アプリ、加盟店等 パートナー様
    全て リクエストが を通る
    共通処理とルーティング
    サービス クライアントから リクエストとレスポンス 責任を持つ
    裏側にある複数 マイクロサービス アグリゲーション
    サービス 機能 ロジックを実現する
    Backend
    Service
    API Gateway
    API
    Service
    Client

    View Slide

  17. メルペイ マイクロサービス 例
    iD決済を実現する流れ
    API-Gateway NFC-api NFC-service
    payment-
    service
    リクエスト 認証と
    ルーティング
    clientへ返すため
    response 作成
    NFC決済を実現する
    ため 処理
    共通 決済処理

    View Slide

  18. API Gateway
    ● Goで書かれたマイクロサービス
    ● リクエストを各マイクロサービスへルーティングする
    共通 リクエスト処理をAPI Gateway と Cloud Load Balancerで実現
    ● TLS termination
    ● DDoS protection
    ● Request buffering
    ● Authマイクロサービスを利用したAuthN/AuthZ

    View Slide

  19. メルペイ マイクロサービス 構築

    View Slide

  20. 開発組織とマイクロサービス
    各機能を実現する
    マイクロサービス開発チーム
    ● バックエンドエンジニア
    ● フロントエンドエンジニア
    ● iOS/Androidエンジニア
    ● デザイナー
    ● PM
    共通基盤とサービス全体を
    見る横串チーム
    ● SRE
    ● アーキテクトチーム
    ● Microservices Platformチーム
    ● Data platformチーム
    ● ソリューションチーム

    View Slide

  21. メルペイ マイクロサービス開発で
    気をつけていること
    一貫性
    ● データ 一貫性
    ● リトライと冪等性
    ● リコンサイル
    信頼性
    ● Go template projectやlibraryによる
    標準化
    ● Production Readiness checklist
    ● DesignDoc
    ● 権限管理

    View Slide

  22. メルペイ マイクロサービス開発で
    気をつけていること
    一貫性
    ● データ 一貫性
    ● リトライと冪等性
    ● リコンサイル
    信頼性
    ● Go template projectやlibraryによる
    標準化
    ● Production Readiness checklist
    ● DesignDoc
    ● 権限管理

    View Slide

  23. マイクロサービスにおける一貫性
    分散システムにおけるデータ 一貫性 担保 難しい
    ● 決済トランザクションが複数サービスをまたがる
    ● DBへ 書き込みや外部サービスへ 接続が分散している
    ● どこかで処理が失敗しても、全体として一貫性が必要
    冪等性
    ● リトライしても二重に処理されず、正しく動く
    詳しく メルカリtech blog 記事を参照
    - マイクロサービスにおける決済トランザクション管理
    - メルペイにおけるお客さま残高 管理手法

    View Slide

  24. マイクロサービスにおける一貫性
    リコンサイル
    ● 本当にデータ整合性が取れている か?
    ● 不整合を見つけて修正する必要がある
    メルペイで
    ● バッチ処理によるリコンサイル
    ● 非同期な結果イベント通知によるリコンサイル
    によって不整合 チェックと修正を行っている

    View Slide

  25. メルペイ マイクロサービス開発で
    気をつけていること
    一貫性
    ● データ 一貫性
    ● リトライと冪等性
    ● リコンサイル
    信頼性
    ● Go template projectやlibraryによる
    標準化
    ● Production Readiness checklist
    ● DesignDoc
    ● 権限管理

    View Slide

  26. メルペイ マイクロサービスとGo
    ほとんど サービスがGoで書かれている(一部Node.js)
    マイクロサービス テンプレート
    ● Liveness/ReadinessProbe対応、Graceful シャットダウンなど
    Kubernetes上で動かすために必要な機能を持つ
    社内で開発した共通 Goライブラリ
    ● Logging, 分散Tracing, クライアントサイド LoadBalancingなどに対

    View Slide

  27. マイクロサービス レビュー
    DesignDoc
    設計をアーキテクト、SRE、Security、関連マイクロサービス
    エンジニアがレビュー・議論する
    Production Readiness Checklist
    本番リリース前に、Kubernetes yaml等で必要な設定が
    されているか、運用 準備が十分かなどをチェックする
    例: Horizontal Pod AutoscalerやPod Disruption Budget 設定

    View Slide

  28. メルペイにおける
    マイクロサービス構築 流れ

    View Slide

  29. 開発を加 する共通 仕組み
    Microservices platform
    各チームがOwnershipを持ってサービスを構築・運用する
    ● microservice-starter-kitによるマイクロサービス 初期化
    ● Protocol Buffersによるサービス インターフェース 定義 共通化
    ● GCP上 リソース 全てTerraformで管理
    ● Kubernetes上 リソースをYAMLで管理
    ● 共通 デプロイフロー
    Platformをメルカリ Microservices platform teamが構築・運用

    View Slide

  30. マイクロサービス 初期化
    microservices-starter-kit という仕組みで自動化
    ● GCP Project 作成+Application用Service Account 作成、
    開発者へ IAM権限 付与
    ● Kubernetes Namespace 作成+必要なRBAC&Secret 設定
    GCP project for GKE
    Centralized cluster
    Namespace: Service A
    Service A
    RBAC: Team A

    View Slide

  31. GCPリソース 作成
    ● Cloud Spanner, Pub/Sub, Cloud Storage等 リソース
    ● すべてTerraformで作成・管理
    CircleCI
    Cloud
    Spanner
    Cloud
    Pub/Sub
    GitHub
    Terraform
    Code Project B
    Cloud
    Spanner Big Query
    Project A

    View Slide

  32. Kubernetesリソース単体 デプロイ
    Manifest 単体をCircleCIからデプロイ
    - Job、Horizontal Pod Autoscalerなど YAML
    CircleCI
    Google Kubernetes Engine
    yaml
    GitHub
    Namespace: service-a
    Container A
    Container A
    Container A
    Namespace: service-b
    Container A
    Container A
    Container B

    View Slide

  33. Microservicesアプリケーション デプロイ
    必要なYAMLとImageを指定してSpinnaker経由でデプロイ
    CI
    Google Kubernetes Engine
    yaml
    Namespace: service-a
    Container A
    Container A
    Container A
    Namespace: service-b
    Container A
    Container A
    Container B
    Cloud
    Build
    Container
    Registry
    code CI

    View Slide

  34. メルペイ マイクロサービス 運用

    View Slide

  35. マイクロサービス 運用 大変
    マイクロサービス 数が増えるだけ運用する要素が増える
    ● 各マイクロサービス アプリケーション
    ● 各マイクロサービスが利用するリソース(データベース等)
    ● マイクロサービス間 通信
    運用 手間を減らす仕組み
    ● マイクロサービス 構成をできるだけ揃える
    ● Kubernetes によるオートスケールや自己修復
    ● Managedなクラウドサービス
    それでもさまざまなところで問題 起きる

    View Slide

  36. マイクロサービス 運用体制
    マイクロサービスで 各チームが担当マイクロサービスを運用
    ● 元から運用経験があるエンジニア 多くない
    Google Kubernetes Engine
    Container A
    Container A
    Container A
    Cloud
    Spanner
    Project A
    Container A
    Container A
    Container B
    Cloud
    Spanner
    Project B
    Cloud
    Pub/Sub

    View Slide

  37. マイクロサービス運用で気をつけていること
    SLOを設定する
    ● サービスが正常な状態を各サービスで定義する
    ● アラートをしたり問題を修正したりする判断 基準
    Observability
    ● Metrics問題が起きたときに調査する&問題が起きる前に気づく
    ● 分散Tracing: リクエスト どこで時間がかかっているか

    View Slide

  38. SLO(Service Level Objective)
    運用を考えると出てくる疑問例
    ● 自分たち サービス 今正常な か?
    ● 自分たち サービス 遅い?一部 お客さまに対してだけ遅い?
    ● CPU使用率が一瞬上がっていたが、問題ない か?
    SLO
    ● 可用性、レイテンシなどシステム 信頼性 目標値
    ● SLOを定義することで、自分たち サービスが正常な か、Alertする
    か、何を修正・改善するか 判断ができる
    例: あるAPI で 最低でも99.99% リクエストが 5xx以外を返す

    View Slide

  39. Observability
    Microservicesで 、1リクエストが複数 マイクロサービスを経由
    する
    ● どこでどれだけ時間がかかっている か
    ● なぜ時間がかかっている か、どんなエラーが出ている か
    ● 各マイクロサービス SLOを満たしている か
    Metrics, Trace, Logをサービス横断して見られるようにすることで、
    問題 特定がスムーズにできる

    View Slide

  40. 監視体制
    Datadogに集約してTimeboardやAPM、Monitor 機能を利用
    Google Kubernetes Engine
    Container A
    Container A
    Container A
    Cloud
    Spanner
    Project A
    Go, gRPC, Docker,
    Kubernetes
    メトリクス
    GLB, Spanner, Pub/Sub,
    Stackdriver Logging
    等 メトリクス

    View Slide

  41. ここまで まとめ
    メルペイで
    ● 短期間で サービスリリースを実現するため
    マイクロサービスアーキテクチャを採用
    ● 共通化された開発・運用 Platformがある
    ● Platform 上で、各チームがOwnershipを持って開発運用
    ● 一貫性と信頼性を実現するため、各マイクロサービス
    アプリケーション上や開発運用 プロセスでさまざまな
    仕組みを作っている

    View Slide

  42. メルペイ マイクロサービス
    課題と今後

    View Slide

  43. 開発・運用で出てきた課題
    一部 マイクロサービスがモノリス化する
    ● 機能をど マイクロサービスに実装するか、判断が難しいことがある
    ● 1つ マイクロサービスにさまざまなビジネスロジックが集まってしまう
    QAが難しい
    ● ど マイクロサービス ど バージョン 組み合わせな か
    ● リリース以前 開発環境 どこかが壊れている状態だった
    運用と開発 リソース 調整
    ● 開発が落ち着いてきたけど運用が続くサービスもあれ 、これから
    開発が活発になるサービスもある

    View Slide

  44. メルペイ マイクロサービス 今後
    リリースを振り返って
    ● サービス 信頼性を高めて運用負荷を下げる改善中
    今後に向けて
    ● さらに広く使われるメルペイを目指して、引き続きさまざま機能を
    企画・開発しています
    ● バックエンド、SREなど各職種で採用してます!
    Go、Microservice、Kubernetes、GCPやりたい人
    ご連絡ください

    View Slide

  45. 残り 時間で、開発中に発生したさま
    ざまなトラブルを紹介します

    View Slide

  46. [1] Deploy時にリクエスト
    一部がエラーになる
    深刻度: ★

    View Slide

  47. [1] Deploy時にリクエスト 一部がエラー
    まずやること
    ● Graceful Shutdown
    ● Readiness/Liveness 適切な設定
    上記をやらないと、
    ● 消えていくPodが正しくリクエストを処理しない
    ● 準備ができていないPodへリクエストが届く

    View Slide

  48. [1] Deploy時にエラーが出る
    まだ、Kubernetesで必ず起きる問題や、gRPCだから起きる
    問題が残っていた
    ● containers.lifecycle.preStop に sleepを入れる
    ● terminationGracePeriodSeconds を設定する
    ● strategy.rollingUpdate.maxSurge を 100%にしない
    等 設定を入れて、RollingUpdateをなめらかに行う

    View Slide

  49. [2] Ingress 再作成に失敗する
    深刻度: ★★★

    View Slide

  50. [2] Ingress 再作成に失敗
    前提
    ● メルペイで 、Ingress-GCEを利用
    起きたこと
    ● 開発環境 Ingressを作り直したところ
    ○ External-IPが当たらない
    ○ Backend-serviceが作られない
    ○ 設定を少し変えると作成されることもある

    ○ ログに 何も出ていない

    View Slide

  51. [2] Ingress 再作成に失敗
    原因
    ● GKE v1.10.6 (に含まれるIngress-GCE) バグだった
    対策
    $ kubectl apply -f merpay-ingress1.yaml
    $ kubectl apply -f merpay-ingress2.yaml
    $ kubectl apply -f merpay-ingress3.yaml -> OK
    $ kubectl apply -f merpay-ingress4.yaml

    View Slide

  52. [3] Ingressを追加したら、
    元からあったIngressが壊れた
    深刻度: ★★★★★

    View Slide

  53. [3] Ingress を追加したら既存 Ingressが
    壊れた
    起きたこと
    ● 新しい用途 Ingressを追加したら、前から使っていたIngress
    (触ってない)方でリクエストが全てエラー
    ● 設定したい証明書と 違う証明書が設定されている
    対応
    ● いろんな設定とログを調べたが全く分からず、 新しいIngressを
    消すと問題が解消した
    ● Ingress-controller ログが見られない…

    View Slide

  54. [3] Ingress を追加したら既存 Ingressが
    壊れた
    原因
    ● 2つ Ingress 設定を元に 同じ HTTPS proxy を交互に更新
    していた
    ● Namespace名+Ingress名 先頭55文字で区別しているため、
    長くて似た名前で作っていたIngressがぶつかっていた
    ● 実 ドキュメントに書いてある
    ○ The total length of the namespace and name of an Ingress must not exceed 55
    characters.

    View Slide

  55. [3] Ingress を追加したら既存 Ingressが
    壊れた
    対策
    ● Ingress 名前を短くした
    ● 長い名前 Ingressを作れないようなLintを追加した

    View Slide

  56. [4] Podが減っていく
    深刻度: ★★★★★

    View Slide

  57. [4] Podが減っていく…
    起きたこと(イメージ)
    ● 5つあった ず Podが3つになっている
    ● 他 2つ 起動できずにRestartを繰り返している
    ● 他 3つがRestartして起動できなくなる も時間 問題…
    調査
    ● エラーが曖昧なも しか出せず、原因調査が難航
    ● 今動いているも を止めたくない で、ログを増やしたPodをデ
    プロイすることもできない

    View Slide

  58. [4] Podが減っていく…
    原因
    ● 起動時 処理に必要な GCP APIが意図せずdisableされてい

    ● Terraform Diffで出ていたが、レビューでそ 影響に気づけ
    ていなかった
    対策
    ● Terraform 設定を修正して各サービスを更新

    View Slide

  59. [5] Spannerへ Latencyが
    ときどき大きくなる
    深刻度: ★★★★

    View Slide

  60. [5] Spannerへ リクエスト レイテンシが
    ときどき大きくなる
    前提
    ● GKE上 Go アプリケーションからCloud Spanner へ読み書き
    を行う
    起きたこと
    ● アプリケーションを動かしていると、数100ms-数秒かかるときが
    ときどき発生

    View Slide

  61. [5] Spannerへ リクエスト レイテンシが
    ときどき大きくなる
    さまざまな原因
    ● クライアントライブラリgoogle-cloud-go 問題
    ● Kubernetesクラスタ DNS 問題
    ● アクセストークン リフレッシュ
    対策
    ● クライアントライブラリ 修正
    ● DNSをアプリケーション側でキャッシュ
    ● アクセストークンをバックグラウンドで定期更新

    View Slide

  62. [5] Spannerへ リクエスト レイテンシが
    ときどき大きくなる
    詳細 メルカリ Tech Blog
    メルペイで Spannerと 戦い 日々
    で紹介しています。

    View Slide

  63. 最後に宣伝
    Google Kubernetes Engine と Cloud Spanner について
    2019.07.31 Google Cloud Next Tokyo で発表します

    View Slide

  64. 66

    View Slide