Slide 1

Slide 1 text

PHPerKaigi 2026 キーワードは「延命」 リプレイス困難システムの現実的バージョンアップ戦略 @yish0

Slide 2

Slide 2 text

株式会社CARTA HOLDINGS 李丞浩(スンスン) @atto_whicker 紹介 ● 出身は韓国 ● 2017年から日本で生活中 ● 2023年 株式会社CARTA HOLDINGS入社 ● シニアエンジニア一人とバージョンアップ中 ● 初登壇なのでワクワクしてます

Slide 3

Slide 3 text

AGENDA 01 アフィリエイトシステムについて 02 とりあえずバージョンをあげた 03 ミラーリングでロジックを検証する 04 一つのブランチで完結させる 05 うまくいかなかったこと

Slide 4

Slide 4 text

01 アフィリエイトシステムについて

Slide 5

Slide 5 text

PHPerKaigi2026 アフィリエイト広告サービス メディア 広告 サービス 広告主 クリック 計測 成果計測 成果発生 LPページ クリック 遷移 成果通知 成果支払 24時間無停止運用 広告クリック→成果(ex. install)→レポーティング→メディアに支払い

Slide 6

Slide 6 text

PHPerKaigi2026 アフィリエイト広告サービス メディア 広告 サービス 広告主 クリック 計測 成果計測 成果発生 LPページ クリック 遷移 成果通知 成果支払 24時間無停止運用 広告クリック→成果(ex. install)→レポーティング→メディアに支払い 成果を測った結果をもとに お金が計算される

Slide 7

Slide 7 text

PHPerKaigi2026 アフィリエイト広告サービス メディア 広告 サービス 広告主 クリック 計測 成果計測 成果発生 LPページ クリック 遷移 成果通知 成果支払 24時間無停止運用 バージョンアップ対象 ここ

Slide 8

Slide 8 text

PHPerKaigi2026 アフィリエイト広告サービス メディア 広告 サービス 広告主 クリック 計測 成果計測 成果発生 LPページ クリック 遷移 成果通知 成果支払 24時間無停止運用 ● 配信された広告の成果データを収集するサーバー ● PHP5.6 / Amazon Linux 2で動いてる

Slide 9

Slide 9 text

PHPerKaigi2026 システムの現状 ● 新システムへのリプレイス予定 ● 新規開発なし ● メンテナンスのみ ● お金はちゃんと稼いでる 延命させる

Slide 10

Slide 10 text

● 多量のレガシースクリプトphp ● ドメイン知識なし、仕様書もなし ● エンドポイント230本 ● サービス利用者は多い。 この状況、あなたならどうしますか?

Slide 11

Slide 11 text

02 とりあえずバージョンをあげた

Slide 12

Slide 12 text

PHPerKaigi2026 まずはPHP8.4にしてみた ● スクリプトのindex.phpが多くてテストだけじゃ足りない ● そもそもテストのカバレッジは20%以下 ● OSが古くて(Amazon Linux 2)PHP 8.4がセットアップできない 現れた課題↓ ● テストは失敗 → テスト修正 → テスト通過 ● サーバー起動 → 起動失敗

Slide 13

Slide 13 text

PHPerKaigi2026 テストどうするか ● スクリプトのindex.phpは10,000行くらい ● そもそもテストのカバレッジは20%以下 今からカバレッジあげてスクリプトもなんとかする? 大変すぎる

Slide 14

Slide 14 text

PHPerKaigi2026 とりあえず叩いてみる ● 今からロジックを全てテストする仕組みは無理 ● テストでロジックを担保するのは諦めてエラー吐くかだけ調べる どうやって全てのエンドポイントの実行に必要なパラメータを揃える? アクセスログ

Slide 15

Slide 15 text

PHPerKaigi2026 とりあえず叩いてみる ● アクセスログ調査結果、有効エンドポイントは50個くらい ● アクセスログのリプレイによるsmokeテスト追加 ● 本番DBをCloneしてシードデータも揃えた smokeテストからのエラーを地道に修正し、リプレイテストの通過率100%を達成

Slide 16

Slide 16 text

PHPerKaigi2026 サーバーを起動させる ● 既存はremi-repository利用 ● remi-repositoryだとAmazonLinux2ではphp8.3まで ● しかもそのrepositoryはEOLになってる OSもAmazonLinux2023に上げる

Slide 17

Slide 17 text

テストは通った、サーバーも起動された。 でも不安しかない

Slide 18

Slide 18 text

今まで確認したこと ● テストは通る ● エンドポイント叩いてもエラー吐かない ● サーバーは起動できる 結局、挙動に問題あるかは確認できてない。 E2Eテストでも作る?

Slide 19

Slide 19 text

楽したい、、

Slide 20

Slide 20 text

03 ミラーリングでロジックを検証する

Slide 21

Slide 21 text

PHPerKaigi2026 ミラーリング ● テスト書くの大変 ● コード読んで仕様確認するのも大変 ● 楽したい! ● 結局、同じinputが同じoutputを出力するのが分かればいい ● 本番で実際のユースケースで確認できる ● 本番と同じ環境で動きが確認できる ミラーリング

Slide 22

Slide 22 text

PHPerKaigi2026 使ったツール https://github.com/probelabs/goreplay

Slide 23

Slide 23 text

PHPerKaigi2026 使ったツール https://github.com/probelabs/goreplay Proxy❌ Response比較⭕

Slide 24

Slide 24 text

構成 ● GoReplayは本番サーバー内で動く ● Responseの比較はミドルウェアで処理

Slide 25

Slide 25 text

PHPerKaigi2026 差分の確認 ● GETはそのままresponse比較する ● POSTは何が書かれるか確認する仕組みが必要 ○ responseやログを活用 再現が難しい差分 テスト追加で倒す

Slide 26

Slide 26 text

移行 ● listener rule設定で検証済みエンドポイントのみ別のTGに向ける ● 問題発覚時にすぐ取り戻せる

Slide 27

Slide 27 text

感想 ● テストが整ってない状況で使い勝手がいい ○ 実際のユースケースで動きか検証できる ● 実装も難しくなかった ○ AIを利用すればミドルウェアも簡単に出来上がるので工数もそんなにかからない ● 本番と同じ環境で検証できるのは安心できた ○ 後から移行した時、環境による動きの違いなどが心配にならない ○ 同じ環境、同じコードで動いてるので移行時にあまり不安にならない

Slide 28

Slide 28 text

04 一つのブランチで完結させる

Slide 29

Slide 29 text

実はこれ、全部一つのブランチでやりました

Slide 30

Slide 30 text

ワンコード戦略 一つのブランチでphp5.6とphp8.4どっちでも動く

Slide 31

Slide 31 text

PHPerKaigi2026 composerのautoload namespace => pathのマッピング spl_autoload_register()で composerのloader登録

Slide 32

Slide 32 text

PHPerKaigi2026 composerのautoload composerのloaderより優先してloadすれば、ファイルの分岐が出来そう

Slide 33

Slide 33 text

PHPerKaigi2026 autoloadを活用したワンコード composerのloaderより優先する loaderを作成

Slide 34

Slide 34 text

05 うまくいかなかったこと

Slide 35

Slide 35 text

PHPerKaigi2026 ある日の朝 ビジネスサイドからの連絡、 昨夜からレポートの成果記録が全部0件になってるんですが、、、 →一日多量の成果が発生するサービスなのに成果記録が止まっていた。

Slide 36

Slide 36 text

PHPerKaigi2026 成果記録が止まっていた原因 ログディレクトリのRead権限をfluentdに付与するだけだったのに、、 権限付与でミスってしまった クリック 成果通知 成果記録 ここが壊れた

Slide 37

Slide 37 text

PHPerKaigi2026 アラートはあった。が 壊れる前は壊れてることに気づけなかった ● 作られたのは2021年 ● 動くはずのないアラートだった

Slide 38

Slide 38 text

PHPerKaigi2026 結果 ● ピークタイムの前日5時間分の成果は蒸発 ● ビジネス側のクライアント対応 ● バージョンアップ一時停止 成果記録だけは止まってはいけない 苦しい、、どこで壊れるか怖い、、 ⇩

Slide 39

Slide 39 text

PHPerKaigi2026 安全フェンスを作る ● このサービスの根幹、成果記録だけは絶対守る 成果記録の一連の流れを本番に叩いて確認 成果記録の一連の流れを常に確認できる仕組みを導入 クリック 成果通知 成果記録

Slide 40

Slide 40 text

終わりに ● まずは踏み出してみる ○ とりあえず手を動いてみることで次の課題が見える ○ 課題が見えたらそれを一つ一つ倒してたら前に進んでる ● 安全フェンスを作っておく ○ 絶対止まってはいけない仕組みを守る ○ 最悪の状況にはならない・気づける

Slide 41

Slide 41 text

ご静聴ありがとうございました