職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

PHP処理中にHTTPサーバ再起動

PHPに限らず、Webアプリケーションを動かしているとどこかのタイミングでHTTPサーバを再起動する必要に迫られることがあります。
そのタイミングで誰もアクセスしていないという保証があるのなら話は簡単なのですが、その保証があることは、以前は極めて稀でした。近年では再起動すべきタイミングにおいては稼働中のサーバを一旦ロードバランサーから切り離すことで新規の HTTP Request を受け付けないようにし、実行中の処理が全て捌けてから再起動するといった運用も行われます。とは言え、再起動したときにどのような現象が起きるのかを知っておくことは無駄ではありません。何故なら、1秒を争うような状況に追い込まれてしまったときはロードバランサーの操作をせずに再起動することも考えられるからです。他にも知っておくと幸せになれる場面はあるでしょう。

このあたりの挙動に関して、自分の知識がn年前の状態のまま更新されていないことに気付いたので、ちょっと実験することにしました。
HTTPサーバ経由で実行された PHP のプログラムが、HTTPサーバ再起動(やそれに近い操作)によってどのように取り扱われるのか。試してみましょう。

PHP の処理

次のようなものを用意しました。それぞれの処理が実行されている途中で、再起動(など)を実施します。

  • wait_with_sleeping.php : sleep関数で処理に時間がかかる場合
  • wait_consuming_cpu_resource.php : PHPの処理でCPU資源を食い潰している場合
  • wait_on_background.php : PHPのコードの中からバックグラウンドプロセスを立ち上げた場合

コードは GIST として公開しています。
PHPで時間のかかる処理を再現する。signalとか受け取ったときの挙動の確認。 · GitHub

検証環境

  • AWS EC2 t2.nano (512MB RAM) 2台(Apache検証用 と NGINX検証用)
  • Amazon Linux 2016.09
  • Apache の場合
    • sudo yum install php70PHP 7.0.11 と Apache 2.4.23 をインストール
    • sudo service httpd startApache 起動
  • NGINX の場合
    • sudo yum install php70PHP 7.0.11 と Apache 2.4.23 をインストール
    • sudo yum install php70-fpmPHP-FPM をインストール
    • sudo yum install nginx で NGINX 1.10.1 をインストール
    • sudo service php-fpm startPHP-FPM 起動
    • sudo service nginx start で NGINX 起動

検証結果

再起動方法 sleep CPU資源を食う処理 バックグラウンド
sudo service httpd restart 死ぬ 死ぬ 死ぬ
sudo service httpd reload 死ぬ 死ぬ 死ぬ
sudo service httpd graceful sleepが中断される きちんと待ってくれる 死なない
sudo service nginx restart 死ぬ 死ぬ 死なない
sudo service nginx reload きちんと待ってくれる きちんと待ってくれる 死なない

ちなみに、PHP 5.6 でも同様の結果が得られました。
標準で用意されているサービス取り扱いのコマンドの範囲では、NGINX の方がより直感的な運用ができるかもしれません。signalを受け取ったら sleep がinterruptされる挙動を期待するようなプログラムを書いているのであれば Apache の方が良いでしょう。もっとも、この特性以外の要因の方が、HTTPサーバを選択する上で重要である場面は多いでしょう。

そう言えば以前、Apacheで運用しているサービスで sudo service httpd reload を流したところバックグラウンドの処理が死んでしまってビビったことがあるのを思い出しました。今だから言える。

追記@2016.11.10

再起動方法 sleep CPU資源を食う処理 バックグラウンド
sudo service php-fpm reload 死ぬ 死ぬ 死なない
sudo service php-fpm restart 死ぬ 死ぬ 死なない

例えば php.ini とかを変更する際は php-fpm を再起動することになるでしょう。その結果はご覧の通りです。やっぱり Apache の方がええんかな…?

PDF Cheatsheet を作った

PDF Cheatsheet - www.tmotooka.com

自宅でも仕事でも、PDFは非常に頻繁に取り扱う。PDFファイルを画面に表示させたり印刷させたり、Word等のドキュメント作成アプリケーションから出力させることもある。だが、これだけではない。そのPDFがどのように作られているのか内容を確認しなければならないことがある。
PDFの中身を読むにあたっては、PDFのファイルフォーマットをある程度抑えておく必要がある。基本的な事項は、このブログでも散々紹介している「PDF構造解説」という名著にて学ぶことができる。

PDF構造解説

PDF構造解説

しかし残念ながら、これは全てではない。この本に書かれていないことも山ほどある。そのような内容を知りたくなったら、Adobe社の文書 にあたるのが良いだろう。
技術的キーワードであれば、上記のAdobe社のサイトからダウンロードできる PDFの仕様のPDF のファイル内を検索することで解説を読むことができる(ただし英語)。ところが、PDFのコンテントストリームの中に書かれている描画コマンドの数々は大抵、アルファベット1〜2文字で構成されていて検索するのは非常に難しい。
ならば、描画コマンドだけ、どのような意味のものなのかを簡潔にまとめたチートシートカンニングペーパー)があれば生活が楽になると思い、冒頭に掲げたチートシートを作った。

PDFを取り扱っている皆さんに、ぜひ活用して頂きたい。

パイプを通るPDF(実験中) 〜 #シェル芸 の新たなる境地へ


先日開催された「第25回 #シェル芸 勉強会」のLT(大阪編)でしゃべった内容を、ここで紹介します。

#大げさなタイトルですが、世の中は広いものです。先駆者はどこかにきっと居られることでしょう。

目標

標準入力や標準出力を受け渡しするための仕組み パイプ はテキストデータだけでなく、バイナリデータも流すことができます。
一般的なシェル芸においては当然ながら大半の用例が、テキストをパイプで流すというものですが、バイナリデータを流すときのノウハウも蓄えていきたいと思います。

空っぽのPDFを作る

これはImageMagickconvert コマンドで実現可能です。

$ convert xc:none -page A4 a.pdf

ImageMagickconvert は、画像ファイルを変換するコマンドです。基本的には、入力画像を与えて、変換処理の内容を与えて、出力先を指定して実行します。上記の例で言えば xc:none が入力で、-page A4 が変換処理の内容(出力形態)、a.pdf が出力先に相当します。
この xc:none は、空っぽの画像を表すようです。テキストデータに例えると /dev/null とも言えるかもしれません。

xc:none については、ここで知りました。
unix.stackexchange.com

空っぽのPDFを標準出力に吐く

convertの結果を標準出力に吐く方法を調べようとしましたが、ImageMagickは通常、出力先のファイル名の拡張子を見て出力フォーマットを決定しています。標準出力にそのまま吐こうとしてもPDFであることを強制できないのではないか?という疑問が湧きます。
この点についてググると、次のようなものがヒットしました。
forcing output file format on stdout - ImageMagick
出力先に jpeg:- と指定するとJPEGで標準出力に出すことができるそうです。ならば pdf:- によってPDFが標準出力に吐かれるはずだ!と推測して試したところ、無事に吐くことができました。

$ convert xc:none -page A4 pdf:- > a.pdf

ここではリダイレクトを使ってファイルを出力していますが、これでファイルが吐かれていれば標準出力からデータが出ていることの確認になります。PDFのファイルフォーマットに慣れ親しんだ方であれば、次のような検証も有効でしょう。

$ convert xc:none -page A4 pdf:- | head

標準入力から受け取ったPDFでゴニョゴニョ

次は、標準入力から受け取ったPDFの加工です。
よく使われるのは gsコマンドこと GhostScript ツールです。

入力元のオプションとして -_ を与えると標準入力から受け取ってくれるという情報がありますが、まだ検証中です。
ここから先は実験中なので、また成果がまとまり次第報告したいと思います。正直なところ、現時点では上手く行ってません。
お楽しみに!

感想(追記@2016/10/30 15:53頃 JST

実験に使った環境

書籍紹介コーナー

この本を読めば、$ cat hoge.pdf とかしちゃっても戸惑うことは減るはずです。

PDF構造解説

PDF構造解説

こちらの記事でも紹介してます => さぁ、PDF手書きの世界へ。 - 職業プログラマの休日出勤

第25回 #シェル芸 勉強会に参加してきました

タイトルの通りです。今回も大阪サテライトに参加しました。

本家
usptomo.doorkeeper.jp

大阪サテライト
atnd.org

Togetterまとめ
togetter.com
あ、一番最初に掲載されている。

問題 【問題のみ】第25回もう4年もやってんのかシェル芸勉強会 – 上田ブログ
問題+解答例 【問題と解答】第25回もう4年もやってんのかシェル芸勉強会 – 上田ブログ

この日の自分の tweet T.Motooka(@t_motooka)/2016年10月29日 - Twilog
シェル芸とは無関係の発言も含んでいるとは言え、171tweetsもしており、不健全な感じがします。(前回は149tweets)

続きを読む

関西モバイルアプリ研究会 #関モバ 第19回 に参加

関西モバイルアプリ研究会(通称 関モバ)の第19回に参加してきました。

kanmoba.connpass.com

会場

今回の会場は、このブログなどでもお世話になっている 株式会社はてな さんの京都オフィス!
本当によくお世話になってます。
はてな記法 にも、結構長いことお世話になっています。このブログ「職業プログラマの休日出勤」も はてな記法 で書いています。

自分で発表した内容

某所において先日、サーバ復旧したと思ったらすぐに再び落ちたという事象を目の当たりにしたことから、この話をしようと思いました。
そのサーバはモバイルアプリのバックエンドではないですし、「再び落ちた」原因もアクセス集中ではなかったのですが、やはりモバイルアプリの世界では多いのはこのスライドの中で紹介しているパターンだろうなーと思っています。

終盤の まとめ のページに掲載している言葉「サーバ管理者に優しい言葉をかけ続けると綺麗なAPI設計が返ってくる」は完全にネタですが、そこまで外していないような気もします。
あと、「札束」が強力な武器であることは誰もが理解しているはずなのですが、企業の会議室の中においては無かったことにされるケースもよく耳にしますので、敢えて言及しました。

対策の例として Exponential Backoff を紹介しましたが、このような考え方が素晴らしいモバイルアプリ開発につながっていったら、非常に嬉しいです。

さいごに

はてなの皆さん、運営の皆さん、参加者の皆さんに感謝!