ぷぎがぽぎ このページをアンテナに追加 RSSフィード

2013-12-15

[][] GistをDB代わりにしてブログを作ってみた

Gistはほんと便利です。

Markdownで書いておけば、ブログの記事みたいにいつでも公開できるし、編集できるしと。

だったらいっそのことAPIでGistの内容をとってきて、自分のブログっぽく表示できたら良いなと思って、AngularJS でやってみた。詳細については実際にGistで書いた記事に続く...

自分のgistでないと読み込んだとしても表示しないように制御してあります。

2013-12-06

[] "PHP Fatal error: Allowed memory size of xxx" で落ちる前にできること

PHP Advent Calendar 2013 - 7日目

昨日は@hidenorigotoさんのBeyond MVCでした。

今日は PHPあるある的な問題に対する対策について少しばかり書きたいと思います。

f:id:brtRiver:20131206232611j:image

歯ブラシを持たせてみた *1

メモリ不足でよくやる対応

PHPで大量のデータを扱ったりすると、設定された利用可能な最大メモリ使用量を超えて

PHP Fatal error:  Allowed memory size of 524288330 bytes exhausted (tried to allocate 351 bytes) in ....

というエラーが発生して対応に追われたことの経験がある人はかなり多いと思います。

そもそも環境のメモリに余裕があるならmemory_limitを調整してメモリの使用量を増やしたり

あまり余裕がない場合は暫定的対応として、該当処理部分だけ

<?php
...
ini_set('memory_limit', '512M');
...

としたり、バッチ処理だったら

$php -d "memory_limit=512M" hoge.php

としたりしますよね。

今日のお話はメモリ不足エラーになる前にできることがあるよねというお話です。

嫌な兆候を事前に察知

突然データが莫大になりメモリ不足になることもあるでしょうが、事前に使用メモリ量が増大して来るケースも多々あります。

つまり、エラーを起こしてしまう前に "最大メモリ量のxx%を超えたらログに残す" ように仕込めば慌てずに済みますよね。

とはいえ、すでに稼働しているアプリでこのような仕込みを行うためにはどうしたらよいでしょう?

フレームワークのフックポイントを利用する

Webアプリケーションの何かしらのフレームワークを使っているなら、大抵処理を終えた後に何か仕込むことができるようになっていると思います。Symfony2 だと Event Listener があるので、`kernel.response` にメモリ使用量をチェックしてログに吐くようなものを仕込んでおけばOKですね。DIでロガーを渡せば簡単に好きなロガーで書き込みもOK。

<?php
...
    public function checkPeakMemory()
    {
        // 512M のように M で指定されている前提なのでアレでごめんなさい
        list($max) = sscanf(ini_get('memory_limit'), '%dM');
        $peak = memory_get_peak_usage(true) / 1024 / 1024;
        $used = ((int) $max !== 0)? round((int) $peak / (int) $max * 100, 2): '--';
        if ($used > 85) {
            $this->logger->warning(sprintf('Memory peak usage warning: %s %% used. (max: %sM, now: %sM)', $used, $max, $peak));
        }
    }

CakePHP なら Event Manager で同じようなことができるんじゃないでしょうか(未確認)

レガシーなアプリなんだけど

継ぎはぎされた素晴らしい実績のあるレガシーコードでそんな仕組みなどない!手を入れづらい!というケースもあるでしょう。

が、PHPには auto_prepend_fileというphp.ini ディレクティブの設定があり、これで上記と同じようなコードを書いてregister_shutdown_functionで指定しておけばアプリケーションの開始時にファイルが読み込まれ、スクリプト処理が完了したとき、あるいは exit() がコールされたときに登録したメソッドが呼ばれます。

ここで ログを残すであればerror_logでざっくりと指定すれば楽ですね。

この方法のメリットは既存のコードに一切修正を加えずにアプリの処理終了時にもれなく処理を練り込むことができるという点です。今回のような使い方以外でも色々と便利な利用シーンがあると思います。

<?php
register_shutdown_function(function(){
    // 512M のように M で指定されている前提なのでアレでごめんなさい
    list($max) = sscanf(ini_get('memory_limit'), '%dM');
    $peak = memory_get_peak_usage(true) / 1024 / 1024;
    $used = ((int) $max !== 0)? round((int) $peak / (int) $max * 100, 2): '--';
    if ($used > 85) {
        $message = sprintf("[%s] Memory peak usage warning: %s %% used. (max: %sM, now: %sM)\n", date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']), $used, $max, $peak);
        error_log($message, 3, "/var/tmp/my-errors.log");
    }
});

もし、しきい値を超えた場合は

[2013-12-07 00:39:12] Memory peak usage warning: 87.5 % used. (max: 128M, now: 112.75M)

みたいにログに残すことができます。

横展開

他にも同様のパターンとして "Fatal error: Maximum execution time of XX seconds exceeded" も仕込んでおけますね。実際自分はメモリと実行時間の両方にしきい値を設けてしきい値を超えたらログに残すようにしています。

監視方法での注意

このとき、メールで通知とかしたくなる人もいらっしゃるかも知れませんが、運用しているサービスの特性によってはメールが飛び過ぎて簡単に死ぬのでエラーの監視は別のレイヤーで行うようにしたほうが幸せです。

さて、明日は@makiesさんです。お楽しみに!

2013-12-03

[] 簡単にPHPをmakeしてみた #vgadvent2013

初めての方こんにちは!!いつもお世話になっている方こんにちは!!

VOYAGE GROUP エンジニアブログ Advent Calendar 2013 の3日目担当の @brtriver です。

Zucks で広告配信システムのアレやコレをやってるエンジニアです。

冬と言えば鍋。そうPHPですね!

皆さんはどうやってPHPをmakeしてますか?

yumapt-getを使ってるという方も多いと思います。

今回は簡単なmake方法について紹介してみます。

適当な大きさで丸める

まずは、軽量樹脂粘土を用意します。PHPなので、青と白があればとりあえず大丈夫ですね。

f:id:brtRiver:20131203002122j:image

今回は目玉用に黒も用意してますが、なければマジックペンとかでも大丈夫です。

青は白と混ぜて良い感じの色にします。

f:id:brtRiver:20131203002153j:image

じっくりと引き延ばしながらこねるこがコツです。

耳としっぽを作る

できあがった青色粘土を適当に丸める。

f:id:brtRiver:20131203002656j:image

本体をmake

丸みを帯びた体のほうがかわいいので、丸みを意識して頭+鼻と足の部分を整形していきます。

make testすると尚良いんですが、大抵失敗します。

f:id:brtRiver:20131203002957j:image

足の部分はつまようじを使って四等分していきます。

f:id:brtRiver:20131203003053j:image

ぼてっとした短足がなんともかわいらしさを倍増させます。

耳とシッポをjoin

あらかじめ作っておいた耳とシッポを結合します。

結合テストを忘れずに。

f:id:brtRiver:20131203003343j:image

良い感じになってきましたね。

命を吹き込む

白色粘土と黒色を使って命を吹き込みましょう。

f:id:brtRiver:20131203003626j:image

きゃー。かわいいぃー。

PHPを背負う

PHPを掲げないと立派な一人前にならないので入れます。

f:id:brtRiver:20131203004538j:image

きゃー。いっぱいー。

f:id:brtRiver:20131203004658j:image

アレンジしてみる

着ぐるみバージョンなんてのもほら簡単。

f:id:brtRiver:20131203011132j:image

f:id:brtRiver:20131203011054j:image

ほら!簡単でしょ!

みんなも Let's make PHP :)

また、Zucks では 一緒に最高のプロダクトを開発したい仲間を募集中です。

気になった方は私と一緒に粘土をこねながらお酒飲みましょう

お気軽に @brtriver まで声をかけてくださいね。

明日のアドベントカレンダーはいつも元気な @chocopie116 です。お楽しみに!

2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |