「 技術系 」一覧

WEB技術,PHP,MySQL,Apache,LAMP,AWS,nginx,システムエンジニア,WEBエンジニアなどの関連記事

Windows Subsystem for Linux上でphp-fpmを動かしてみた

Windows Subsystem for Linux上でphp-fpmを動かしてみた

最近のWindows 10にはLinuxバイナリをそのまま動かすような仕組みが導入されています。これは Windows Subsystem for Linux (WSL) とか Bash on Ubuntu on Windows (BoW) などと呼ばれているもので、VM実行でなくWindowsネイティブでLinuxを動かすという意欲的な取り組みです。


この環境で最新版のPHPをソースコードからビルドし、アプリケーションサーバとして動作させてみました。


本稿執筆時点(2017年5月)ではWSL自体がまだ不安定な印象ですが、nginx+php-fpmを動作させることができました。以下はWindowsのlocalhost 80番ポートでPHPが動作している証拠画像です。「System」欄のunameの表示にMicrosoftという文字列が入っているのがオシャレですね。


f:id:hnw:20170502120845p:image


以下、WSL上でnginx+php-fpmを動かすまでの手順を紹介します。


WSLのセットアップ

Bash on Ubuntu on Windows - Installation Guide」に従ってセットアップします。


PHPのビルド

まずはWSL上でPHPをビルドしてみましょう。


コンパイル済みバイナリをaptでインストールしてもいいのですが、普通にビルドできる程度にWSLが安定してるのかな?という興味から自前ビルドしてみました。


まずは必要パッケージをインストールします。


$ sudo apt update
$ sudo apt install build-essential libxml2-dev zlib1g-dev libcurl4-openssl-dev \
    libjpeg62-dev libpng12-dev libmcrypt-dev libreadline-dev libtidy-dev \
    libxslt1-dev libssl-dev libbz2-dev git autoconf

今回はphpenv+php-buildでPHPをビルドします。


$ curl -L https://raw.github.com/CHH/phpenv/master/bin/phpenv-install.sh | bash
$ mkdir $HOME/.phpenv/plugins
$ cd $HOME/.phpenv/plugins
$ git clone https://github.com/php-build/php-build.git

下記の内容を .bashrc に追記してシェルを再起動します。


PATH=$HOME/.phpenv/bin:$PATH
eval "$(phpenv init -)"

あとはphpenv経由でPHPをビルドするだけです。


$ PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 phpenv install 7.1.4

ビルドにはかなり時間がかかるので注意してください。筆者の手元のマシン(Thinkpad X260、Intel Core i7 2.5GHz)で30分以上かかりました。同じビルドが12インチMacBook(Early 2016、Intel Core m5 1.2GHz)で10分を切ることを考えると、まだお仕事で使えるレベルではない印象です。今後のパフォーマンスチューニングに期待しましょう。


ちょっと遅いことを除けば、ビルド自体は正常に終了します。ここまでは普通のLinuxと大差ありません。


nginx+php-fpmの設定

つぎに、nginxをaptでインストールします。


$ sudo apt install nginx

設定ファイル /etc/nginx/sites-enabled/default の設定のうち、下記部分のコメントアウトを外して有効化します。


        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass 127.0.0.1:9000;
        }

nginxを再起動します。


$ sudo service nginx restart

php-fpmの方はデフォルトの設定ファイルをコピーしてそのまま使います。


$ cd $HOME/.phpenv/versions/7.1.4/etc/
$ cp php-fpm.conf.default php-fpm.conf
$ cp php-fpm.d/www.conf.default php-fpm.d/www.conf

下記コマンドでphp-fpmを起動します。


$ $HOME/.phpenv/versions/7.1.4/sbin/php-fpm

ここで /var/www/phpinfo.php などを設置すれば、nginx経由でphp-fpmを利用することができます。


ただし、この設定だと1秒に1回下記のエラーが出続けます。getsockopt(2) の実装がまだ不完全のようですね。


[01-May-2017 20:06:06] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92)
[01-May-2017 20:06:07] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92)
[01-May-2017 20:06:08] ERROR: failed to retrieve TCP_INFO for socket: Protocol not available (92)

TCPでのプロセス間通信に問題があるならunix domain socketにすればいいじゃない、と考えてunix domain socketも試してみたのですが、phpinfo() の結果が途中で切れてしまうようです。こちらも実装が不完全なようで、16KB超のデータがうまく扱えないとか、そんな制限がありそうな挙動に見えました。TCPの方がまだ安定している状況だといえるでしょう。


まとめ

WSLはまだbeta版なので過度の期待をする方が悪いと言えばそうなのですが、まだ性能が出なかったり未実装のシステムコールもあったりで、お仕事で使えるようになる日は遠いかな、という印象を持ちました。


とはいえ、長期的に期待できる技術なのは間違いないところでしょう。さらなる安定と正式リリースが待ち遠しいですね。

プログラミング学習で擬似コードを活用しよう!

プログラミング学習で擬似コードを活用しよう!

JavaScript学習に役立つお話がありました。 「擬似コード」でロジックを書き出す練習について紹介されています。 www.webprofessional.jp JavaScriptに限らず、プログラミングの基本を学んだら何か動くモノ(プライベートプロジェクト)を作ってみたくなります。でも実際にどうやって進めたらいいのでしょうか? 現実には、プロジェクトは完璧なコードをガンガン書くことではなく、たくさんの試行錯誤とリファレンスを幾度も参照して少しずつできあがるものなのです。 アプリ作成の進め方として、以下の手順が紹介されています。 最初に基本を身に着けよう 計画を立てる コード無しで書いてい…

NO IMAGE

アメリカで何年の4月1日がサマータイムだったか調べてみた

日付関連のテストケースを書いていたら、ロサンゼルスの1970年4月1日0時はサマータイムではないけれど、2012年4月1日0時はサマータイムであることに気づきました。何かの間違いじゃないかと思って改めて調べてみたところ、ロサンゼルスで4月1日がサマータイムだった年は以下の5つの時期に含まれることがわかりました。


  • 1918-1919年
  • 1942-1945年(War Time)
  • 1948年
  • 1974-1975年
  • 2007年以降、現在まで

このうち、1番目は第一次世界大戦中に制定された「標準時間法」 (Standard Time Act)によるものです。アメリカでは初のサマータイム導入でしたが、不評のため2年で廃止されたとか(おそらく終戦の影響もあったでしょう)。


2番目は第二次世界大戦時の省エネ対策として通年の「War Time」が実施されたもので、1942年2月9日から1945年9月30日まで継続的に運用されました。


3番目は1948年にカリフォルニアで電力危機があり、その対策でカリフォルニア州のみ3月14日から通年のサマータイムが実施されたようです。このころ各州バラバラでサマータイムを実施していたようですが、開始時期は大半が4月でした。


4番目は第一次オイルショック(1973年)によるもの。1967年から全米でサマータイムが実施されていますが、この開始時期は4月第1週からでした。しかし、オイルショックの影響により1974年は1月6日から、1975年は2月23日からサマータイム開始だったとのこと。


5番目は「包括エネルギー政策法」(Energy Policy Act of 2005)が2007年から施行され、サマータイム開始が4月第1週から3月第2週にズレたことによるもの。


サマータイムについて調べていたはずが、歴史の教科書に載っているような出来事が関係してくるのは面白いですね。


上のリストを作る方法

上記リストは以下のPHPスクリプトを使って求めました。


<?php
for ($i = 1900; $i <= 2017; $i++) {
    $dt = new DateTime("$i-04-01 00:00:00",
                       new DateTimezone("America/Los_Angeles"));
    var_dump($dt->format("c T"));
}

このスクリプトの出力を下記のようにgrepすれば標準時でないもの(≒夏時間)が抜き出せます。


$ php dst-investigate.php | grep -v ST
string(29) "1918-04-01T00:00:00-07:00 PDT"
string(29) "1919-04-01T00:00:00-07:00 PDT"
string(29) "1942-04-01T00:00:00-07:00 PWT"
string(29) "1943-04-01T00:00:00-07:00 PWT"
string(29) "1944-04-01T00:00:00-07:00 PWT"
string(29) "1945-04-01T00:00:00-07:00 PWT"
string(29) "1948-04-01T00:00:00-07:00 PDT"
string(29) "1974-04-01T00:00:00-07:00 PDT"
string(29) "1975-04-01T00:00:00-07:00 PDT"
string(29) "2007-04-01T00:00:00-07:00 PDT"
string(29) "2008-04-01T00:00:00-07:00 PDT"
string(29) "2009-04-01T00:00:00-07:00 PDT"
string(29) "2010-04-01T00:00:00-07:00 PDT"
string(29) "2011-04-01T00:00:00-07:00 PDT"
string(29) "2012-04-01T00:00:00-07:00 PDT"
string(29) "2013-04-01T00:00:00-07:00 PDT"
string(29) "2014-04-01T00:00:00-07:00 PDT"
string(29) "2015-04-01T00:00:00-07:00 PDT"
string(29) "2016-04-01T00:00:00-07:00 PDT"
string(29) "2017-04-01T00:00:00-07:00 PDT"

上のように、タイムゾーン名がPDT(Pacific Daylight-saving Time、太平洋夏時間)やPWT(Pacific War Time、太平洋戦争時間)などと表示されているのがわかります。


PHPの日付関数はTime Zone Databaseを元にしているので、他の言語でも同じ結果を得る方法があると思います。


感想など

調べてみると、省エネ対策としてカジュアルにサマータイムを実施している歴史がわかって面白いですね。サマータイムが身近でない日本人の感覚だと「本当に省エネ効果あるの?」という気もしちゃいますけど、きっと効果があるからやってるんでしょう。


また、州ごとに夏時間の適用状況が違うのもアメリカならではです。上のスクリプトを America/Detroit とか America/Phoenix などで試すと全然違う結果になって面白いです。


参考URL

Cookpad TechConf 2017 提供 Wi-Fi の裏側

Cookpad TechConf 2017 提供 Wi-Fi の裏側

インフラ部 id:sora_h です。 先週開催された Cookpad TechConf 2017 如何でしたでしょうか。わたしは TechConf において Wi-Fi を担当していて、こちらも好評いただいたようでなによりでした。 というわけで、この記事では TechConf 2017 における Wi-Fi についての詳細を紹介します。 ネットワーク機器設定・サーバー mitamae レシピ等の公開 https://github.com/cookpad/techconf2017-network 今回の紹介する構成のうち、ネットワーク機器およびサーバ側の設定等、ほとんどを GitHub で公開…

NO IMAGE

PHP 7.1.3で時刻の差を取ると時々1マイクロ秒ズレる

本日はエイプリルフールなので、ウソでも本当でも誰も困らないPHPのバグの話をします。


PHP 7.1.0からPHPのDateTimeクラスでマイクロ秒の扱いを強化しているようで、挙動やコードの変更がチラホラ見受けられます。(参考:「PHP 7.1からDateTimeが現在時刻のマイクロ秒まで見るようになった - Qiita」)


時刻と時刻の差分を扱うDateIntervalクラスでもPHP 7.1.0以降マイクロ秒に対応したようで、DateInterval::formatメソッドもマイクロ秒の表示に対応しているようです。さっそく実験してみましょう。


<?php
$dt1=new DateTime("2000-01-01 00:00:00");
$dt2=new DateTime("2006-01-02 03:04:05.6");
$interval = $dt1->diff($dt2);
var_dump($interval->format("%R%Y-%M-%D %H:%I:%S.%F"));
/* Output: string(25) "+06-00-01 03:04:05.600000" */

パラメータ%Fで差分のマイクロ秒が表示できました。ところで、次のような例を試すと奇妙なことに気づきます。


<?php
$dt1=new DateTime("2000-01-01 00:00:00");
$dt2=new DateTime("2006-01-02 03:04:05.000251");
$interval = $dt1->diff($dt2);
var_dump($interval->format("%R%Y-%M-%D %H:%I:%S.%F"));
/* Output: string(25) "+06-00-01 03:04:05.000250" */

0と251の差なので「000251」と表示されるはずが「000250」となっており、1マイクロ秒ズレた結果になっています。


ドキュメント化もされていない機能なので誰も困らないと思いますが、一応バグ報告しておきました。


– PR –
– PR –