Benchmarking Apache

Je suis en train de comparer Apache / 2.2.3 (prefork) en utilisant ab et siege avec la command suivante:

 ab -kc 200 -t 120 http://www.mywebsite.com/test.php siege -c200 -t2M http://www.mywebsite.com/test.php 

test.php est un file très simple qui crée simplement une connection mysql puis se ferme

 <?php $link = mysql_connect("localhost", "username", "password"); mysql_select_db("dbname"); if(!$link) { die('Could not connect: ' . mysql_error()); } echo 'Connected successfully'; mysql_close($link); ?> 

Les résultats que je reçois ont beaucoup de requests échouées en eux. J'essaie de comprendre comment réduire le nombre de ces requests échouées car il s'agit d'un script assez simple, la charge du server est assez faible, je ne devrais pas avoir de problème sur une machine Quad-Core Xeon 3Ghz avec 8G de RAM.

Sortie du siège

 Transactions: 9438 hits Availability: 98.33 % Elapsed time: 119.39 secs Data transferred: 0.38 MB Response time: 1.31 secs Transaction rate: 79.05 trans/sec Throughput: 0.00 MB/sec Concurrency: 103.37 Successful transactions 9438 Failed transactions: 160 Longest transaction: 21.24 Shortest transaction 0.21 

Sortie de ab :

 Benchmarking www.mywebsite.com (be patient) Server Software: Apache/2.2.3 Server Hostname: www.mywebsite.com Server Port: 80 Document Path: /test.php Document Length: 22 bytes Concurrency Level: 200 Time taken for tests: 35.851520 seconds Complete requests: 50000 Failed requests: 618 (Connect: 0, Length: 618, Exceptions: 0) Write errors: 0 Keep-Alive requests: 49600 Total transferred: 12932098 bytes HTML transferred: 1149345 bytes Requests per second: 1394.64 [#/sec] (mean) Time per request: 143.406 [ms] (mean) Time per request: 0.717 [ms] (mean, across all concurrent requests) Transfer rate: 352.26 [Kbytes/sec] received 

Un point fort rapide de ma configuration d'Apache

 Timeout 300 KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 15 <IfModule prefork.c> StartServers 20 MinSpareServers 20 MaxSpareServers 50 ServerLimit 500 #default 200 MaxClients 500 MaxRequestsPerChild 4000 </IfModule> 

J'ai exécuté le même test avec le même script sur un autre server plus faible, et il a eu des requêtes échouées et des tests finis plus rapidement. Je me request donc ce qui ne va pas sur celui-ci.

Configuration MySQL mise à jour:

Variables

 mysql> show variables LIKE '%connect%'; +--------------------------+-------------------+ | Variable_name | Value | +--------------------------+-------------------+ | character_set_connection | latin1 | | collation_connection | latin1_swedish_ci | | connect_timeout | 10 | | init_connect | | | max_connect_errors | 10 | | max_connections | 100 | | max_user_connections | 0 | +--------------------------+-------------------+ 

Statut mondial

 mysql> SHOW GLOBAL STATUS LIKE '%connect%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | Aborted_connects | 343 | | Connections | 1463797 | | Max_used_connections | 101 | | Ssl_client_connects | 0 | | Ssl_connect_renegotiates | 0 | | Ssl_finished_connects | 0 | | Threads_connected | 3 | +--------------------------+---------+ 

Votre limite de concurrency est définitivement du côté de MySQL, même si je ne suis pas sûr que cela soit nécessairement une mauvaise chose pour les performances du monde réel. Vous avez MySQL pour accepter 100 connections simultanées, de sorte que vous ne pouvez avoir que 100 instances Apache qui parlent à la fois. Étant donné que votre script de test est si simple, il va passer la majeure partie du time qu'il est connecté activement ou au less se connecter à MySQL. Ajoutez un peu plus pour les process Apache qui se trouvent dans d'autres états, et vous obtenez votre concurrent dans le siège de 100. Je ne sais pas exactement pourquoi ab reçoit un niveau de concurrency plus élevé de 200, mais peut-être que cela count les choses différemment.

Si vous souhaitez get plus haut vos numéros de reference, il suffit de définir vos limites de connection plus élevées pour MySQL. La limite de connection MySQL devrait probablement être au less égale au nombre de process Apache pour quelque chose qui passe la grande majorité du time à parler à la DB.

Malheureusement avec ab, vous êtes en train de comparer les performances de votre client. Vous avez besoin d'un meilleur outil de performance tel que httperf qui ne tue pas l'hôte client. Si vous souhaitez exécuter de vrais tests, vous devriez utiliser plus d'un hôte pour cela ou, en certains cas, être un bon outil. Il suffit de vérifier ce que l'ab fait en fait, il pourrait lutter avec les limites de files ouverts. Aussi bon de vérifier la configuration du server.

http://httpd.apache.org/docs/2.0/misc/descriptors.html

Peut-être qu'il y a quelque chose d'étrange sur le côté de MySQL. Une chose qui peut se produire facilement lors de ce type de test rapide "créer un connection db – fermer" est que mysql_max_connection_errors se remplit, par défaut, il n'en rest que 10.

Et une autre chose: avez-vous déjà vérifié que les limites maximales de connection sont égales entre votre server plus faible (mais fonctionnant) et ce plus rapide (et ne fonctionne pas)? Peut-être que la valeur par défaut de 100 connections MySQL simultanées se remplit.