私たちのチームは、WordPressプラグインを開発し、独立したいくつかのサーバーでホストされたインスタンスを提供しています。WordPressインストールはGitによって管理され、すべてのサーバーはsource&WordPressセットアップが展開され、ドメインとデータベース内の実際のデータのみが異なります。インストールごとに、MySqlは同じホストで実行されます。WordPressは排他的に実行されます各サーバー上。
ただし、このセットアップをWindows Server 2008 RC2に展開した後、他のサーバーと比較してパフォーマンスが大幅に異なることに気付きました。ページ生成時間は平均よりも長くなります。 PHPで生成されたページの場合、400ミリ秒から4000-5000ミリ秒。 Apacheのみが提供する静的リソースの場合、速度はLinuxとほぼ同じです。
そこで、問題を絞り込むためにいくつかの手順を実行しました。
プロファイリングをいくつか行った後、Windowsマシンでは正規表現の評価がひどく遅いことがすぐにわかりました。 10.000正規表現(preg_match
)の評価には、Linuxで約90ミリ秒、Windowsで3000ミリ秒かかります。
プロファイリング、システムテスト、および構成の詳細を以下に示します。 このスクリプトを最適化したくありません(方法は知っています)。Linuxとほぼ同じ速度でスクリプトを実行するようにしたい(opcacheに関して同じ設定を与えた/ ...)。スクリプトのメモリフットプリントも最適化する必要はありません。
更新:しばらくすると、システムがメモリ不足になり、メモリ不足の例外とランダム割り当てがトリガーされるようです。詳細については、以下を参照してください。 Apache/PHPを再起動すると、今のところ問題が修正されました。
_get_browser
へのトレースは次のとおりです。
File (called from)
require wp-blog-header.php (index.php:17)
wp (wp-blog-header.php:14)
WP->main (functions.php:808)
php::do_action_ref_array (class-wp.php:616)
php::call_user_func_array (wp-includes/plugin:507)
wp_slimstat::slimtrack (php::internal (507))
wp_slimstat::_get_browser (wp-slimstat.php:385)
更新2:何らかの理由で、サーバー上のApacheモジュールとしてPHPを有効にしたことを思い出せません(パフォーマンスが低下するのと同じです)。 Opcacheを追加すると、これは約400ms/reqになりますが、Apache/PHP/Windowsは同じままです。
1)プロファイリング結果
プロファイリングは、すべてのマシンでXDebugを使用して行われました。通常、数回の実行のみを収集しました-ほとんどの時間(50%+)が費やされた場所を明らかにするのに十分でした:WordPress plugin [get_browser][1]
のメソッドwp-slimstats
:
protected static function _get_browser(){
// Load cache
@include_once(plugin_dir_path( __FILE__ ).'databases/browscap.php');
// browscap.php contains $slimstat_patterns and $slimstat_browsers
$browser = array('browser' => 'Default Browser', 'version' => '1', 'platform' => 'unknown', 'css_version' => 1, 'type' => 1);
if (empty($slimstat_patterns) || !is_array($slimstat_patterns)) return $browser;
$user_agent = isset($_SERVER['HTTP_USER_AGENT'])?$_SERVER['HTTP_USER_AGENT']:'';
$search = array();
foreach ($slimstat_patterns as $key => $pattern){
if (preg_match($pattern . 'i', $user_agent)){
$search = $value = $search + $slimstat_browsers[$key];
while (array_key_exists(3, $value) && $value[3]) {
$value = $slimstat_browsers[$value[3]];
$search += $value;
}
break;
}
}
// Lots of other lines to relevant to the profiling results
}
この関数は、PHPのget_browser
と同様に、ブラウザーの機能とOSを検出します。スクリプトの実行時間のほとんどは、このforeach
ループに費やされ、それらのpreg_match
(ページリクエストごとに約8000-10000)をすべて評価します。これには、Linuxでは約90ms、Windowsでは3000msかかります。テストしたすべてのセットアップで結果は同じでした(写真は2回の実行のデータを示しています)。
確かに、2つの巨大な配列の読み込みには時間がかかります。正規表現も評価します。しかし、LinuxとWindowsではほぼ同じ時間がかかると予想されます。これは、Linux VMでのプロファイリング結果です(1ページのリクエストのみ)。違いはかなり明白です:
別のタイムキラーは、実際にはオブジェクトキャッシュでしたWordPress使用:
function get( $key, $group = 'default', $force = false, &$found = null ) {
if ( empty( $group ) )
$group = 'default';
if ( $this->multisite && ! isset( $this->global_groups[ $group ] ) )
$key = $this->blog_prefix . $key;
if ( $this->_exists( $key, $group ) ) {
$found = true;
$this->cache_hits += 1;
if ( is_object($this->cache[$group][$key]) )
return clone $this->cache[$group][$key];
else
return $this->cache[$group][$key];
}
$found = false;
$this->cache_misses += 1;
return false;
}
この関数自体の中で時間がかかります(3スクリプト実行):
Linuxの場合:
最後の本当の大きな時間のキラーは翻訳でした。メモリからロードされた各翻訳には、WordPressで0.2msから4msまでの時間がかかります。
Linuxの場合:
2)テスト済みシステム
仮想化またはApacheがこれに影響することを確認するために、いくつかのセットアップでこれをテストしました。 Antivirはすべてのセットアップで無効にされました。
上記のプロファイリング結果は、異なるシステムで同じでした(最大10%の導出)。 Windowsは常にLinuxよりも遅い重要な要素でした。
WordPress&Slimstatsの新規インストールを使用すると、ほぼ同じ結果が得られました。コードの書き換えは、ここではオプションではありません。
更新:一方、この完全なスタックが非常に高速に実行される他の2つのWindowsシステム(Windows 2008 R2、VM&Physの両方))が見つかりました。
更新2:実行中PHP Life-Servers上のApacheモジュールはfastcgiメソッドよりもわずかに高速だったため、最大2秒まで、50%減少しました。
メモリ不足
しばらくすると、Live-Serverはまったく動作しなくなり、これらのメモリ不足例外が発生します。
PHP Fatal error: Out of memory (allocated 4456448) (tried to allocate 136 bytes)
PHP Fatal error: Out of memory (allocated 8650752) (tried to allocate 45 bytes)
PHP Fatal error: Out of memory (allocated 6815744) (tried to allocate 24 bytes)
これは、ランダムなスクリプトの場所で発生します。 Zend Memory Managerは、これ以上のメモリを割り当てることはできませんが、スクリプトはそうすることを許可されます。インシデントが発生した時点で、サーバーには約50%の空きRAM(2GB +)がありました。したがって、サーバーは実際にRAMを使い果たしません。
この問題がパフォーマンスの問題に関連しているかどうかはわかりません。しかし、両方の問題はメモリに関連しているように見えるため、ここに含まれています。特に、適切なパフォーマンスを提供するWindowsテストの設定を再現しようとします。
)Apache&PHP設定
...おそらく一般的な落とし穴はありません。 Output-Bufferingは有効(デフォルト)、multibyeオーバーライドは無効、...興味のあるオプションがあれば、喜んで提供します。
httpd.exe -V
の出力
Server version: Apache/2.4.7 (Win32)
Apache Lounge VC10 Server built: Nov 26 2013 15:46:56
Server's Module Magic Number: 20120211:27
Server loaded: APR 1.5.0, APR-UTIL 1.5.3
Compiled using: APR 1.5.0, APR-UTIL 1.5.3
Architecture: 32-bit
Server MPM: WinNT
threaded: yes (fixed thread count)
forked: no
Server compiled with....
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses disabled)
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=256
-D HTTPD_ROOT="/Apache"
-D SUEXEC_BIN="/Apache/bin/suexec"
-D DEFAULT_PIDLOG="logs/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/Apache_runtime_status"
-D DEFAULT_ERRORLOG="logs/error.log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
mpm_winnt_module
設定:
<IfModule mpm_winnt_module>
ThreadsPerChild 150
ThreadStackSize 8388608
MaxConnectionsPerChild 0
</IfModule>
Php.iniの抜粋:
realpath_cache_size = 12M
pcre.recursion_limit = 100000
4)現在の疑わしい理由
古い仮定:
3つの例はすべて、大きな配列と文字列操作に大きく依存しています。ある種は一般的な工場のようです。 Linuxでの実装は問題なく動作するため、これはWindowsのメモリの問題であると思われます。ピンポイントの場所でデータベースとのやり取りがない場合、データベースまたはサーバー<-> PHP統合が問題であるとは思われません。どういうわけかPHPのメモリのやり取りが遅いようです。 Windowsのメモリに干渉してアクセスを劇的に遅くしている可能性がありますか?
古い仮定2:
同じスタックが他のWindowsマシンでも問題なく動作するため、問題はWindows構成のどこかにあると想定しています。
新しい仮定3:
実際、私は仮定から外れています。なぜPHP Apacheモジュールよりfastcgiのようにはるかに遅い>
これを検証する方法、またはここで実際の問題を見つける方法についてのアイデアはありますか?この問題を解決するためのヘルプまたは指示は大歓迎です。
Windowsには、あらゆる状況でコンピューターの使用を制限、防止、保護、制御などする多くのサービス/ポリシーがあります。
優れたマイクロソフト認定スペシャリストは、数分以内にあなたの質問を解決することができます。彼らは、どの設定/サービス/ポリシーを確認し、設定を無効化/有効化/変更するかを正確に伝える経験があるため、PHPスクリプトはより速く実行されます。
私の記憶では、RAM、ハードドライブアクセス、環境変数、制限、セキュリティ(ファイアウォールなど)を扱うすべてのものをチェックすることをお勧めします。 PHPスクリプトの実行に影響を与える可能性のあるすべてのもの。いくつかのリモートプロシージャコールポリシーから始まり、動作中のスタックメモリで終わります。
ロジックは、php.exeが何らかの外部の.dllファイルを呼び出して何らかの操作を実行するというものです。OSによって行われる方法にチェックがあり、そのような.dllを介した要求の送信と応答の受信の両方が遅くなります。 .dllがハードドライブを使用して何かにアクセスする場合-ハードドライブアクセスポリシーがシーンに入ります。また、すべてがメモリ内に配置される方法-RAMまたはRAMのハードドライブキャッシュ。アプリケーションポリシー。スレッドポリシー。アプリケーションで使用可能な最大パーセンテージの制限。
Windowsベースのホストが悪いと言っているのではなく、一般的な管理者にとって適切にセットアップするのがはるかに難しいというだけです。マイクロソフトのスペシャリストがいる場合、彼はあなたのサーバーをLinuxベースのサーバーと同じ速度に調整することができます。
pHP5.4を使用する場合、APCを有効にします
aPCがオンのときに速度の向上に気付かない場合は、何かが誤って設定されています
_[APC] extension=php_apc.dll apc.enabled=1 apc.shm_segments=1 apc.shm_size=128M apc.num_files_hint=7000 apc.user_entries_hint=4096 apc.ttl=7200 apc.user_ttl=7200
_
オンのときにZend Opcodeを有効にするPHP 5.5
_[Zend] zend_extension=ext/php_zend.dll zend_optimizerplus.enable=1 zend_optimizerplus.use_cwd=1 zend_optimizerplus.validate_timestamp=0 zend_optimizerplus.revalidate_freq=2
_
zend_optimizerplus.revalidate_path=0 zend_optimizerplus.dups_fix=0 zend_optimizerplus.log_verbosity_level=1 zend_optimizerplus.memory_consumption=128 zend_optimizerplus.interned_strings_buffer=16 zend_optimizerplus.max_accelerated_files=2000 zend_optimizerplus.max_wasted_percentage=25 zend_optimizerplus.consistency_checks=0 zend_optimizerplus.force_restart_timeout=60 zend_optimizerplus.blacklist_filename= zend_optimizerplus.fast_shutdown=0 zend_optimizerplus.optimization_level=0xfffffbbf zend_optimizerplus.enable_slow_optimizations=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=10000 opcache.revalidate_freq=60 opcache.fast_shutdown=1 opcache.enable_cli=1
disable Wordpress拡張機能を段階的に使用して、メモリ使用量のモンスターを見つける
define('WP_MEMORY_LIMIT', '128M');
を設定します(十分な画像変換プラグインを使用しない場合)ini_set('memory_limit', -1);
memory_get_usage
_を使用し、システム全体に呼び出しを広げて、メモリリークが発生するコード位置を見つけます。zend.enable_gc=1
_を試してください。スクリプトは遅くなりますが、使用するメモリは少なくなりますGithubでそのプラグインを見てみました:
https://github.com/wp-plugins/wp-slimstat
また、含まれている問題のあるファイルは、ある程度縮小されたファイルであり、実際にはデータ(コードではない)であり、それぞれ約400KBの5つのバリエーションがあります
400KBのmaxmind.datファイルもありますが、両方を使用するかどうかはわかりません。
プラグインの古いバージョンであるバージョン3.2.3を使用しており、問題を解決できる可能性のある新しいバージョンがあります。
作成者またはgit履歴を順番に保持していない人がいるので、違いを比較するのは難しいので、ファイルを手動で比較する必要がありました。 _get_browserに関連する変更のほとんどは、キャッシュを追加しているようです。
そのファイルの読み込みは解析が遅い可能性がありますが、PHP IOキャッシュが機能していることを条件に両方のプラットフォームで両方のファイルを同じレートで読み込むと期待します。
[〜#〜] edit [〜#〜]問題を解決できないかもしれない、もう少し詳しく見てみましょう。これらのファイルは基本的に大きな正規表現のルックアップテーブルです。 LinuxシステムにAPCキャッシュがありましたが、これにはありませんか? APCキャッシュは、おそらくPHPファイルデータをキャッシュします(ただし、コンパイル済みの正規表現パターンではありません))
PHPではなくUNIXソケットを介して(TCPソケットではない)にNGINXおよびFCGIを使用します。
http://wiki.nginx.org/PHPFcgiExample
アクセラレータがなくても、すぐに速度が向上します。さらに、上記のセットアップでは、メモリ使用量がはるかに少なくなります。
この種の問題をトラブルシューティングするには、次のことを行う必要があります。
その場合は、Windowsの更新プログラムや問題の原因となっているソフトウェアをアンインストールし、サーバーを完全にシャットダウンしてから、更新プログラムまたはソフトウェアを再インストールします(セットアップ中に安定した状態を確保するため)。
この問題のトラブルシューティングに役立つツールには、Sysinternals Suiteが含まれます。 http://technet.Microsoft.com/en-us/sysinternals/bb842062.aspx
もっと簡単に言うと、オープンソースのVBSスクリプトを使用して、システム上の更新とアプリケーションの比較可能なリストを作成します。