Help us understand the problem. What is going on with this article?

気を付けよう getimagesize() の引数に

More than 1 year has passed since last update.

本記事は、前の記事
gethostbyaddr()って外部と通信するんだね
と同時進行していた話です。よければ一緒にご覧ください。

【 概要 】

PHPのあるシステムで、なぜかブラウザ表示が
重くなる現象が起きていました。

まず対象のページについて、テスト環境で調べました。
すると apache のログ( /var/log/httpd/ )が妙なのです。
ページに1回だけアクセスしたはずなのに、
ログ上は2回アクセスしているのです。

はぁっ? と思い、その2回目のログをよく見ると、
リモートIP(通信元)が、サーバIPと同じでした。
つまり、自サーバから自サーバに通信していたのです。

その後いろいろ調べたところ、
getimagesize() が原因だと突き止めました。
(画像の大きさを取得する関数です。)

【 原因 】

最初に言っておきますが、
getimagesize() に罪はありません。
コールの仕方に問題があったのです。

まず getimagesize() の引数 filename は、
主に2種類の書き方ができます。

[ローカルファイル形式]
/var/www/image.gif

[URL形式]
http: //xxxx.yyy/image.gif

ここで、画像が自サーバ内にある場合は、
どちらの書き方でもコール可能です。

ただし http: //xxxx.yyy/image.gif(URL)の書き方だと、
画像が自サーバ内にあるにもかかわらず、
わざわざ apache のコネクションを介して画像を取得するのです。

これが apache の不明なログの正体でした。
(問題のPHPソースでは、URL形式を引数にしていました。)
言い換えれば、apache のコネクションを無駄に張っていたのです。

もう少し詳しく説明しましょう。

PHPのページにアクセスする際、そのページ内で、
画像(自サーバ内)のサイズ取得のため getimagesize() をコールしていて、
その引数としてURLを指定していると、
本来1個のコネクションで済むはずが、
2個のコネクションを張ってしまうのです。

仮にそのページに、同時に100アクセスされた場合、
apache のコネクションは200になってしまいます。

・ページに対するコネクションが100
・画像に対する(予想外の)コネクションも100
・合わせて200

【 何が違う? 】

以上を読んで、
「HTML内に img タグがあれば、同じことが起こるじゃないか」
と思われたでしょうが、それとは違います。
その場合は、ページに対するコネクションの「後」に、
画像へのコネクションが発生するからです。

今回 私が見た現象は、ページに対するコネクションの「最中」に、
画像へのコネクションが追加発生するのです。

【 apache との関係 】

以上に述べた、予想外のコネクションが発生するとなると、
httpd.conf の MaxClients の意味が薄れてしまいます。

なぜなら MaxClients は、外部からの純粋なアクセス数を
予測/計算して決めますが、その1アクセスで
じつは内部的に2アクセス以上 発生するとなれば、
MaxClients が不足することになるのです。

結果、本来 捌ける(さばける)はずのアクセスを
捌けなくなってしまいます。アクセスの待ち行列が増大します。
これが、ブラウザ表示が重くなった理由です。

【 まとめ 】

結局、getimagesize() の引数を
/var/www/image.gif(ローカルファイル形式)に修正したところ、
apache がリクエストを捌けるようになり、ブラウザ表示が軽くなりました。

プログラマーは、apache 等のサーバやインフラのことなど
あまり意識しない(というか知らない)場合もあると思います。

本番環境の特殊な状態に晒されて、
初めて問題に気づくことが多いです。

結局 地道に、ノウハウを蓄積するしかないですねぇ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away