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

運用中の大規模オンラインゲームで8年ぶりにPHPバージョンアップをした話

Yosuke Fukuda
October 07, 2023

 運用中の大規模オンラインゲームで8年ぶりにPHPバージョンアップをした話

Yosuke Fukuda

October 07, 2023
Tweet

Other Decks in Technology

Transcript

  1. 6 サービスの特徴
 • 2015-07-23にリリースされ、8周年を迎えた
 • リクエスト数:1000 - 7000 rps
 •

    アップデート周期:1〜2ヶ月に1度、機能追加を実施
 • ゲームサーバ、運用ツール、バッチがPHPで実装されている
 BLEACH Brave Soulsとは

  2. 13 • PHPのセキュリティサポート懸念
 • 導入しようとしたライブラリでPHP7.x以上が条件
 • 運用ツールのレスポンスタイムが遅い
 • PHPの新しい機能や記法を使いたい
 


    → PHP8.1 にして全部解決や!
 
 ただし、期間は6ヶ月。
 2023年1月スタートで2023年6月末にリリースしたい。
 なぜなら7月末に周年イベントで負荷が高くなる。
 その1ヶ月前までには、PHP8.1を安定動作させておきたい。
 なぜPHPバージョンアップをしたかったか?

  3. 34 • @expectedException アノテーション
 ◦ PHPUnitで例外のテストを書きたい時に使用する
 ◦ PHPUnit9 で廃止
 •

    対応方法
 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止

  4. 35 • @expectedException アノテーション
 ◦ PHPUnitで例外のテストを書きたい時に使用する
 ◦ PHPUnit9 で廃止
 •

    対応方法
 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止
 古いPHPUnitでは
 この書き方はできない 

  5. 36 • @expectedException アノテーション
 ◦ PHPUnitで例外のテストを書きたい時に使用する
 ◦ PHPUnit9 で廃止
 •

    対応方法
 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->setExpectedException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止
 PHPUnit4.5でも使える setExpectedExceptionに書 き換える

  6. 37 • @expectedException アノテーション
 ◦ PHPUnitで例外のテストを書きたい時に使用する
 ◦ PHPUnit9 で廃止
 •

    対応方法
 /* - * @expectedException ValidationException */ public function testCannotPlay() { + $this->expectException(ValidationException::class); $this->game->play(); // should throw an exception } 事前リリースした具体例 @expectedException の廃止
 リリース時に
 expectException に 
 一括置き換えする

  7. 39 • PHPUnit_Framework_TestCase が PHPUnit\Framework\TestCase になった
 ◦ PHPUnit6で追加
 • 対応方法


    事前リリースした具体例 名前空間対応
 
 -class BleachUnitTestCase extends PHPUnit_Framework_TestCase +class BleachUnitTestCase extends PHPUnit\Framework\TestCase {
  8. 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');
  9. 49 • ゲームサーバだけでなく、バッチ処理もPHP8.1対応
 → バッチ処理は独立しているため、後日1つずつ8.1対応。
 • PHP7.3からMCrypt削除されたためOpenSSLに移行。
 →PECLでMCryptをインストールして一旦使い続ける
 • 新パフォーマンスモニタリングの導入(xhprof代替)


    →リリース後に考える
 • PHPUnit10でwithConsecutiveの廃止
 →一旦削除
 
 
 PHPバージョンアップはやることが多い
 #あとでやる
 やることはたくさんあるので、 
 必須で対応しなければならないことに集中する 

  10. 67 3. 運用環境で出た問題(MessagePackの変更)
 なにが起こったか?
 →DBからのデータ読み込みに失敗するようになった
 なぜ?
 →失敗していたのはMessagePackを使用していた箇所。 
  msgpackのバージョンアップ0.5.5 ->

    2.2.0 の際
 文字列の新シリアライズ方式(str8)が採用されたため。
  新しいバージョンで保存したデータを古いバージョンで
  読み込むことができなくなった
  (msgpack v0.5.6から変わった)
 

  11. 84 対策
 opcache.jit の設定をOFFにすることで解決した
 
 なぜかはわからない。初回コンパイル時の挙動に関連?
 (わかる人いたら教えてください)
 
 opcache.jit をOFFにすることでレスポンスタイムは多少悪化した

    (3%くらい)
 予め適切なファイルサイズに分割するのが良いので、大きなPHP ファイルがあるプロジェクトは注意しましょう。
 (自分たちは今後のアップデートで分割予定)
 巨大PHPファイルのJITが時々壊れる問題

  12. 100 バグチケット件数
 
 • デバッグ期間中に報告されたバグチケットは2件だけ
 ◦ いずれもサーバ設定に関連するもので、PHPバージョンアップの 修正に起因するものはなかった。
 ◦ →ユニットテストを通す過程で、PHP_CodeSnifferでは検知でき

    ていなかった修正漏れなどが見つかり対応できた。
 ◦ → デバッグ前にユニットテストを通したことで、修正必要な部分 は対応しきれていた。
 ◦ ユニットテストのバージョンアップは大変だけど大切