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

PHP Application における Kubernetes 内 gRPC 通信

PHP Application における Kubernetes 内 gRPC 通信

PHP Conference 2026 での発表スライド
Mercari において PHP Application がどのように Kubernetes Cluster で 他のサービスと連携をしているか紹介

Avatar for Shin Ohno

Shin Ohno

July 19, 2026

More Decks by Shin Ohno

Other Decks in Programming

Transcript

  1. $ whoami - Shin Ohno(@ganchiku) • 2020年〜 Mercari の主に Backend

    側の改善, 移行, 運用 ◦ 入社以来, ずっとコードやテーブルを削除 ◦ モノリスの将来設計とその実践 • 複数チームのマネージャー ◦ Mercari API(PHP Service) & DBRE(主にTiDB) ◦ プレイングマネージャータイプ • 関わっているチームの主な偉業 ◦ Mercari の Monolithを Kubernetes Cluster へ移行 2022 ◦ PHP Application のgRPC Client化 2025(今日話すのはココ ) ◦ Mercari のコアなデータベースを TiDB Cloud へ移行 2026 • Philosophy ◦ No Improvement Cycle, No Maintainability
  2. $ 今日の話の想定聴衆者 Kubernetes 上での大規模 PHP アプ リケーション運用に興味がある方 モノリス PHP とマイクロサービスの接

    続・移行戦略に興味がある方 大規模サービスで PHP がどのように 活用されているか知りたい方 PHP アプリケーションを Kubernetes / gRPC 環境へ適応させる際の実践的な 知見を持ち帰れる内容を目指します PHP サービスにおける gRPC 連携の 実践例を知りたい方
  3. • Mercari における PHP Application の 現在 ◦ 規模感, 運用

    • PHP Application の Service 間連携の歴史 ◦ 2018 - 2020 移行期初期 - オンプレミス /GCE ◦ 2020 - 2024 移行期中期 - GKEへの移行 ◦ 2025 - 2026 現在 - クラスタ内直接通信 • PHP Application の gRPC Client の実際 ◦ Application に任せること , istio(Envoy) に任せること ◦ Go の gRPC 使用との違いとチャレンジ • gRPC Client 利用コードの解説 ◦ 簡略化した Application の呼び出しコード解説 $ Agenda
  4. 構成 API: 約400 CronJob: 約35 Worker: 約10 Deploy 頻度: 3-10/day

    Traffic: 30k-80k RPS (この service の参考値 , 時間帯により変動 ) Pod数: 300-600 (HPA設定により変動 ) $ Mercari の PHP Application 規模感
  5. 2013年から PHP で運用, 現在も重要なサービス • PHP8.5 & Apache, DataDog •

    主に Transaction, Logiチームが開発(一部 IdP, Coupon チームも担当) ▪API 約400 (用途別に3つの系統で提供) Public API • インターネット公開用 iOS, Android, Web 向け (サード パーティ向けではない) • コア機能の開発 創業期からの取引, 配送周りのコ アなAPI Internal API • クラスター内限定連携 ネット接続不可, Kubernetes内 Backend サービスが呼び出し • 移行期・共有ロジック DB使用移行や, Public APIとのロ ジック共有用 Admin API • 管理用途に特化 ネット接続不可, Kubernetes内の Admin 目的で利用 • コアDB制御・ロジック コアDBの限定利用, およびPublic APIとのロジック融合 $ Mercari の PHP Application 運用
  6. CronJobs 約35 • Kubernetes CronJob で Workload を管理 Workers 約10

    • Kubernetes Deployment で Workload を管理 • Q4M ベースの Workers • Transactional Outbox Pattern の Workers 開発環境 GitHub に PR にラベルを貼ることをトリガーと して, 開発環境 Cluster に Service, Deployment が作成され PR 用の pod が立 ち上がり QA が可能 関連資料 & 開発情報 • Kubernetes Controller for PR Based Env • The World Is at Your PR! • Dynamic Service Routing using Istio $ Mercari の PHP Application 運用
  7. サービス概要 • 依然として大規模なトラ フィックを安定して運用 • ビジネス上極めて重要な サービスがPHP上で稼働 実行環境 & 監視

    • Kubernetes上で稼働 • PHP8.5 & Apache構成 • DataDogによる高度なオ ブザーバビリティの実現 リリース & API • リリース頻度は多いとき で1日10回 3つの提供API • Public API (iOS, Android, Web用) • Internal API (Backend Services用) • Admin API (Admin用) $ Mercari の PHP Application まとめ
  8. $ 2018 - 2019移行初期 - DataCenter • PHP Service ◦

    DataCenter ◦ 全て HTTP • Go Service ◦ Kubernetes & DataCenter(記載 なし) • Authority Service ◦ Mercari Token を 検証し, Private Token を発行 ◦ Private Token を 検証する • Database は DataCenter 側
  9. $ 2019 - 2021移行初期 - GCEへ • PHP Service •

    HTTP Server, HTTP Client • DataCenterから GCE へ移行 • 同じ時期に一部の Go Service も GCE へ移行(記載無し) • Go Service ◦ HTTP & gRPC Server, gRPC Client ◦ gRPC Server, gRPC Client • Authority Service ◦ Mercari Token を検証し , Private Token を発行 ◦ Private Token を検証する • GCE, Data Center, Kubernetes Cluster 内に Proxy がいる • Database は DataCenter 側
  10. $ 20201- 2024 移行 - GKEへの移行開始時 • PHP Service •

    HTTP Server, HTTP Client • Go Service ◦ HTTP & gRPC Server, gRPC Client ◦ gRPC Server, gRPC Client • Authority Service ◦ Mercari Token を検証し , Private Token を発行 ◦ Private Token を検証する • GCE, Data Center, Kubernetes Cluster 内に Proxy がいる • Database は DataCenter 側
  11. $ 2025 - 2026 現在 - クラスタ内直接通信 • PHP Service

    • HTTP Server, gRPC Client • Go Service ◦ HTTP & gRPC Server, gRPC Client ◦ gRPC Server, gRPC Client • 2 つの異なる用途の Token • Mobileapp や Web 用の Platform Token • Kubernetes Cluster 内の Private Token • Authority Service(One of the Go Services) ◦ Platform Token を検証し , Private Token を発行 ◦ Private Token を検証する • Database は TiDB Cloud or DataCenter 側s
  12. $ Service 間連携の歴史的遷移のまとめ 2018 - 2020 移行期初期 オンプレミス /GCE •

    PHP Applicationは Kubernetesクラスタ 外で運用 • Gateway経由の HTTP通信を, gRPC へ変換して接続 2020 - 2024 移行期中期 GKEへの移行 • PHPをGKEへ移行 しクラスタ内通信が可 能に • 通信は一度インター ネット経由で Gatewayへ出力する フロー 2025 - 2026 現在 クラスタ内直接通信 • PHPから各サービス へgRPC直接通信に 切り替え • 外部からのリクエスト 受付は引き続きHTTP を使用 202x ~ 将来 次期フェーズ • 現在活動中であり, 具体的な成果はまだ 出せる段階にない
  13. $ HTTP Client から gRPC Client へ HTTP Client (gRPC

    移行前) • Guzzle で HTTP Client を実装 • 生の Guzzle では timeout, retry, UA などを個別に指定する 薄いラッパー を用意 • リクエストは Gateway を経由し, Gateway が HTTP を gRPC に変換 する • Gateway には Platform(Mercari)Token を使用 gRPC Client • ext-grpc 拡張で, 実際のネットワーク処 理を担当 ◦ バージョンに関して難あり (後スライドに おいて説明) • grpc/grpc パッケージ github.com/grpc/grpc/tree/master/src/ php • HTTPの時と同じく, timeout, UA などを 指定する薄いラッパー を用意 • Gateway を経由せず直接サービスを Private Token でリクエストする
  14. Load Balancing と Routing • Load Balancing には istio が必須

    Go なら Client Load Balancing があるが, PHP は… 実装の切り分け • 業務ロジックが必要なのは Application • Canary Release は PHP Application で は基本用意していない。危険な Release は 検討の余地があるが, 多くのリリースがある ため実現可能性と相談 $ Application or istio(Envoy)
  15. $ 移行自体は 2021年くらいから 2025年まで BACKGROUND & CONTEXT 周りは Go のサービスで

    gRPC 接続が当たり前の状態だった 移行への契機と確信 当初はチーム内での小さな技術的改善と してスタート その後, Forward Proxy のメンテナンス 上の問題が顕在化し廃止を決定 , さらに オブザーバビリティ改善の必要性が判明 したことで, プロジェクトの方向性がより確 固たるものに CORE OBJECTIVES / 移行の目的 リクエストの追跡を単純化したい 複数サービス間の複雑な通信経路を一元的にトラッキング可能 に DataDog での Trace でオブザーバビリティ向上 分散トレーシングの強化により, ボトルネックの可視化を容易に Token のハンドリングを統一 認証ロジックを標準化し, システム全体のメンテナンス懸念を排 除 エラーの対処を統一化したい 共通のエラーハンドリング定義を適用し, システム品質を安定化
  16. $ 移行の結果得られたもの トラフィックの簡略化と認証認可の強化 Cluster 内での直接呼び出しが可能になり , 通信トラ フィックが大幅に簡略化された • Private

    Token の活用により, よりきめ細かな認証認可の制御が可能 に 構造上課題の解決 Cluster 内限定で使用すべき Private Tokenが, 旧アー キテクチャでは外部経路を経由していた構成上の課題 を根本解決した • 暫定的なForward Proxy IP制限の運用を廃止し、アーキテクチャレベ ルでの恒久的な解決を実現。 オブザーバビリティの大幅な向上 DataDog Tracing における Span の可視化が実現さ れた • 障害発生時, エンドポイントから呼び出し先サービス内部まで一貫した トレースが可能になり , 調査工数を削減。 コード健全化とパフォーマンス改善 長年放置されていたバグや , 既に使われていない不要 なコードを発見・整理できた • コードの保守性(メンテナビリティ)が向上したほか , 無駄な通信を削る ことで Latency 自体も改善
  17. $ 移行の苦労話 CHALLENGE & BACKGROUND エンジニアリング的改善ゆえにプ ライオリティの扱いが難しい 技術負債の蓄積 約50のサービス, 200以上のAPI呼び

    出しが存在し, 中には作りっぱなしで放 置されたものもあるなど, 見えない負債 が積み重なっている状態だった TRANSITION & EXECUTION / 移行の推進 役割の変遷とメンバーの支援 最初はICとして自ら動きつつ, 途中からEMへ立場が変化。 2022年頃に入社したメンバーに対しても, 諦めずに「最後ま でやり切ることの大切さ」を説き続け, やり遂げてもらった 地道な問題の計画的対処 先頭に立って泥臭い問題に対処し, 計画的にクリアしていっ た • すでに使われていない不要なAPI呼び出しの整理 • 誤った定義で呼び出されているAPIの修正 • そもそも常時エラーになっていた箇所の根本解決 お疲れ様です 🙏
  18. $ gRPC Client php-ext の問題 ext-grpc STDERR noise Errors by

    statically-linked Abseil library . • 最新版は 1.82.0 (2026/7/2 に出た)。少なくとも 1.78(2026/2/6) までは absl::InitializeLog の初期化のロ グが STDERR に大量に出てしまう問題があり ,1.64.1 より上に上げることができていなかった ◦ Static link されている abseil の初期化のログが出てしまう問題 • 一方, Debian trixie が 1.64.1をビルドできなくて, bookworm で止まってしまっている 問題はこの辺 , Public issues on GitHub/gRPC • grpc/grpc ◦ https://github.com/grpc/grpc/issues/31772 ◦ https://github.com/grpc/grpc/issues/37178 ◦ https://github.com/grpc/grpc/issues/38336 ◦ https://github.com/grpc/grpc/issues/41525 • Abseil ◦ https://github.com/abseil/abseil-cpp/issues/1656
  19. $ 調査, 検証中 EXISTING EXT-GRPC 複数バージョン検証も改善に至らず 検証済みバージョン 1.65.0, 1.65.1, 1.67.0,

    1.70.0, 1.74.0, 1.78.0 また, パッチを当てたり試したりするなどの 対策も実施したが, 改善は見られなかった ALTERNATIVE / grpc-php-rs の検討 https://github.com/BSN4/grpc-php-rs 開発環境での検証結果(良好) 採用には至っていないが , 開発環境で試したところ , 問題のあったログが出なくなっていることを確認 採用における懸念点と検討状況 • 個人ライブラリであり , 実績・スターが少ない → 現在の ext-grpc に問題があるため, バージョン 固定での採用を検討 • ドロップイン互換があるが , 網羅的な互換性 検証が困難 → 切り戻しが可能なため, 試験的な 導入・検証も視野に
  20. PHP Application on gRPC Server? • Mercari JP では, PHP

    Application で gRPC Server の実績はない • Mercari US では, PHP Application で gRPC Server の実績はある ◦ nginx+php-fpm を使用 ◦ nginx は HTTP/2 gRPC で受けて行かを FastCGRI に落として php-fpm に渡して grpc-status を戻している ▪ REQUEST_URI ▪ QUERY_STRING ▪ STDIN protobuf ▪ HTTP_* 化した metadata ▪ プロトコル変換だけを担い , 中身のデコードは PHP(REQUEST_URI と php://input)が 行っている JP では, 既存のものを置き換える必要性は現状ないという判断 • それをするなら, Go に移行しようという話はあるが , それは別の機会 $ btw, why not to use gRPC Server?
  21. $ proto 定義と PHP パッケージ(例) 生成物は手コミットせず , バージョン付きパッケー ジとして配布する Mercari

    では, proto が Merge されたタイミング でそれぞれの言語用に パッケージを配布
  22. $ gRPC Client 呼び出し(with inHouse Wrapper) 「何を呼ぶか」と「どう呼ぶか」を分 離する "どう呼ぶか "(timeout・認証・エ

    ラー処理・型・トレーシング)を毎回 書かなくても , デフォルトで正しく動く 状態にしている $greeterService を DI Container に登録すれば , 環境毎に切り替えが柔軟に 可能
  23. $ inHouse Wrapper(BaseService 簡略版) Status code をまとめたり , ErrorDetail を

    Parse したり 開発者は BaseService を継 承し、呼びたい API を指定し, invoke を呼ぶ
  24. $ まとめ • PHP Application の 現在 ◦ 規模感, 運用

    • PHP Application の Service 間連携の歴史 ◦ 2018 - 2020 移行期初期 - オンプレミス /GCE ◦ 2020 - 2024 移行期中期 - GKEへの移行 ◦ 2025 - 2026 現在 - クラスタ内直接通信 • PHP Application の gRPC Client の実際 ◦ Application に任せること , istio(Envoy) に任せること ◦ Go の gRPC 使用との違いとチャレンジ • gRPC Client 利用コードの解説 ◦ 簡略化した Application の呼び出しコード解説
  25. $ 積極採用中! • 今日の話とは違いますが , 大規模サービスの DBに興味のある方ぜひ! ◦ 今日の話は mercari-api

    チーム側の話でしたが , もう一つのチームで積極採用し ています! ◦ ご興味のある方 , カジュアル面談いたします。 ◦ このチームに関しては現在 , 英語はやる気があったら良い , くらいの募集としています。 むしろミッションクリティカルな DB を高いレベルで運用していきたい , 改善していきた い, という方を積極採用しています! ▪ 止めずに移行 メルカリの 40TB超・50台MySQLからTiDB Cloudへ エンジニアリング | 株式会社メルカリ - 採用情報