PHP facteur 30 différence de performances de Linux à Windows
Notre équipe de travail est le développement de plugins WordPress et fournit des cas hébergé sur un couple de serveurs indépendants. Notre installation de WordPress est géré par Git, tous les serveurs ont la même source & programme d'installation de WordPress déployé, seuls les domaines & les données dans la base de données varie. Pour chaque installation, MySql est en cours d'exécution sur le même hôte. WordPress est exécuté exclusivement sur chaque serveur.
Cependant, après avoir déployé cette installation sur un Windows Server 2008 RC2, nous avons remarqué une chute drastique de différence de performance par rapport à nos autres serveurs: génération de la page le temps passe de avg. 400ms à 4000-5000 ms pour les pages générées avec PHP. Pour les ressources statiques livré par Apache seulement, la vitesse est environ le même que sur linux.
Nous avons donc pris des mesures pour réduire le problème:
- Assurez-vous il n'y a pas de antivir logiciel en cours d'exécution ou autre domaine windows trucs interférer
- Collecter les données de profilage pour identifier les timekillers au cours de l'exécution du script
- De tester les différents serveur & les configurations des matériels
- Double-vérifier à la fois d'Apache et de PHP de configuration pour d'évidentes erreurs de configuration
Après un certain profilage nous avons rapidement remarqué que l'évaluation des expressions régulières est horriblement lent sur nos machines windows. L'évaluation de 10.000 expressions Régulières (preg_match
) prend environ 90ms sur Linux et 3000ms sur Windows.
De profilage, des tests de système et la configuration des détails sont fournis ci-dessous. Nous ne voulons pas d'optimiser ce script (dont nous ne savons comment le faire). Nous voulons obtenir le script à exécuter environ la même vitesse sur windows que sur Linux (étant donné que la même configuration concernant opcache/...). Pas besoin d'optimiser l'empreinte mémoire du script de trop.
Mise à jour: Après un certain temps, les systèmes de semble manquer de mémoire, le déclenchement de la mémoire des exceptions et aléatoire des allocations. Voir ci dessous pour plus de détails. Le redémarrage d'Apache/PHP résolu le problème pour l'instant.
Trace de _get_browser
est:
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)
Mise à jour 2: Certains une raison que je ne me souviens pas, nous sommes retournés à l'activation de PHP en tant que Module Apache sur nos serveurs (le même qui livrent mauvaise performance). Mais aujourd'hui, ils courent très rapide (~1s/demande). L'ajout de Opcache apporte cela à l' ~400ms/req. Apache/PHP/Windows est resté le même.
1) Le Profilage Des Résultats
De profilage a été fait avec XDebug sur toutes les machines. Habituellement, nous ne sont collectées que quelques pistes à ceux qui ont suffit à révéler l'endroit où la plupart du temps (50%+) a été consacré à la méthode [get_browser][1]
du plugin WordPress 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
}
Cette fonction similaire à PHP get_browser
détecte les capacités du navigateur et de l'OS. La plupart de l'exécution du script de temps est passé dans cette foreach
boucle, l'évaluation de tous ceux preg_match
(~environ 8000 - 10000 per demande de page). Cela prend environ 90ms sur Linux et 3000ms sur Windows. Les résultats étaient les mêmes sur toutes les configurations testées (tableau montre les données de deux exécutions):
Sûr, le chargement de deux tableaux de grande prend un certain temps. L'évaluation des expressions régulières aussi. Mais nous nous attendons à ce que la prendre à peu près en même temps sur Linux et Windows. C'est le profilage de résultat sur une machine virtuelle linux (une demande de page uniquement). La différence est assez évident:
Un autre tueur de temps a fait l'Objet de la mémoire Cache de WordPress utilise:
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;
}
De temps est passé dans cette fonction elle-même (3 exécutions de scripts):
Sur linux:
Le dernier vrai grand tueur de temps ont été traduits. Chaque traduction, chargé de la mémoire, prend quelque chose de 0,2 ms à 4ms dans WordPress:
Sur linux:
2) les systèmes Testés
Afin de s'assurer de la virtualisation ou Apache influent sur cela, nous l'avons testé sur plusieurs configurations. Antivir est désactivé sur toutes les configurations:
- Linux Debian, Apache 2 & PHP, jusqu'à ce jour les versions stables. C'est la même chose pour les développeurs d'exécution dans leurs machines virtuelles comme pour la mise en scène/serveurs en direct. Agissant comme un système de référence de la performance désirée. Soit dans nos bureaux ou à certaines d'hébergement fournit (espace partagé). Les Systèmes Windows avait entre 4 go et 8 go de RAM, à tous les temps de l'utilisation de la mémoire a été sous le seuil des 50%. Virtualizations ne jamais exécuter Windows & Apache en même temps.
- De vie des Serveurs, la course à T-Systems (gestion de serveurs virtualisés), sur VMWare Player
- Win 2008 R2. Apache 2.2.25 + PHP 5.4.26 NTS,VC9 comme module fastcgi
- Win 2008 R2. Apache 2.2.25 + PHP 5.5.1 NTS,VC11 comme module fastcgi
- Win 2008 R2. Apache 2.2.25 + PHP 5.5.1 NTS,VC11 en tant que module apache
- Win 2008 R2, Apache 2.2.25 + PHP 5.5.11 TS,VC11 en tant que module apache (c'est le plus rapide que j'ai mentionné dans la mise à jour 2)
- Sur une machine locale, de l'Hôte: OpenSuse, la Virtualisation: VMWare player, de même que @T-Systems. Pour éviter à leurs infrastructures, nous influence:
- Win 2008 R2. Apache 2.2.25 + PHP 5.4.26 NTS,VC9 comme module fastcgi
- Win 2008 R2. IIS7 + PHP 5.4.26 NTS,VC9 comme module fastcgi (avec et sans wincache)
- Gagner 2012. IIS * + PHP 5.5.10 NTS,VC11 comme module fastcgi (avec et sans wincache)
- Sur une machine locale sans la virtualisation
- Win 2008 R2. Apache 2.2.25 + PHP 5.4.26 NTS,VC9 comme module fastcgi
De profilage des résultats comme mentionné ci-dessus étaient les mêmes sur les différents systèmes (~10% de la dérivation). Windows a toujours été un facteur important plus lent que Linux.
À l'aide d'une nouvelle installation de WordPress & Slimstats entraîné env. les mêmes résultats. Réécrire le code n'est pas une option ici.
Mise à jour: en Attendant, nous avons trouvé deux autres Systèmes Windows (Windows 2008 R2, VM & Phys) où cette pile fonctionne très rapide. Même configuration que.
Mise à jour 2: l'Exécution de PHP en tant que module apache sur la durée de Vie des Serveurs a été légèrement plus rapide que la fastcgi méthode: jusqu'à ~2sec, 50% de moins.
À cours de Mémoire
Après un certain temps, notre Vivre-Server cesse de travailler à tous, le déclenchement de ces de mémoire exceptions:
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)
Ce qui se passe au hasard emplacement des scripts. Évidemment, le Gestionnaire de Mémoire Zend n'est pas en mesure d'allouer plus de mémoire, bien que les scripts soient autorisés à le faire. À l'époque, si l'incident, le serveur a eu environ 50% de libérer de la mémoire vive (2 GO+). Si le serveur n'a pas effectivement de la mémoire vive. Le redémarrage d'Apache/PHP résolu ce problème pour l'instant.
Ne sais pas si ce problème est lié à la performance de questions ici. Pourtant, comme les deux questions semblent être liés à la mémoire, son inclus ici. En particulier, nous allons essayer de reproduire les paramètres de Windows-Tests qui ont fourni des performances décentes.
3) Apache & Configuration de PHP
... n'ont probablement pas tous les pièges les plus courants. De sortie de la mémoire Tampon est activée (par défaut), multibye priorité désactivée, ... Si tout option(s) sont d'intérêt, nous serons heureux de fournir.
Sortie de 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
configuration:
<IfModule mpm_winnt_module>
ThreadsPerChild 150
ThreadStackSize 8388608
MaxConnectionsPerChild 0
</IfModule>
Extrait de php.ini:
realpath_cache_size = 12M
pcre.recursion_limit = 100000
4) Courant soupçonné raison
Hypothèse ancienne:
Tous les trois exemples s'appuient largement sur de grands tableaux et les opérations de la chaîne. Qu'un type qui semble être la commune d'usine. Comme les travaux de mise en œuvre ok new'ish sur Linux, nous soupçonnons que cela soit un problème de mémoire sur Windows. Il n'existe pas d'interaction de base de données au détour des lieux, nous ne soupçonne pas le Serveur ou base de données <-> PHP intégration pour être le problème. En quelque sorte de mémoire PHP interaction semble juste être lent. Peut-être il ya quelqu'un d'interférer avec la mémoire sous Windows, rendant l'accès considérablement plus lent?
Vieille hypothèse 2:
Que la même pile fonctionne très bien sur d'autres machines sous Windows, nous supposons que le problème doit être quelque part dans la configuration de Windows.
Nouvelle hypothèse 3:
En fait, je suis d'hypothèses. Pourquoi irait PHP que beaucoup plus lent que fastcgi puis en tant que module apache>
Des idées sur la façon de vérifier cela, ou trouver le vrai problème ici? Toute aide ou d'orientation pour la résolution de ce problème est très bienvenu.
- Êtes-vous en cours d'exécution à la fois sur le même matériel?
- apache & mysql? oui. Étant donné le contexte actuel de la mémoire / CPU de la consommation et de l'emplacement de temps passé, cela ne devrait pas poser un problème.
- Non, je veux dire windows et linux
- non, différentes machines. Même pour les différents Tests Windows.
- Je veux dire: Sont-ils comparables?
- ils ont tous le même partitionnement du disque dur (et les applications sont sur le même emplacement), la quantité de ram et environ la même Vitesse du PROCESSEUR. Des différences mineures oui, mais rien de radical. Linux, VMs sont probablement les plus limitée de ceux (encore plus performants).
- (en disant: le windows serveurs de tests, tous étaient équipés de façon meilleurs que n'importe quel serveur linux, nous avons utilisé).
- Qu'est-ce que le Windows Apache taille de la pile? Est-il le même?
- Elle a été définie par défaut, il a augmenté de 8 MO. pas de changements dans la performance. À cours de pile doit au moins résultat dans les processus d'être tué. Processus de finition toujours bien. Ajout de la sortie de
httpd -V
et lampm_winnt_module
de configuration dans la question. - Sont Apache, PHP, et le fastcgi tous les modules 64 bits? (Et je suppose que vous voulez dire Windows Server 2008 R2, pas RC2?)
- Tous les Logiciels en versions 32 bits. Et oui, bien sûr R2 🙂
- Que pourrait être un facteur, je voudrais essayer les versions 64 bits si disponible.
- Nous avons vécu la même que celle décrite dans ce thread: stackoverflow.com/questions/21448661/... . Il n'y avait pas de différence de performances (au moins pas assez pour résoudre ce problème ici).
- Je ne sais pas si c'est une option pour vous, mais si vous voulez réparer rapidement, aurait PHP+IIS être vaut la peine d'essayer? Je crois que PHP les performances de l'intérieur IIS a été considérablement améliorée récemment, en raison de travaux conjoints entre Zend et Microsoft. Je n'ai aucune idée si cela peut aider dans ce cas, vous l'esprit.
- IIS est une parfaitement bien de remplacement. Nous avons cependant eu la même mauvaise performance sur IIS (voir 2) les Systèmes Testés).
- Avez-vous jamais résoudre ce problème ? Nous avons aussi remarqué que PHP et WordPress sont très lents sur windows.
- malheureusement pas. nous avons déménagé à une machine physique avec un excédent de ressources et tout a fonctionné okish. Il propose toujours de manière plus mauvaise performance et de voir toutes ces ressources vont à la poubelle avec une telle mauvaise performance, assurez-vous blesse (24 cœurs, 32 go de ram), mais de génération de la page est d'environ maintenant correctement au moins. Heureusement, nous avons enfin peut passer à linux dans les prochains mois 🙂
- Curieusement, le commentateur dans le sljit.sourceforge.net/regex_perf.html a trouvé la plupart des regex analyseurs plus rapide dans MSWindows que Linux. (alhtough ils ne triche et exécutez le MSWindows tests sur du matériel plus puissant)
Vous devez vous connecter pour publier un commentaire.
Windows a beaucoup de services et les politiques qui restreignent, prévenir, protéger, contrôler et etc l'utilisation de l'ordinateur dans chaque situation.
Une bonne certifié Microsoft spécialiste sera en mesure de résoudre votre problème en quelques minutes, parce qu'ils ont l'expérience pour dire exactement quels paramètres/services/politiques pour vérifier et activer/désactiver/modifier les paramètres, de sorte que les scripts PHP sont exécutés plus rapidement.
De ma mémoire, je ne peux que vous suggérer de vérifier tout ce qui traite de RAM, Disque Dur d'accès, les variables d'Environnement, des Limites et de la Sécurité (comme les Pare-feu). Tout ce qui peut influer sur l'exécution de script php, en commençant avec une certaine Distance l'Procedue Appel politiques et se terminant avec le fonctionnement de la pile mémoire.
La logique est que est php.exe les appels externes .dll fichier pour exécuter une opération, il peut y avoir des contrôles sur le chemin fait par l'OS, qui va ralentir à la fois de l'envoi de la demande par le biais de tels .dll, et la réception de la réponse à partir d'elle. Si l' .dll utilise le disque dur pour accéder à quelque chose d'accès au disque dur politiques entrer dans la scène. Aussi, la manière dont le tout est situé dans la mémoire RAM ou le disque dur de la mémoire cache de RAM. L'Application des politiques. Threads politiques. Limites sur max pourcentage disponibles pour les applications.
Je ne dis pas que Windows hôtes sont mauvais, juste qu'ils sont beaucoup plus difficiles à correctement le programme d'installation pour une administration générale. Si vous avez Microsoft spécialiste sur les mains, il peut ajuster votre serveur pour être aussi rapide que serveur Linux.
activer APC, lors de l'utilisation de PHP5.4
si vous ne remarquez pas un gain de vitesse, lors de l'APC est sur, quelque chose est mal configuré
[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
permettre Zend Opcode quand sur 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
désactiver WordPress extensions de pas-sage, de trouver l'utilisation de la mémoire monstre
define('WP_MEMORY_LIMIT', '128M');
, sauf si vous utiliser l'image conversion plug-ins qui devrait suffireini_set('memory_limit', -1);
memory_get_usage
et la propagation des appels partout dans le système pour trouver le code de position, d'où les fuites de mémoirezend.enable_gc=1
un essai, scripts sera plus lent, mais utilisent moins de mémoire@
. Mais sans toucher le code: quel est votrerealpath_cache_size
etpcre.recursion_limit
?realpath_cache_size = 12M
etpcre.recursion_limit = 100000
_get_browser
? Aussi, ce qui me rend vraiment étonnant est que cela se produit sur IIS et Apache: peut-être "RLimitMEM"?_get_browser
. Arrive à la fois sur IIS & Apache.J'ai pris un coup d'oeil à ce plugin sur Github:
https://github.com/wp-plugins/wp-slimstat
Et la délinquance fichier à inclure est un fichier
qui a été minimisé à un certain degré, et vraiment
est des données (pas de code), il y a 5 variations de chacune des
ce qui est sur 400KB
Il est également que maxmind.fichier dat qui est 400KB,
bien que je ne sais pas si il utilise à la fois.
Vous utilisez une ancienne version du plugin, version
3.2.3 et il est beaucoup plus récente, qui peut résoudre
votre problème.
De comparer les différences est dur parce que l'auteur
ou celui qui n'a pas gardé l'historique de git dans l'ordre,
j'ai donc dû manuellement diff sur le fichier. La plupart des changements
liées à _get_browser semblent être l'ajout d'un cache.
Il est possible de charger ce fichier est lent à analyser, mais
Je m'attends à PHP à charger les deux fichiers similaires
les taux dans les deux plates-formes accordée que IO est la mise en cache
de travail.
MODIFIER à la Recherche d'un peu plus près qui pourraient ne pas résoudre votre
problème. Ces fichiers sont essentiellement de grandes Expression Régulière
les tables de recherche. Votre système Linux ont un cache APC
sur il et celui-ci ne l'est pas? Le cache APC serait probablement
garder le fichier PHP de données mises en cache (bien que pas compilé
modèles regex)
Utiliser NGINX et FCGI pour PHP via UNIX socket (pas de socket TCP).
http://wiki.nginx.org/PHPFcgiExample
Vous remarquerez immédiatement les améliorations de la vitesse même sans accélérateurs. En outre, la configuration ci-dessus aurait beaucoup plus faible utilisation de la mémoire de l'empreinte.
Pour résoudre un problème de ce genre, vous aurez à:
et/ou la date d'identifier les dates de la question.
Si c'est le cas, vous aurez envie de désinstaller la mise à jour de Windows et/ou le logiciel qui provoque le problème, la fermeture de votre serveur, puis réinstallez la mise à jour ou un logiciel (pour assurer un état stable au cours de l'installation).
Des outils qui peuvent vous aider à résoudre ce problème sont les sysinternals suite:
http://technet.microsoft.com/en-us/sysinternals/bb842062.aspx
Ou, plus simplement, open source scripts VBS pour produire des listes comparables de mises à jour et des applications sur un système.