Crash apache

Nouveau WRInaute
Bonjour,

je viens chercher un peu d'aide à un problème que je n'arrive pas identifier et donc pas à résoudre concernant un site web hébergé sur l'un de mes serveurs. Je vais tenter de donner autant d'informations que possible en essayant de ne pas vous perdre.

La machine que j'appelerai NET2 est un serveur dédié SuperPlan BestOF chez OVH (Intel Core i5-2400 - 4x3.1+ GHz - 64 bits - 16 Go DDR3 - 2x 2To - SATA2) qui tourne sous debian squeeze. Dessus sont installés apache 2.2.16 et PHP 5.3.3-7+squeeze14 with Suhosin-Patch (+ un postfix pour l'envoi des mails). Cette machine n'héberge qu'un seul site web dont le trafic n'est pas très important (600-700 visites/jours pour 3000-4000 pages). Initialement ce site était hébergé sur une autre machine (que j'appellerai NET1) avec la même configuration et plusieurs autres site. C'est à cause des crashs qu'il génère que nous l'avons déplacé.

Le site est développé sous ZendFramework (1.12), avec une base de données MySQL hébergée sur NET1 (mysql Ver 14.14 Distrib 5.1.63, for debian-linux-gnu (x86_64) using readline 6.1). Les fichiers (php, html, css, images, etc…) sont sur un NAS. Ce site utilise également une “base de données” distante qui retourne un fichier XML via un appel d'URL. Ces fichiers XML sont mis en cache sur le serveur pour réduire les temps de latence (la base distante étant assez lente et fréquemment inaccessible). Ce site est également multilingue (fr, en, de, nl, it).

2-3 fois par jour, le site devient presque inaccessible. Les pages mettent plus de 2 minutes à être affichées, sans qu'il n'y ait de timeout ou autre. Lorsque ce site était sur NET1 et que ce phénomène se produisait, dans un premier temps lui seul était impacté. Mais au bout de quelques minutes, tous les processus apache étaient occupé par des requêtes sur ce site, ce qui rendait les autres inaccessible. C'est pourquoi nous l'avons déplacé sur NET2.

Cela fait maintenant 1 semaine que le site est isolé. Malgré quelques correction d'erreur php (Warning ou Notice) le problème est toujours présent. Et je n'ai malheureusement aucune information dans les logs du serveur, que ce soit ceux d'apache ou du système. La seule chose que je sais, c'est que lorsque ce phénomène se produit, c'est le chargement des traductions qui met du temps à s'exécuté. Je l'ai identifié en utilisant utilisant microtime_debut_appel_fonction - microtime_fin_appel_fonction. Pourtant, ces traductions qui utilisent des fichiers PO (gettext) sont également mise en cache via Zend_Cache dans Zend_Translate.

Voici les graphiques munin du serveur montrant ce crash/latence apache :
727740apacheaccessesday.png

413036apacheprocessesday.png

730257apachevolumeday.png

489494memoryday.png

361561processesday.png


On peut constater les trous correspondants aux périodes où le site met plusieurs minutes à répondre. La RAM est loin d'être saturée, le processeur n'est quasiment pas utilisé (je n'ai pas mis le graphique mais la valeur mini de idle sur la même période est de 367%), le load average est de 0.1 (maxi 0.3). Le point inquiétant c'est qu'il y a des process zombies.

Je ne sais plus trop où chercher pour identifier le problème. Toutes les idées et les conseils seront les bienvenus. S'il vous faut plus d'infos, et je me doute bien que oui, demandez les. D'avance merci.
 
WRInaute passionné
Tu peux virer le suhosin pour gagner un peu en perf (commente /etc/php5/conf.d/suhosin.ini les lignes qui appellent le .so).
Tu peux virer le keepalive d'apache, le diminuer, diminuer le nombre de requête Apache.

Mauvaise méthode : Tu peux mettre un petit cron qui restart Apache toutes les 20 minutes, ce qui nettoiera un peu (c'est crade), mais ça repartira.

Bon, sans ta conf Apache, ça va être un peu galère.

Sinon, on voit que tu as des processus zombies sur ton dernier graph, je pense (ça correspond) que c'est dû à Apache (à vérifier lors d'un top/ps aux), mais mes théories :
tu as mis des valeurs d'Apache trop grosse (ce qui fait que quand tu as trop de monde (ou juste un pic de visite de bot, un buzz twitter ou autre), ton serveur tente de servir *TOUS* les gens, sans y arriver.
tu as mis des valeurs d'Apache trop grosses et petites à la fois (certains trucs vont faire qu'Apache dit "non" on répond pas, alors qu'il a ce qu'il faut derrière).

Tu pourrais voir l'état avec le server-status d'Apache (mod status).

En tout cas, joues sur tes workers,

Au hasard si tu es à 30 pour ça (ou 60, je ne me rappelle plus la valeur par défaut) :
Timeout 60 << mets ça à 10s (si une page mets plus de 10s à s'afficher, un message d'erreur est mieux que de laisser ramer un utilisateur pendant 1 minute).
KeepAliveTimeout 5 << si tes pages mettent 1s à s'afficher (tout compris), mets ça à 3 ou 4.

ce serait bien d'avoir ce :
Code:
    StartServers          5
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadLimit          64
    ThreadsPerChild      25
    MaxClients          250
    MaxRequestsPerChild   0

Voir ce que ça donne.
 
Nouveau WRInaute
Voici les extraits de ma config apache actuelle quasi inchangée par rapport à la version du paquet debian.

Code:
Timeout 300 # par défaut
KeepAlive On
MaxKeepAliveRequests 100

# les ajustements que j'avais mis en place
KeepAliveTimeout 2 #15 par défaut
<IfModule mpm_prefork_module> #oui je suis en prefork et pas en worker
    ServerLimit          128
    MaxClients           128
    MinSpareServers        5
    MaxSpareServers       10
    MaxRequestsPerChild 1000    
</IfModule>

Le keepalive on est sensé justement accélérer l'affichage des pages en faisant plusieurs requêtes sur une même connexion évitant ainsi les temps d'attente pour obtenir une connexion au serveur entre chaque requete. Je ne comprend pas pourquoi il faudrait le désactiver.

J'ai aussi trouvé quelques infos dans le syslog, liés à suhosin (heap overflow) qui signifient que certains de me scripts n'ont pas assez de mémoire. J'ai donc remonté le memory_limit pour cette appli. Depuis ca va un peu mieux, mais il y a toujours des crashs.

Pour le pic de visite de bot tu as raison, en fouillant les logs d'accès je trouve des concordances entre les heures de plantage et le passage du bingbot et du yandexbot.

Je continue de surveiller avec les modifs de config que tu conseille. En tout cas merci pour la réponse.

Si tu as besoin de plus d'infos, n'hésite pas.
 
WRInaute passionné
MaxRequestsPerChild << diminue le (j'aurais dit 200 MAX)
MaxClients << 250 sans problèmes
ServerLimit << 250 aussi
MaxSpareServers << 20 (peut-être 30, ça reste à tester)

Pour le KeepAlive, ça peut dépendre de ton site:
Si une page contient 2000 éléments (à télécharger sur le même serveur), là oui, c'est vital.
Après c'est principalement à tester, mais le keepalive fait qu'Apache laisse ouvert des processus pour que le client puisse les réutiliser. Du coup si le client (ou le bot) ferme mal sa connexion, ça laisse ouvert des processus pour rien.

Ton "Timeout 300" diminue le à 30s (voir moins).

J'ignore si tu as ce paquet (fourni sur dotdeb aussi) php5-apc, si "non", installe le, ça fera un bien énorme, surtout pour du zend.

Un peu bloqué en tout cas, mais n'hésites surtout pas à tester, je pense que ça peut faire du bien. Vu la RAM que tu as en rab, tu peux te faire plaisir niveau valeurs, mais avec un MaxClients à 250 ça devrait déjà aller mieux. (Check que tu n'as pas dans ton error.log d'Apache un "servers reach max client" (ou un truc du genre).

MaxRequestsPerChild << par contre ça diminue le, ou augmente proportionnelement ton MaxSpareServers.
 
Nouveau WRInaute
Le tandem apache/nginx je me suis déjà renseigné dessus et je le mettrai en place dès que j'aurai le temps de tout tester.

Il faut savoir qu'à la base je ne suis pas admin système, mais développeur. J'ai hérité de l'admin sys au départ de mon collègue qui gérait ça et qui lui non plus n'était pas admin sys. Et aussi ce site qui aujourd'hui me pose des problèmes tournait très bien précédemment sur un serveur beaucoup moins puissant (Intel(R) Core(TM)2 Duo CPU E7400 @ 2.80GHz - 2Go de RAM).

La config apache était la suivante :
Code:
Timeout 300
KeepAlive Off
ServerLimit 1024
<IfModule mpm_prefork_module>
    StartServers          10
    MinSpareServers       10
    MaxSpareServers      15
    MaxClients          100
    MaxRequestsPerChild   500
</IfModule>

En tout cas depuis les modifs de ce matin, il y a eu une petit point du nombre de process apache a 40 mais pas de plantage. Wait And See
 
Nouveau WRInaute
Me revoilà avec des infos.

Depuis les modification de la configuration d'apache, plus de plantage. En revanche, je me retrouve avec 200 process apache busy,
19 idle, et 37 free. C'est énorme et ca fait plus de 4 heures que ça dur. Alors je me suis dis, que j'allais regarder le trafic réseau sur la machine. Un petit netstat me donne plein de lignes du genre :
Code:
unix  3      [ ]         STREAM     CONNECTE      9673042  
unix  3      [ ]         STREAM     CONNECTE      9673041  
unix  3      [ ]         STREAM     CONNECTE      9673039  
unix  3      [ ]         STREAM     CONNECTE      9673038  
unix  3      [ ]         STREAM     CONNECTE      9673036  
unix  3      [ ]         STREAM     CONNECTE      9673035  
unix  3      [ ]         STREAM     CONNECTE      9673033  
unix  3      [ ]         STREAM     CONNECTE      9673032  
unix  3      [ ]         STREAM     CONNECTE      9673030  
unix  3      [ ]         STREAM     CONNECTE      9673029
je ne les ai pas compté mais ca ne m'étonnerais pas qu'il y en ai 200.

Pas très parlant comme info, donc je me dis que je vais aller voir le server-status d'apache. Voici un extrait :
Code:
20-1 22388 0/5/240 W 1.36 17714 0 0.0 0.00 3.88 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   21-1 22389 0/8/79 W 1.63 16772 0 0.0 0.02 28.78 82.225.16.37 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   22-1 22434 0/9/229 W 1.27 17351 0 0.0 0.03 3.34 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   23-1 22435 0/6/247 W 1.37 17322 0 0.0 0.02 32.42 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   24-1 31361 0/0/48 W 5.41 17750 0 0.0 0.00 1.29 157.55.35.80 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   25-1 22436 0/7/227 W 1.23 17894 0 0.0 0.06 5.15 157.55.34.179 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   26-1 31406 0/0/71 W 7.20 17743 0 0.0 0.00 0.14 157.55.34.179 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   27-1 23014 0/9/254 W 1.93 16539 0 0.0 0.05 4.90 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   28-1 25216 0/2/23 W 0.57 17260 0 0.0 0.00 0.06 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   29-1 23016 0/8/49 W 1.41 16715 0 0.0 0.07 0.46 157.55.33.20 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   30-1 23061 0/5/51 W 1.10 17015 0 0.0 0.05 0.33 65.55.24.243 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   31-1 23062 0/5/22 W 0.97 18403 0 0.0 0.03 0.25 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   32-1 31407 0/0/42 W 0.81 17730 0 0.0 0.00 0.38 65.55.24.243 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   33-1 23064 0/10/34 W 1.30 16662 0 0.0 0.12 6.39 93.24.109.109 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   34-1 7118 0/49/55 W 10.21 17918 0 0.0 0.13 0.13 157.55.35.80 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   35-1 31408 0/0/40 W 5.14 17721 0 0.0 0.00 0.09 157.55.35.93 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   36-1 16722 0/21/30 W 5.03 16780 0 0.0 7.99 7.99 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   37-1 23065 0/6/20 W 1.24 17351 0 0.0 0.01 37.18 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   38-1 31409 0/0/43 W 5.31 17714 0 0.0 0.00 0.10 157.55.34.179 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   39-1 23066 0/5/17 W 1.53 16869 0 0.0 0.01 0.02 66.249.76.208 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   40-1 23067 0/6/21 W 1.62 16835 0 0.0 0.02 0.02 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   41-1 - 0/0/1602 . 0.00 909 0 0.0 0.00 54.14 91.121.145.100 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   42-1 7170 0/54/60 W 10.77 16770 0 0.0 0.18 0.18 157.55.35.80 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   43-1 16824 0/31/44 W 5.26 16645 0 0.0 6.29 6.30 93.24.109.109 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   44-1 31410 0/0/58 W 10.46 17714 0 0.0 0.00 0.13 157.55.34.179 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   45-1 23069 0/6/15 W 1.20 17482 0 0.0 0.06 0.09 157.55.35.80 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   46-1 31455 0/0/16 W 1.28 17703 0 0.0 0.00 0.10 157.55.35.93 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   47-1 23071 0/4/15 W 1.33 16832 0 0.0 0.00 0.00 92.249.127.111 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   48-1 23072 0/4/69 W 0.98 18194 0 0.0 0.05 7.16 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   49-1 16828 0/25/60 W 5.93 17285 0 0.0 0.05 7.17 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   50-1 23117 0/7/42 W 1.53 16729 0 0.0 0.01 0.12 65.55.24.243 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   51-1 31456 0/0/34 W 4.11 17700 0 0.0 0.00 0.03 37.59.49.210 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   52-1 23118 0/4/48 W 1.06 16780 0 0.0 0.00 11.75 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   53-1 31457 0/0/21 W 0.64 17694 0 0.0 0.00 0.07 157.55.35.80 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   54-1 23164 0/6/46 W 1.26 17953 0 0.0 0.11 0.30 157.55.34.179 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   55-1 23165 0/7/18 W 1.59 16777 0 0.0 0.00 0.01 157.56.93.193 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   56-1 31458 0/0/61 W 0.78 17684 0 0.0 0.00 0.58 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   57-1 23167 0/6/19 W 1.12 18129 0 0.0 0.00 0.01 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   58-1 23214 0/5/15 W 0.98 18374 0 0.0 0.02 0.03 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   59-1 23658 0/6/43 W 1.17 16571 0 0.0 0.01 26.22 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
   60-1 23659 0/6/17 W 1.18 18129 0 0.0 0.06 0.06 157.56.229.189 www.domain.tld GET /url-de-mes-pages HTTP/1.1
Alors le W de la 4e colonne signifie Sending Reply. Donc en gros il est entrain de servir des pages au bingbot ! Sauf qu'avec un petit iftop aucune trace d'échange de données entre le serveur et les IP en question.

Ma conclusion, la connexion n'a pas été terminée correctement par le bot. Du coup Apache garde le process actif. Vous en pensez quoi ? Et si c'est bien ca, y a-t-il un moyen de résoudre ce problème pour qu'apache termine correctement les process ?
 
Nouveau WRInaute
Alors aujourd'hui le server-status d'apache me dis ceci :
Code:
GGGG_GGGWGGGGGGGGGGGGGWGGGGGGGGGGGGGGGGGG_GGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGGGGGGG_GGGGGGGGGGGGG_GGGGGGGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGGGWGGGGGGGGG_GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
GGGGGGGGGG___G_.G.WW............................................

   Scoreboard Key:
   "_" Waiting for Connection, "S" Starting up, "R" Reading Request,
   "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
   "C" Closing connection, "L" Logging, "G" Gracefully finishing,
   "I" Idle cleanup of worker, "." Open slot with no current process

Une idée du pourquoi les connexion ouverte par le bingbot ne se ferment pas correctement ?
 
WRInaute passionné
En diminuant les timeout, ça dégagerait un peu plus vite le bingbot.
Je trouve pas ça spécialement gênant sinon, les connexions "mal faites" ça arrive (bon là c'est un "gros" bot, ça devrait être plus propre).
Ca peut aussi venir d'une connectivité de "merde" entre ton serveur et le bing bot, pas gênant, vu ton load average (pas sûr que je lise bien), ça me semble très bien.
Perso sur mes gros serveurs, j'ai jusqu'à 20K de connexions ouvertes (du nginx ou du lighttpd), ça passe sans trop de soucis.
 
Nouveau WRInaute
Bonjour,

je reviens ici après plusieurs longs mois d'absence concernant ce sujet. J'ai enfin réussi à identifier clairement le problème et à le résoudre.

Il ne s'agissait en réalité pas d'un problème de configuration d'apache. Bien qu'une petite optimisation n'ait pas fait de mal. Je vous explique.

Dans un premier temps, j'avais tout simplement interdit l'indexation par le BingBot, car le problème survenait à chacun de ses passages. Depuis, plus de problème tout se passait bien. Mais niveau référencement, c'était loin d'être ce qu'il y avait de mieux. Donc aujourd'hui, je me décide à autoriser à nouveau son passage. Le voilà donc qui vient crawler le site. Ni une ni deux, le nombre de process apache passe de 10 à 220.

Un petit coup de apache-status me donne le même résultat que précédemment, plein de connexions en W. Je recommence donc mes recherches sur le sujet et tombe sur un article qui m'aura au moins permit de nommer le problème "Perpertual Bush Syndrome".

Le diagnostics proposé ne m'a pas permis de trouver le problème. Donc, aux grand maux les grands remèdes, j'installe xdebug pour profiler la page d'accueil. Je récupère le fichier de log, un petit tour dans webgrind et là le problème m'a sauté aux yeux. flock

Il s'avère que peu de temps avant que survienne le problème, j'avais modifié le site qui tourne sur ZendFramework. Initialement, ma gestion du cache était codée directement en PHP dans mon bootstrap. Mais voulant simplifier mon code et regrouper le maximum de chose dans mon application.ini, j'y avais déplacé la configuration du cache. Sauf que j'avais oublié une petite ligne :
Code:
resources.cachemanager.main.backend.options.file_locking = false
Donc à chaque appel, les fichiers étaient verrouillés empêchant l'accès aux requêtes suivantes, et générant une file d'attente de plus en plus longue.
Je peux donc à nouveau autoriser l'indexation par le BingBot, sans que celui-ci ralentisse la navigation sur mon site.

Le plus drôle dans l'histoire, c'est que le mécanisme sensé accélérer l'affichage des pages était en fait à l'origine des ralentissements :lol:
 
WRInaute accro
Comme quoi Bing bot est cool pour tester sa config avant d'avoir beaucoup de visiteurs :D

Si Bingbot met notre serveur sur les rotules à lui tout seul, c'est qu'il y aurait forcément eu un problème avec un pic de visiteurs éventuel tôt ou tard :)
 
Discussions similaires
Haut