J'ai actuellement un serveur Apache2 fonctionnant avec mpm-prefork
et mod_php
sur un OpenVZ VPS avec 512 Mo de RAM réel / 1024 Mo de mémoire vive (pas de swap). Après avoir exécuté quelques tests, j'ai constaté que la taille maximale du processus qu'Apache obtient est de 23 MaxClients
Mo, j'ai donc défini 25 (23 Mo x 25 = 575 Mo, ok pour moi). J'ai décidé d'exécuter des tests de charge sur mon serveur et les résultats m'ont laissé perplexe.
J'utilise ab
sur ma machine de bureau pour demander la page principale d'un blog wordpress.
Lorsque je cours ab
avec 24 connexions simultanées, tout semble aller bien. Bien sûr, le CPU augmente, la RAM libre diminue et le résultat est un temps de réponse d'environ 2-3 secondes par demande.
Mais si je lance ab
avec 25 connexions simultanées (ma limite de serveur), Apache se bloque juste après quelques secondes. Il commence à traiter les demandes, puis il cesse de répondre, le processeur revient à 100% inactif et ab
expire. Le journal Apache indique qu'il a atteint MaxClients
.
Lorsque cela se produit, Apache reste verrouillé avec 25 processus en cours d'exécution (ils sont tous en "W" si je vérifie l'état du serveur) et seulement après le TimeOut
réglage, les processus commencent à mourir et le serveur recommence à répondre (dans mon cas, il est défini à 45).
Ma question: est-ce le comportement attendu? Pourquoi Apache meurt juste quand il atteint MaxClients
? Si cela fonctionne avec 24 connexions, ne devrait-il pas fonctionner avec 25 connexions, en prenant peut-être juste plus de temps pour répondre à chaque demande et mettre en file d'attente le reste?
Cela me semble un peu étrange que tout enfant en cours d'exécution ab
puisse à lui seul tuer un serveur Web simplement en configurant les connexions simultanées aux serveurs MaxClients
.
la source
Ce qui se passe ici, c'est que vous avez 25 threads capables d'accepter les connexions et que vous envoyez 26 requêtes simultanées. Cette dernière demande se trouve dans la file d'attente de socket en fonction de la taille de votre backlog.
Le deuxième problème est que tout ce que vous exécutez, qui prend 2-3 secondes, prend suffisamment de temps pour répondre que les 25 connexions simultanées le ralentissent. sleep (1) peut fonctionner, mais, quelque chose où vous effectuez un verrouillage de fichier ou un verrouillage de table à partir de mysql, chaque demande parallèle peut attendre le avant d'être terminée jusqu'à ce qu'elle atteigne le délai d'expiration de 45 secondes.
23mb semble petit pour un processus apache avec mod_php et tous les modules chargés, donc, je soupçonne que vous pourriez voir ces processus apache prendre un peu plus de RAM pendant que votre application est en cours d'exécution. Vous ne pouvez pas vraiment faire de mathématiques avec MaxClients et la mémoire comme ça ... ce sera un peu proche, mais, vous ne savez jamais.
Il y a une machine, des processus 56M et 49M.
une autre machine:
une autre machine:
Ainsi, l'utilisation de la mémoire dépend beaucoup de la tâche, des modules qui sont chargés, etc. Sur les deux derniers, je pense que nous avons désactivé pdo & pdo_mysql car cette application ne les utilise pas.
La vraie question est, qu'est-ce que tu fais qui prend 3 secondes? Dans le monde d'aujourd'hui, c'est une éternité et considérée comme une application «bloquante». Apache ne mourra pas normalement, mais laissera ces threads dans la file d'attente du backlog jusqu'à ce qu'il puisse les traiter ou que les requêtes en attente expirent. Je crois que votre application entraîne probablement un dépassement de délai pour apache. Essayez-le sur une page contenant juste phpinfo (); et voyez si les résultats sont les mêmes.
la source