Je cherche à comprendre certains problèmes de performance du serveur, je vois avec un serveur Web fortement chargé. L'environnement est le suivant:
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.
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.
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.
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.