Share
Embed
運用中の大規模オンラインゲームで8年ぶりにPHPバージョンアップをした話
Yosuke Fukuda
October 07, 2023
Transcript
111 slides
-
2 2012年 KLab株式会社 に入社 2016年からBLEACH Brave Soulsにサーバサイドエンジニアとして参画。 2021年からサーバチームのリーダーをしています。 前職は、金融システムや物流管理のシステムを作っていました。
福田 陽介 エンジニア KLabGames事業本部 KLab株式会社 画像 -
3 今日話すこと • 前提説明(ゲームの説明・バージョンアップの理由) • 開発方針(修正箇所洗い出し・ブランチについて) • 後回しにしたこと • 運用中プロジェクトでPHP8.1切り替えをどう進行したか
• バージョン移行後に起こったトラブル • 数値で見る実績と効果 • まとめ -
6 サービスの特徴 • 2015-07-23にリリースされ、8周年を迎えた • リクエスト数:1000 - 7000 rps •
アップデート周期:1〜2ヶ月に1度、機能追加を実施 • ゲームサーバ、運用ツール、バッチがPHPで実装されている BLEACH Brave Soulsとは -
7 • バージョンアップ前のPHPバージョンは ◦ 5.5.13 ▪ 2014-01-26 リリース ▪ EOLは
2016-07-10 なぜPHPバージョンアップをしたかったか? -
12 • PHPのセキュリティサポート懸念 • 導入しようとしたライブラリでPHP7.x以上が条件 • 運用ツールのレスポンスタイムが遅い • PHPの新しい機能や記法を使いたい
→ PHP8.1 にして全部解決や! なぜPHPバージョンアップをしたかったか? -
13 • PHPのセキュリティサポート懸念 • 導入しようとしたライブラリでPHP7.x以上が条件 • 運用ツールのレスポンスタイムが遅い • PHPの新しい機能や記法を使いたい
→ PHP8.1 にして全部解決や! ただし、期間は6ヶ月。 2023年1月スタートで2023年6月末にリリースしたい。 なぜなら7月末に周年イベントで負荷が高くなる。 その1ヶ月前までには、PHP8.1を安定動作させておきたい。 なぜPHPバージョンアップをしたかったか? -
33 • @expectedException アノテーション ◦ PHPUnitで例外のテストを書きたい時に使用する ◦ PHPUnit9 で廃止 事前リリースした具体例
@expectedException の廃止 -
34 • @expectedException アノテーション ◦ PHPUnitで例外のテストを書きたい時に使用する ◦ PHPUnit9 で廃止 •
対応方法 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止 -
35 • @expectedException アノテーション ◦ PHPUnitで例外のテストを書きたい時に使用する ◦ PHPUnit9 で廃止 •
対応方法 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止 古いPHPUnitでは この書き方はできない -
36 • @expectedException アノテーション ◦ PHPUnitで例外のテストを書きたい時に使用する ◦ PHPUnit9 で廃止 •
対応方法 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->setExpectedException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止 PHPUnit4.5でも使える setExpectedExceptionに書 き換える -
37 • @expectedException アノテーション ◦ PHPUnitで例外のテストを書きたい時に使用する ◦ PHPUnit9 で廃止 •
対応方法 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止 リリース時に expectException に 一括置き換えする -
39 • PHPUnit_Framework_TestCase が PHPUnit\Framework\TestCase になった ◦ PHPUnit6で追加 • 対応方法
事前リリースした具体例 名前空間対応 -class BleachUnitTestCase extends PHPUnit_Framework_TestCase +class BleachUnitTestCase extends PHPUnit\Framework\TestCase { -
40 • PHPUnit_Framework_TestCase が PHPUnit\Framework\TestCase になった ◦ PHPUnit6で追加 • 対応方法
• エイリアスを使うことでPHPUnit4.5でも名前空間っぽい記載が できる 事前リリースした具体例 名前空間対応 -class BleachUnitTestCase extends PHPUnit_Framework_TestCase +class BleachUnitTestCase extends PHPUnit\Framework\TestCase { +class_alias('PHPUnit_Framework_TestCase', 'PHPUnit\Framework\TestCase'); -
42 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 • PHP7.3からMCrypt削除されたためOpenSSLに移行 • xhprof代替の新パフォーマンスモニタリングの導入
• PHPUnit10でwithConsecutiveの廃止 -
43 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 • 新パフォーマンスモニタリングの導入(xhprof代替)
• PHPUnit10でwithConsecutiveの廃止 締め切りに間に合わない! -
44 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 • 新パフォーマンスモニタリングの導入(xhprof代替)
• PHPUnit10でwithConsecutiveの廃止 -
45 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 → バッチ処理は独立しているため、後日1つずつPHP8.1対応。 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 •
新パフォーマンスモニタリングの導入(xhprof代替) • PHPUnit10でwithConsecutiveの廃止 -
46 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 → バッチ処理は独立しているため、後日1つずつPHP8.1対応。 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 →PECLでMCryptをインストールして一旦使い続ける •
新パフォーマンスモニタリングの導入(xhprof代替) • PHPUnit10でwithConsecutiveの廃止 -
47 PHPバージョンアップはやることが多い • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 → バッチ処理は独立しているため、後日1つずつPHP8.1対応。 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 →PECLでMCryptをインストールして一旦使い続ける •
新パフォーマンスモニタリングの導入(xhprof代替) →リリース後に考える • PHPUnit10でwithConsecutiveの廃止 -
48 • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 → バッチ処理は独立しているため、後日1つずつPHP8.1対応。 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 →PECLでMCryptをインストールして一旦使い続ける • 新パフォーマンスモニタリングの導入(xhprof代替)
→リリース後に考える • PHPUnit10でwithConsecutiveの廃止 →一旦削除 PHPバージョンアップはやることが多い -
49 • ゲームサーバだけでなく、バッチ処理もPHP8.1対応 → バッチ処理は独立しているため、後日1つずつ8.1対応。 • PHP7.3からMCrypt削除されたためOpenSSLに移行。 →PECLでMCryptをインストールして一旦使い続ける • 新パフォーマンスモニタリングの導入(xhprof代替)
→リリース後に考える • PHPUnit10でwithConsecutiveの廃止 →一旦削除 PHPバージョンアップはやることが多い #あとでやる やることはたくさんあるので、 必須で対応しなければならないことに集中する -
66 3. 運用環境で出た問題(MessagePackの変更) なにが起こったか? →DBからのデータ読み込みに失敗するようになった なぜ? →失敗していたのはMessagePackを使用していた箇所。 msgpackのバージョンアップ0.5.5 ->
2.2.0 の際 文字列の新シリアライズ方式(str8)が採用されたため。 -
67 3. 運用環境で出た問題(MessagePackの変更) なにが起こったか? →DBからのデータ読み込みに失敗するようになった なぜ? →失敗していたのはMessagePackを使用していた箇所。 msgpackのバージョンアップ0.5.5 ->
2.2.0 の際 文字列の新シリアライズ方式(str8)が採用されたため。 新しいバージョンで保存したデータを古いバージョンで 読み込むことができなくなった (msgpack v0.5.6から変わった) -
70 暫定対処 並行稼働期間は新シリアライズ方式(str8)の設定をOFFにする msgpack 0.5.5も 2.2.0 も同じデータ形式で保存される
3. 運用環境で出た問題(MessagePackの変更) -
71 暫定対処 並行稼働期間は新シリアライズ方式(str8)の設定をOFFにする msgpack 0.5.5も 2.2.0 も同じデータ形式で保存される
3. 運用環境で出た問題(MessagePackの変更) php.ini msgpack.use_str8_serialization = Off -
76 バグ修正のためプログラムを本番環境にデプロイした際 約3%の確率でSegmentation fault が起こるようになった。 →バグ修正したプログラムが原因かと考えRevertしてデプロイす るも解消せず →Webサーバの再起動をするとなぜか解消した →
$a = 1 + 1; のような関係ない差分をデプロイしても発生 巨大PHPファイルのJITが時々壊れる問題 -
82 対策 opcache.jit の設定をOFFにすることで解決した なぜかはわからない。初回コンパイル時の挙動に関連? (わかる人いたら教えてください)
巨大PHPファイルのJITが時々壊れる問題 -
83 対策 opcache.jit の設定をOFFにすることで解決した なぜかはわからない。初回コンパイル時の挙動に関連? (わかる人いたら教えてください) opcache.jit をOFFにすることでレスポンスタイムは多少悪化した
(3%くらい) 巨大PHPファイルのJITが時々壊れる問題 -
84 対策 opcache.jit の設定をOFFにすることで解決した なぜかはわからない。初回コンパイル時の挙動に関連? (わかる人いたら教えてください) opcache.jit をOFFにすることでレスポンスタイムは多少悪化した
(3%くらい) 予め適切なファイルサイズに分割するのが良いので、大きなPHP ファイルがあるプロジェクトは注意しましょう。 (自分たちは今後のアップデートで分割予定) 巨大PHPファイルのJITが時々壊れる問題 -
92 バージョン情報 5.5.13 バージョンアップ前 8.1.13 バージョンアップ後 PHP 4.5 10.3 PHPUnit
1.4.10 3.7.2 PHP_CodeSniffer 0.5.5 2.2.0 msgpack -
99 バグチケット件数 • デバッグ期間中に報告されたバグチケットは2件だけ ◦ いずれもサーバ設定に関連するもので、PHPバージョンアップの 修正に起因するものはなかった。 ◦ →ユニットテストを通す過程で、PHP_CodeSnifferでは検知でき ていなかった修正漏れなどが見つかり対応できた。
◦ → デバッグ前にユニットテストを通したことで、修正必要な部分 は対応しきれていた。 -
100 バグチケット件数 • デバッグ期間中に報告されたバグチケットは2件だけ ◦ いずれもサーバ設定に関連するもので、PHPバージョンアップの 修正に起因するものはなかった。 ◦ →ユニットテストを通す過程で、PHP_CodeSnifferでは検知でき
ていなかった修正漏れなどが見つかり対応できた。 ◦ → デバッグ前にユニットテストを通したことで、修正必要な部分 は対応しきれていた。 ◦ ユニットテストのバージョンアップは大変だけど大切 -
107 バージョンアップ後に起こったトラブル • 本番環境デプロイ時に3%の確率でSegmentation faultが発生 する障害 ◦ opcache.jit の設定をOFFにすることで暫定対応 •
PHP8.1が早すぎてタイムアウトのテストができない問題 ◦ キャラ数を10倍に増やすことで対応 まとめ -
108 数値で見る実績と効果 • 164人日 • ゲームサーバ 42%改善 • ユニットテスト 50%改善
• 運用ツール 40%改善 まとめ