btn_arrowcorroborationengineerEngineerhamburgericon-angleicon-externalicon-facebookicon-hatebuicon-instagramicon-lineicon-linked_inicon-pinteresticon-twittericon-youtubelicense-foreignlicenselogo-gree

TECH BLOG

【TECH BLOG #26】PHP5からPHP7への移行

技術戦略チームのTAです。
今回はPHP7移行について取り上げたいと思います。

なぜ古いものから移行する必要があるのか

グリーエンターテインメントではいくつかのゲームを運営しています。
リリース時期も様々で、比較的新しいものから長期運営となっているものまであります。
今回はその中でも、主に長期運営のプロダクトへ焦点を当てたお話になります。

長期運営する上で課題となることはいくつもありますが、その1つとしてバージョン更新が挙げられます。
ゲームに限らずアプリケーションはいくつもの要素を組み合わせて成り立っていますが、それぞれにバージョン…つまり変更や修正されたものが積み重なっていくわけです。
OSであったり、ミドルウェアであったり、ライブラリであったり。

各要素は時間の経過とともに古くなり、より新しいバージョンが出てきます。
当然ではあるのですが、それは何もしなくてもリスクが増加するということです。
ここで言うリスクとはセキュリティ的なものやベンダーサポート的なものが主ですが、サポートは提供停止や強制アップデートによるサービス停止のリスクも含みます。
とはいえ、基本的には古いシステムでもそれなりに動き続ける場合が多く、それゆえにそれらの問題は後回しにされがちです。

ということで、長らく5系で稼働していた担当プロダクトのPHPですが7系へ移行しました。
ついでにOSを含む環境の更新も実施しました(どちらかというと本来のメインはこちらでしたが)。

PHP7移行で実施したこと

移行する上で実施したことは、大まかに以下の通りです。
・コード修正
・開発環境整備、動作検証
・本番環境準備
・本番移行

コード修正

コード修正にあたっては、まず静的解析によるエラーおよび警告の修正を実施しました。
静的解析に用いたツールは、普段から開発業務で使用しているPhpStormになります。
大量のソースをすべて手作業で確認するのは現実的ではないため、あらかじめ問題が起こりそうな部分を先行で対応する形です。
PHP5系と7系の両方で動作するように、また挙動が変化しないよう考慮しながら修正し、少しずつリリースしました。
ただし静的解析も完璧ではなく、修正実施の可否はリストにまとめて都度判断しています。
特に動的な変数名の使用によるundefinedなど、警告メッセージに従って修正することで逆に不具合となってしまう箇所には注意が必要でした。

▲静的解析を元にした修正リスト

開発環境整備、動作検証

開発環境の整備では、旧環境との入れ替えがなるべくスムーズに進むよう配慮しました。
・QAを行う検証環境は複数存在するため、日程に間隔を空けて順次入れ替え
・開発メンバー向けの環境は各自の作業に支障がないタイミングをヒアリングし、簡単な移行手順書を作成して共有
こうして環境移行自体は大きな問題なく実施できました。

とはいえ不具合なしとはいかず、コード的に考慮漏れしている箇所や言語仕様の差異による挙動変化でトラブルはありました。
言語仕様の差異は公式ドキュメントに記載があるものですが、やはり事前にすべて対応することは難しいです。

もし今後似たような対応をするという方は、事前にPHP公式ドキュメント付録の「PHP ○.○.x から PHP ○.○.x への移行」のうち、対応するバージョンだけでも熟読しておくことをお勧めしておきます。
対応漏れを防ぐのは難しいですが、トラブルが起きたときの原因特定は早くなると思います。

本番環境準備

本番環境の準備ではインフラ担当者と連携し、慎重に準備を進めました。必要モジュールの洗い出しから使用バージョンの確認、設定ファイルの確認など…。
出来上がったマシンイメージを使用した、開発環境での挙動確認も実施しました。
ほぼすべてのバージョンが変わっているため、設定ファイルも旧環境と同じにはできません。
新しいバージョンに合わせた追加や変更などを依頼し、再度マシンイメージを受け取って検証。
手間ではありますが本番移行で大きな障害を出すわけにはいかないため、ここは時間をかけました。

本番移行

本番移行に関しても全サーバー同時ではなく、段階を分けて移行しました。
サーバーの役割によって移行スケジュールを分割し、さらに影響がありそうなWebサーバーについては一部を先行で移行するなど。
全体の移行スケジュールは様子を見て柔軟に日程調整しました。

それぞれの移行に関してはサービスメンテナンスを設定し、メンテナンス時間内の作業項目をリスト化したタイムテーブルを用意しました。
初回は見込みがやや甘く、予定時間ギリギリになってしまったことが反省点です。
切り戻しの可能性も想定していましたが、その必要がなかったことは良かったですね。

▲分単位で作業項目を設定したタイムテーブル

発生した問題点と解決法

一連の作業で発生した問題点と解決方法の一部を紹介します。

・静的解析が終わらない
ソース量が膨大すぎて、解析開始から時間を置いても全然結果が出てきませんでした。
プロジェクトルートディレクトリから解析するのをやめ、下位ディレクトリをそれぞれ解析して対応しました。

・開発環境で何回も環境整備するのが大変
マシンイメージの検証や各開発サーバーの環境構築のため、同じ環境整備を何回も行う必要がありました。
最初は手作業で対応したものの非効率的だったので、Ansibleで再構築できるようにしました。

・デプロイを開発環境で検証するのが難しい
本番では様々な役割を持ったサーバーがいくつかあり、それぞれに適したデプロイを行うようになっています。
開発環境ではそのような構成になっていないため、どう検証するかが問題です。
今回の対応方針としては、本番同等ながら最小構成のサーバー群を起動し、検証完了したらすべて終了するようにしました。
AWSを使用しているため、CloudFormationによる構築と破棄により効率化しています。

・PHP的なバージョン差分
問題になる箇所はいくつかあり、プロダクトに依存しやすいところだと思います。
基本的には見つかったら内容に合わせて修正、という形を取りました。
内容としては前述の「PHP公式ドキュメント付録」の通りですが、特に注意したほうがいいと個人的に感じたポイントを挙げておきます。
5.6から7.4への移行を想定しています。
・エラーや例外の取り扱いの変更
・エラーレベルの変更
・intの取り扱いの変更
・文字列の取り扱いの変更
・mt_randのアルゴリズム変更
・デフォルトでPEAR無効化

最後に

ここまでざっと実施したことを書きましたが、いかがだったでしょうか。
短くまとめていますが実際の移行には長い期間がかかっており、神経を使うことも多かったです。
PHP7移行対応の合計としては5ヶ月ほどだったと思います。
ただ途中で優先度の高い別作業や日程調整が入ったこともあり、開始から終了まではもっとかかりました。
また大きな障害というのは起きていませんが、完璧に進んだということもなかったです。
特に本番に向けた作業においては、何かが起きるものと想定して動くのが良いかと思いました。

今回の経験は似たような移行作業でも通じるところがあると思うので、ノウハウとしてまとめて活かしていきたいです。
そのときはまた記事にできたらいいですね。
PHP8移行とか!?(まだ全然予定ないですが)

information

グリーエンターテインメント株式会社 広報担当

東京都港区六本木6-10-1 六本木ヒルズ森タワー

E-mail:info-ent@ml.gree.net