PHP」タグアーカイブ

PHPカンファレンス2017に行ってきた

2017年10月8日に大田区産業プラザPIO 日本PHPユーザ会によるPHPカンファレンス2017に参加してきました。このカンファレンスは数年ほど一般参加させていただいております。

今回は某ライブのDay2公演と日程が被っており、前日にDay1公演だけ観てくるつもりだったのですが、体調を盛大に崩し参加できず……。この日もまだ病んだ状態でした。

行く途中でmeijiの「速攻元気」というゼリー飲料を買って飲んだのですが、これ、成分的にはカフェインの無いエナドリなんじゃないの?という代物で、カロリーは控えめ。病んでいる時にはなかなか効果があるんじゃないかと思います。

※以下登壇者名について敬称略

基調講演は見られなかったのですが、今回は「チャレンジ」がテーマのようです。パンフレットの表紙にも「challenge!」と書かれています。今回はDocker関連のカンファレンスが3つも有りました。私は「開発環境をDockerにしてみませんか? necomori LLC 高橋邦彦(kunit)」を拝聴しました。

開発者間で統一する為の開発環境というと最近はVagrantが一般的ですが、Dockerにしてみるのもいいのでは?という話題でした。vagrant+ansibleの環境は意外と壊れる問題、バージョン間の差異が出やすいなどが理由でした。Dockerの基本的な事からの説明、設定ファイルそれぞれの意味などが丁寧に説明されました。私は実際にDockerを使った事は1度もないため、docker-composeなどワードとしては知っているが具体的にどういう物なのか知らないレベルの人に助かるセッションでした。Docker上のポートと親ホストではポートが変換される事など知らない事も有りました。

他にはレガシーシステムをどう今時に近いものへ持って行くか、という話題も多かった気がします。「PHP Version UpとAWSへの移行 グリー株式会社 吉本 将宣」では、アプリケーション間のRequireすらあるような闇の深い環境をどう改善していったかという話でした。

レガシーと言ってもどこかで意を決してやらなければいけない。始めた後は少人数によるプロトタイピング、先に共通コードの完成を目指す、そこでの問題の先取り、開発環境の統一など、やる事をやっていき、「PDCAを普通に回した」「円滑なコミュニケーション」と言った説明からも有るように、体制・計画としてしっかりやって行く事が大事なのだなと思いました。

セッションとしては「それらに取り組み移行が出来た事が組織としての財産になった」「お互いのシステムへの相互理解、組織を越えたチームワークが得られた」というニュアンスのまとめになっており、それらが出来れば組織としても参加した個人としても強いだろうなという印象でした。

「運用、追加開発しづらいPHPアプリケーションに未来を与える方法  株式会社VOYAGE GROUP リードエンジニア 田中 改」では、実際に移行をするうえでどんなテクニックが用いられたか踏み込んだ話も有りました。モニタリングを入れる事でアプリケーションの改善点がわかる、AWSのALBを使ったパスベースルーティングを用いる事で、実装が終わった新ロジックから切り替えて行く事が出来るなどのお話が有りました。

AWSのALBは私自身も業務上活用していますが、アプリケーションの改修・移行に用いるというのは初めて聞く用法で面白かったです。アプリケーション全体を切り替えないので徐々に切り替えが行える、問題があった時は切り戻しが楽というのは有効度が高そうです。ただしセッション管理には気を付ける必要があります。

最後のライトニングトークも毎回面白いですが、@MiracleTShirt09による「MDD(筋肉駆動開発」では、強いプログラマになる為に必要なのは筋肉であったことが判明したり、他にもユーザー対応を行う上での取り組み、カンファレンスを主宰する側の取り組みの話(ライブ感が凄い)、APIを設計するうえでSwaggerを活用する事でドキュメントとソースの乖離を防ぐ仕組み、イケていないテストデータの話、初めて聞いた「Google Cloud Spanner」の話(既存のRDBとの互換性は無いけどAuroraよりもスケールするRDB(NoNoSQL)みたいな感じなのかな)、PECL拡張を登録するまでの話(WindowsバイナリはPECL側が自動でビルドしてくれていた!)など、今回もなかなか知らない、聴く機会のない内容が多く興味深かったです。

今回はどこかで困っている、辛い、レガシーであるといった部分に「そこで困っているよねぇ」と同意できる話題と、それに対する取り組みの話がちょくちょく有って、そういう意味でも「challenge!」だったんだろうなぁという印象のPHPカンファレンス2017でした。どんなに有名な所でもPHPのバージョンは古かったり、辛い部分が有ったりするのは共通で、そこをどう解決して行けたか、しようとしたかという話はなかなか参考になりました。

今回は懇親会も初めて参加したのですが、懇親会LTもなかなか面白かったです。病み上がりに長丁場だったので途中で抜けましたが、もし次が有ればもっといろんな人に話しかけられたらなぁと、思ったり思わなかったり。

Amazon Linux AMI 2017.09で今こそApacheをhttp/2対応にする手順

Aローリングリリースで提供されるAmazon Linux AMIが先日バージョン2017.09となりました。数年ぶりにOpenSSLのバージョンが更新される(1.0.1k → 1.0.2k)等、それなりに変更点の大きいリリースとなっており、これによりディストリビューション標準のパッケージのみでApache/Nginxのhttp/2に対応できるようになりました。ソースコンパイルを伴うミドルウェアは実運用においては、メンテナンス性に難が有りましたが、今後は簡単に導入が可能なはずです。「今こそ」、なタイミングかと思いますので対応していきます。

Amazon Linux AMIのバージョン確認

# cat /etc/system-release
 Amazon Linux AMI release 2017.09

まだ2017.09になっていなければ(問題無い事を確認したうえで)yum updateしてください。
古いリリースはセキュリティ修正も行われません。

前提

Webサーバー

Apache 2.4を使います。WordPressを動かす為にPHP 7.1を使っています。

SSL/TLSへの対応

既にWebサイトは(常時)SSL/TLS対応になっているものとして進めます。
まだであれば、Let’s Encryptなど各種方法で対応して下さい。

ロードバランサ

ELB(ALB/CLB/NLB)は未導入のものとして話を進めます。

PHP-FPMの導入

なぜいきなりPHPの話になるかというと、Apacheでhttp/2に対応するためには、Prefork MPMではなく別のMPMを使う必要が有るからです※1。その為、PHPをApacheモジュール版ではなく、
php-fpmで動作させる必要があります。

※1: Apache 2.4.27以降はmod_http2がprefork MPMに対応しない。

導入手順

php-fpmをyumからインストール。PHP 7.1を利用しているので php71-fpm になっています。

# yum install php71-fpm

Apache側の現在のMPMを確認

# /usr/sbin/httpd -V | grep MPM
 Server MPM: prefork

preforkで動いています。

/etc/httpd/conf.modules.d/00-mpm.conf

で設定されているので上記ファイルを開き、

LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

を#でコメントアウト

#LoadModule mpm_event_module modules/mod_mpm_event.so

のコメントアウトを外しevent MPMを使うように修正

構文チェック

# /usr/sbin/httpd -t
 AH00513: WARNING: MaxRequestWorkers of 64 is not an integer multiple of ThreadsPerChild of 25, decreasing to nearest multiple 50, for a maximum of 2 servers.
 Syntax OK

スレッド数の部分で警告が出ていますが、これは後で修正します。

バーチャルホストの設定

PHPファイルの実行をphp-fpmに渡すための設定を追加する。
Apache(やNginx)とphp-fpmの接続は、UNIXドメインソケットと127.0.0.1:9090へのTCP/IP接続が選べますが、ApacheとPHPを同じサーバーで実行する場合は、応答速度の速いUNIXドメインソケットの方で設定します。
対象のバーチャルホスト設定に以下を追記。拡張子がphpのファイルをphp-fpmに渡します。

<FilesMatch \.php<pre wp-pre-tag-6=""></pre>amp;amp;amp;gt;
    SetHandler "proxy:unix:/var/run/php-fpm/php-fpm.sock|fcgi://localhost"
</FilesMatch>

FilesMatchにマッチしたファイルしかphp-fpmに渡されない事に注意。

構文チェック

# httpd -t
 AH00513: WARNING: MaxRequestWorkers of 64 is not an integer multiple of ThreadsPerChild of 25, decreasing to nearest multiple 50, for a maximum of 2 servers.
 Syntax OK

php-fpm側の設定

ユーザーの設定やソケットファイル名の設定など修正。

# cp /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.conf.orig
# vim /etc/php-fpm.d/www.conf
# diff /etc/php-fpm.d/www.conf.orig /etc/php-fpm.d/www.conf
38c38
< listen = /var/run/php-fpm/www.sock
---
> listen = /var/run/php-fpm/php-fpm.sock
48,49c48,49
< ;listen.owner = nobody
< ;listen.group = nobody
---
> listen.owner = apache
> listen.group = apache
55c55
< listen.acl_users = apache,nginx
---
> ;listen.acl_users = apache,nginx

php-fpmのログレベルをnoticeからwarningに変更する。

# vim /etc/php-fpm.conf

;log_level = notice

を以下に修正

log_level = warning

php-fpmの起動とhttpdの再起動

# /etc/init.d/php-fpm start
 Starting php-fpm-7.1: [ OK ]

# /etc/init.d/httpd restart
 Stopping httpd: [ OK ]
 Starting httpd: AH00513: WARNING: MaxRequestWorkers of 64 is not an integer multiple of ThreadsPerChild of 25, decreasing to nearest multiple 50, for a maximum of 2 servers.
 [ OK ]

まずはこの時点でWebサイトが正常に表示されることを確認する。
次にMPMの確認

# /usr/sbin/httpd -V | grep MPM
 Server MPM: event

あとはドキュメントルートに適当にphpinfoを実行するファイルを置いて確認。
下記ファイルをWebブラウザで開いた際に、Server APIに
「Apache handler 2.0」ではなく「FPM/FastCGI」と表示されていればOK。

phptest.php
<?php
    phpinfo();

※確認後はこのファイルの消し忘れにご注意ください。

これでApacheがevent MPMかつ、php-fpmでPHPが動作する環境になりました。
MPMがeventになった事により、多数のアクセスに対しても(適切にチューニングをすれば)preforkよりもスケールする事が出来ると思われます。

http2/対応

ここまでくればhttp/2対応は簡単です。
Amazon Linuxバージョンアップの時点で、mod_http2はすでに導入されているので

# ls -l /etc/httpd/modules/ | grep http2
 -rwxr-xr-x 1 root root 253544 Sep 25 08:20 mod_http2.so

対象のバーチャルホストに以下を追記

Protocols h2 http/1.1

し、httpdを再起動

# /etc/init.d/httpd restart

これでもうhttp2対応です。お疲れ様でした。

なお、Apacheで出ている、MaxRequestWorkersやThreadsPerChildのワーニングについては、MaxRequestWorkersがThreadsPerChildの整数倍になるように、各自調整を行ってください。ここの調整はアクセス数などによっても異なります。

ci-phpunit-testが動かない理由がphp7ccだった話

Composerで導入できる kenjis/ci-phpunit-test は Codeigniter 3.x で快適にPHPUnitによるテストが書ける便利なツールです。

その ci-phpunit-test にはクラスのメソッド、PHP標準の関数、定数などを書き換える事が出来る、モンキーパッチ機能が有るのですが。なぜか動かなくなり悪戦苦闘していました。

原因はComposerでグローバルにインストールしたphp7ccでした。

sstalle/php7cc はそのPHPアプリケーションが PHP 7.0 で動作するうえで問題が無いかを静的解析するツールなのですが、どちらも nikic/php-parser というPHPで書かれたPHPパーサに依存しており、違うバージョンが入ってしまうことが原因のようです。

nikic/php-parser v1.2.1 の composer.json の記述(抜粋)
nikic/php-parser: ~1.4,

kenjis/ci-phpunit-test v0.15.0 の composer.json の記述(抜粋)
nikic/php-parser: ^2.1|^3.0

とりあえずグローバルに入っている古いバージョンをremoveする事で、問題なく動くようになりました。

なお、php7cc の代わりになりそうな物としては wimg/PHPCompatibility があります。php7cc でカバーしていた範囲をすべてチェック出来るかはまだ分からないのですが、チェックのターゲットとして、PHP 5.6 以前のバージョンであったり、PHP 7.1 にも対応してるようです。