web-dev-qa-db-fra.com

Réglage des performances Un serveur Apache haute charge

Je cherche à comprendre certains problèmes de performance du serveur, je vois avec un serveur Web fortement chargé. L'environnement est le suivant:

  • Debian Lenny (tous les packages stables + corrigés vers des mises à jour de sécurité)
  • Apache 2.2.9
  • Php 5.2.6
  • Amazon EC2 Grands instance

Le comportement que nous voyons est que le Web se sent généralement réactif, mais avec un léger délai pour commencer à gérer une demande - parfois une fraction d'une seconde, parfois 2-3 secondes dans nos heures d'utilisation maximale. La charge réelle sur le serveur est rapportée comme très élevée - souvent 10.xx ou 20.xx comme indiqué par top. En outre, courir d'autres choses sur le serveur pendant ces périodes (même vi) est très lente, de sorte que la charge est définitivement là-haut. Curieusement, suffisamment Apache reste très sensible, autre que ce délai initial.

Nous avons Apache configuré comme suit, à l'aide de Préfourge:

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

Et conserve comme:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

En regardant la page d'état du serveur, même à ces moments de chargement lourd, nous frappons rarement au capuchon du client, servant généralement entre 80 et 100 demandes et beaucoup de ceux de l'état de garde. Cela me dit d'exclure la demande de demande initiale comme "en attente d'un gestionnaire", mais je me trompe peut-être.

La surveillance de CloudWatch de Amazon me dit que même lorsque notre système d'exploitation signale une charge de> 15, notre utilisation de la CPU d'instance est comprise entre 75 et 80%.

Exemple de sortie de top:

top - 15:47:06 up 31 days,  1:38,  8 users,  load average: 11.46, 7.10, 6.56
Tasks: 221 total,  28 running, 193 sleeping,   0 stopped,   0 zombie
Cpu(s): 66.9%us, 22.1%sy,  0.0%ni,  2.6%id,  3.1%wa,  0.0%hi,  0.7%si,  4.5%st
Mem:   7871900k total,  7850624k used,    21276k free,    68728k buffers
Swap:        0k total,        0k used,        0k free,  3750664k cached

La majorité des processus ressemblent:

24720 www-data  15   0  202m  26m 4412 S    9  0.3   0:02.97 Apache2                                                                       
24530 www-data  15   0  212m  35m 4544 S    7  0.5   0:03.05 Apache2                                                                       
24846 www-data  15   0  209m  33m 4420 S    7  0.4   0:01.03 Apache2                                                                       
24083 www-data  15   0  211m  35m 4484 S    7  0.5   0:07.14 Apache2                                                                       
24615 www-data  15   0  212m  35m 4404 S    7  0.5   0:02.89 Apache2            

Exemple de sortie de vmstat en même temps que ce qui précède:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 8  0      0 215084  68908 3774864    0    0   154   228    5    7 32 12 42  9
 6 21      0 198948  68936 3775740    0    0   676  2363 4022 1047 56 16  9 15
23  0      0 169460  68936 3776356    0    0   432  1372 3762  835 76 21  0  0
23  1      0 140412  68936 3776648    0    0   280     0 3157  827 70 25  0  0
20  1      0 115892  68936 3776792    0    0   188     8 2802  532 68 24  0  0
 6  1      0 133368  68936 3777780    0    0   752    71 3501  878 67 29  0  1
 0  1      0 146656  68944 3778064    0    0   308  2052 3312  850 38 17 19 24
 2  0      0 202104  68952 3778140    0    0    28    90 2617  700 44 13 33  5
 9  0      0 188960  68956 3778200    0    0     8     0 2226  475 59 17  6  2
 3  0      0 166364  68956 3778252    0    0     0    21 2288  386 65 19  1  0

Et enfin, la sortie de Apache server-status:

Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers

C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................

De mon expérience limitée, je dessine les conclusions/questions suivantes:

  • Nous permettons peut-être beaucoup trop de KeepAlive demandes

  • Je vois du temps passé à attendre IO dans le VMSTAT bien que pas systématiquement et pas beaucoup (je pense?) Donc je ne suis donc pas sûr que ce soit une grosse préoccupation ou non, je suis moins expérimenté avec vmstat

  • En outre, dans VMSTAT, je vois dans certaines itérations Un certain nombre de processus attendus à servir, ce qui correspond à ce que je attribue le délai de charge de la page initiale sur notre serveur Web à, éventuellement à tort.

  • Nous servons un mélange de contenu statique (75% ou plus) et de contenu de script, et le contenu du script est souvent assez intensif du processeur, il est donc important de trouver le bon équilibre entre les deux est important; long terme Nous voulons déplacer la statique ailleurs pour optimiser les deux serveurs, mais notre logiciel n'est pas prêt pour cela aujourd'hui

Je suis heureux de fournir des informations supplémentaires si quelqu'un a des idées, l'autre note est qu'il s'agit d'une installation de production à haute disponibilité, donc je me méfie de faire de la modification après la modification, et c'est pourquoi je n'ai pas joué avec des choses comme la KeepAlive valeur moi-même.

12
futureal

Je vais commencer par admettre que je ne connais pas beaucoup de choses sur les nuages ​​- mais sur la base de mon expérience ailleurs, je dirais que cette configuration WebServer reflète un volume de trafic assez faible. Que la runqueuse est si importante suggère qu'il n'ya tout simplement pas assez de processeur disponible pour y faire face. Qu'est-ce que d'autre est dans la course?

Nous pouvons laisser beaucoup trop de demandes de conserve

Non - KeePlive améliore toujours les performances, les navigateurs modernes sont très intelligents sur la connaissance de la pipeline et pour exécuter des demandes en parallèle, bien qu'un délai d'attente de 5 secondes soit encore assez élevé et que vous avez un [~ # ~ ] Lot [~ # ~ ~] des serveurs en attente - sauf si vous avez d'énormes problèmes de latence, je vous recommande de démarrer cela jusqu'à 2-3. Cela devrait raccourcir un peu la runqueuse.

Si vous n'avez pas déjà installé Mod_deflate installé sur le serveur Web - alors je vous recommanderais de le faire - et ajoutez l'OB_GZHANDLER () à votre PHP scripts. Vous pouvez le faire en tant que PREPEND:

if(!ob_start("ob_gzhandler")) ob_start();

(Oui, la copression utilise plus de CPU - mais vous devez enregistrer dans l'ensemble des CPU en obtenant des serveurs hors des serveurs de runqueur plus rapidement/manipulation inférieur TCP paquets - et en bonus, votre site est également plus rapide).

Je vous recommanderais de définir une limite supérieure sur maxrequestSperchild - disons quelque chose comme 500. Cela permet simplement de renverser des processus au cas où vous avez une fuite de mémoire quelque part. Vos processus httpd cherchent à être énormes - assurez-vous que vous avez supprimé les modules Apache dont vous n'avez pas besoin et assurez-vous de servir de contenu statique avec de bonnes informations de mise en cache.

Si vous voyez toujours des problèmes, le problème est probablement dans le PHP (si vous passez à l'aide de FastCGI, cela devrait être évident sans une pénalité de performance majeure).

Mise à jour

Si le contenu statique ne varie pas beaucoup d'une pages, cela pourrait également être expérimenté:

if (count($_COOKIE)) {
    header('Connection: close');
}

sur le PHP scripts aussi.

7
symcbean

Vous devriez envisager d'installer un proxy inverse asynchrone, car un certain nombre de processus de l'état W sont assez élevés. Vos processus Apache semblent passer beaucoup de temps à envoyer du contenu aux clients lents sur le réseau étant bloqués à ce sujet. Nginx ou LightTPD en tant que fronçage sur votre serveur Apache peut réduire considérablement un certain nombre de processus dans l'état W. Et oui, vous devez limiter un certain nombre de demandes de conservation. Il vaut probablement la peine d'essayer de faire demi-tour.

BTW, 107 processus Apache sont trop élevés pour 22 rps, j'ai pu servir 100-120 RPS en utilisant uniquement 5 processus Apache. Probablement, la prochaine étape consiste à profiler votre application.

4
Alex

Première suggestion: Désactiver les conserves. Je n'en avais jamais besoin que lorsque je puisse identifier une situation spécifique que la performance a augmenté, mais dans les demandes générales/sètes diminuées avec Conservealive activée.

Deuxième suggestion: mettre un maxrequestSperchild. J'échoque Symbo Symcbean ici, cela aidera à traiter le roulement dans le cas d'une fuite de mémoire. 500 est un bon point de départ.

Troisième suggestion: augmenter les maxclients. Un calcul de Ballpark pour cela est (Mémoire physique - Mémoire utilisée par le processus non httpd)/Taille de chaque processus HTTPD. Selon la compilation httpd, ce nombre maxe à 255. J'utilise 250 pour mes serveurs publics pour gérer Google/Yahoo/MS ramper les systèmes.

Au-delà de la suggestion: Augmentez MaxSpaRestervers: quelque chose comme 4-5x Minssparvers.

Baring Ces suggestions échouent, je regarderais l'équilibrage de la charge avec le proxy inverse ou le memcache pour DB.

0
Paul S