web-dev-qa-db-ja.com

PHP + Apacheの長い待機時間

専用のWebサーバーのトラブルシューティングで、レンガの壁に少し遭遇しました。最近、私のWebサイトは1秒あたりのリクエスト数が急増し、クラッシュしました。

元のボックスには、8 GBのRAM、8 Core Xeon E3-1230、1 TB 7,200 RPMディスク(RAIDなし)、100 Mbit専用ネットワークが搭載されていました。

急増後、RAM= 24GBに増やして、より多くの同時ユーザーをサポートしました。

Apacheは、3,000人の同時ユーザーがいてもうまく処理できるようですが、HTMLと静的コンテンツを非常にすばやく返します(キャッシュなし)。

Apache/HTMLとApache/PHPの違いをさらにテストするために、abを実行しました。

両方とも test.htmlおよびtest.phpは静的コンテンツがまったく同じです。PHPはincludesを呼び出さず、MySQLに接続しません。

HTMLテスト

ab -n 500 -c 50 http://www.~~.com/test.html

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      252  375 190.3    276    1399
Processing:   254  354 121.5    282     657
Waiting:      253  353 121.4    280     653
Total:        510  730 231.7    573    1675

PHPテスト

ab -n 500 -c 50 http://www.~~~.com/test.php

Connect:      248  275  51.1    267    1316
Processing:   256 4167 6210.2   2262   41489
Waiting:      253 4166 6210.2   2262   41489
Total:        509 4442 6212.4   2523   41754

Pingdomは、PHPスクリプトにアクセスするときに長い待機時間も報告します。 enter image description here

WebPageTest.orgでも同様の結果が得られますが、最初にバイトするのは[〜#〜] f [〜#〜]の方が優れています。

           Load Time   **First Byte**   Start Render    DOM Elements    Time    Requests    Bytes In    Time    Requests    Bytes In
First View  2.061s  **0.839s**  0.000s  55  2.061s  20  428 KB  2.061s  20  430 KB

これがtopの結果です。 enter image description here

I/Oテスト

負荷が高い場合、wa%は数ミリ秒間95%に増加する可能性があります。

ロード中にiostatを実行しました:

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
           8.37    0.00    5.18    0.56    0.00   85.88

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb               0.00    45.50  3.00 48.00   136.00   748.00    17.33     3.05   59.76   2.53  12.90
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb3              0.00    45.50  3.00 48.00   136.00   748.00    17.33     3.05   59.76   2.53  12.90

avg-cpu:  %user   %Nice %system %iowait  %steal   %idle
           4.00    0.00    3.56    0.69    0.00   91.75

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sda1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb               6.00   118.50  9.50 21.00   996.00  1116.00    69.25     0.29    9.44   1.66   5.05
sdb1              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb2              0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
sdb3              6.00   118.50  9.50 21.00   996.00  1116.00    69.25     0.29    9.44   1.66   5.05

私にはそれは悪くないように見えますが、何かが足りないかもしれません。

FCGIを使用しています

<IfModule mod_fcgid.c>
FcgidMaxRequestLen 1547483648
FcgidMaxRequestInMem 52485760
FcgidIdleScanInterval 15000
FcgidBusyTimeout 15000
FcgidProcessLifeTime 7200
FcgidConnectTimeout 1800
FcgidIOTimeout 1800
PHP_Fix_Pathinfo_Enable 1
FcgidMaxRequestsPerProcess 1000
</IfModule>

そして、ここに私のApache Confがあります(私は2.4.xを使用しています)

Timeout 60
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag None
StartServers 10
<IfModule prefork.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
<IfModule itk.c>
MinSpareServers 5
MaxSpareServers 15
</IfModule>
ServerLimit 2200
MaxRequestWorkers 2000
MaxConnectionsPerChild 15000
KeepAlive On
KeepAliveTimeout 1
MaxKeepAliveRequests 2000

Apacheのエラーログとアクセスログを調べました。奇妙な報告はありません。

ここで頭を掻いています。

ファイアウォールをオフにしてみました。

最大接続数を増やしてみました。

私はmySQLを最適化し、多くの遅いクエリ(> 0.5s)を削除しました。

他に何ができますか、問題を特定するのに役立つ何かがありますか?どんな助けでも大歓迎です。

PS:

サーバーに頻繁にアクセスしているときでも、PHPMyAdminとcPanelは非常に応答が速いことに注意してください。 WebサイトのPHPを除いて、他の何も遅れていないようです。

4
Moe

あなたの問題は、単にアクセス時間のあるハードディスクだと思います。 Apacheはhtmlページをメモリにキャッシュできますが、phpスクリプトはキャッシュされません。毎回再度実行する必要があります。したがって、phpインタープリターが呼び出され、hddからスクリプトを読み取ります。これには時間がかかります。サーバーで最も遅いのはHDDです。私のPCでは、SSDから始まるアプリケーションとHDDから始まるアプリケーションに極端な違いがあります(SSDは最大で10倍高速です!)。 HDDが機能する場合、phpスクリプトを実行するためのレイテンシが大幅に増加する可能性があります。

考えられる解決策:SSDを取得し(スクリプトなどの頻繁にアクセスされるデータ用の小さなもの)、サーバーでのスクリプト呼び出し(およびHDDアクセス)を最小限に抑えます。ファイルシステムが最適化されていることを確認してください(通常は自動的に実行されます)。 php-scriptが同じコンテンツを頻繁に作成する場合は、それらをhtmlファイルにキャッシュしてみてください。

この答えはあなたにも役立つかもしれません: https://stackoverflow.com/questions/4181865/Apache-php-caching

1
K. Biermann

テストしているHTMLファイルは単なるプレーンファイルです。Apacheが行う必要があるのは、いくつかのシステムコール(オープン、読み取り)を実行し、そのコンテンツを提供することだけです。

PHP OTOHは実際にはかなり「重い」オプションです。それは完全なインタプリタ(バイトコードコンパイラ?)です。また、同時テスト(-c)を使用しているので、リクエストがどのように多重化されているかを誰が知っているでしょうか。これはApacheの問題である必要はなく、PHPの問題です。

私がすること:

  1. Apache MPM(マルチプロセスのマルチスレッド)に切り替えます。

  2. 順次テスト(複数の同時要求なし)を実行し、比較します。

  3. Apacheプロセスでvalgrindなどを実行し、ほとんどのCPU時間が費やされている場所を確認します(ApacheまたはPHP)。

  4. 同じテストを実行しますが、nginxを介してこのページを提供します。 nginxは非同期モデルに基づいており、非常に高速であるため、同様の結果が得られる場合は、PHPが原因です。

  5. 最後に、Zend Optimizer(30日間の試用は無料)または次のようなsmthをインストールできます: https://github.com/zendtech/ZendOptimizerPlus

実際、静的ファイルの提供と動的に生成されたWebページの比較は、リンゴとオレンジの比較のようなものです。少なくとも静的ファイルを提供する場合と比較すると、この点で典型的なソリューション(Python mod-Apache、Django、PHPなど)のいずれも非常に高速になることはありません。 Node.jsはおそらく例外です。これは、非同期モデル内の「低レベル」プログラミングWebページに直接起因するためです。

追伸あなたは引用していませんphp.iniコンテンツ。投稿したり、微調整したりします。

2
LetMeSOThat4U