Optimisation Apache/PHP/MySQL

Avant de poser une question, voyez si on n'y a pas déjà répondu pour vous !

Modérateur : Mods GNU/Linux

Avatar de l’utilisateur
Malekal_morte
Site Admin
Site Admin
Messages : 86148
Inscription : 10 sept. 2005 13:57
Contact :

Optimisation Apache/PHP/MySQL

Message par Malekal_morte » 07 août 2014 15:23

Un petit tutorial pour vous aider à optimiser Apache/PHP/MySQL. Vous trouverez les grandes libres et conseils, libre à vous de googler un peu pour parfaire.

Note concernant les distributions, la configuration Apache de Debian est relativement bien faite, par contre sur CentOS, c'est une catastrophe. Cette page parlera surtout donc de CentOS. Notez que les processus et commandes différents d'une Debian à CentOS. Sur Debian, le nom utilisé est apache2 (conf : /etc/apache2/apache2.conf) alors que sur CentOS le nom utilisé est httpd (conf : /etc/httpd/conf/httpd.conf) Dans les scripts donnés sur cette page, veuillez à remplacer httpd/apache2 selon votre distribution.

Utilisation Mémoire Apache

Apache fonctionne de manière modulaire. Apache va charger un certains nombre de processus selon la charge serveur et la configuration pré-établie. Vous serez donc limiter par les ressources hardwares de votre serveur et ne pourrez charger qu'un certains nombre de processus notamment la mémoire disponible. Une bonne configuraton peux permettre de répondre à des charges ponctuelles ou mettre à mal le serveur (si Apache s'amuse par exemple à charger et décharger des processus enfants).

Dans un premier temps, ce qu'il faut faire c'est de répondre la taille en mémoire d'Apache afin de pouvoir charger un maximum de processus Apache selon les ressources disponibles. Il ne faut pas que le serveur se mette à swapper, sinon les performances seront dégradées (Accès disques etc).

Pour visualiser l'utilisation mémoire Apache, vous pouvez utiliser la commande top.

Image

Rapidement pour donner les grandes lignes :
  • RES : Taille mémoire résidente, c'est la taille mémoire consommé par le processus sans le SWAP.
  • SHR : Taille mémoire partagée : c'est la portion de mémoire VIRT partagée par le processus avec d'autres processus.
  • VIRT : Taille mémoire virtuelle d'un processus : c'est la mémoire qui comprend en plus les bibliothèques chargées par le processus.
Ce qui nous intéresse ici, c'est la colonne RES (équivalent de RSS dans la commande ps). Dans la capture ci-dessous, qui vient d'un CentOs, on voit que le RES est à ~19Mo et le VIRT à ~380Mo.

Optimisation Apache/PHP

Dans un premier temps, nous allons limiter l'utilisation mémoire des processus Apache.
Pour cela, on va décharger les modules inutiles (qui change selon le serveur).

Listons les modules chargés avec la commande httpd -M (sous Debian : apachectl -M).
On constate notamment des modules par forcément nécessaires et surtout python et perl qui ne sont pas utiles dans mon cas. Vous trouverez une liste des modules à la page suivante : http://httpd.apache.org/docs/2.0/mod/

Image

Editons /etc/httpd/conf/httpd.conf pour commenter quelques modules :

Code : Tout sélectionner

LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule auth_digest_module modules/mod_auth_digest.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_alias_module modules/mod_authn_alias.so
LoadModule authn_anon_module modules/mod_authn_anon.so
#LoadModule authn_dbm_module modules/mod_authn_dbm.so
#LoadModule authn_default_module modules/mod_authn_default.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_owner_module modules/mod_authz_owner.so
#LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
#LoadModule authz_dbm_module modules/mod_authz_dbm.so
LoadModule authz_default_module modules/mod_authz_default.so
#LoadModule ldap_module modules/mod_ldap.so
#LoadModule authnz_ldap_module modules/mod_authnz_ldap.so
LoadModule include_module modules/mod_include.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
LoadModule ext_filter_module modules/mod_ext_filter.so
LoadModule mime_magic_module modules/mod_mime_magic.so
LoadModule expires_module modules/mod_expires.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule usertrack_module modules/mod_usertrack.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
LoadModule status_module modules/mod_status.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule info_module modules/mod_info.so
LoadModule dav_fs_module modules/mod_dav_fs.so
LoadModule vhost_alias_module modules/mod_vhost_alias.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule dir_module modules/mod_dir.so
LoadModule actions_module modules/mod_actions.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule userdir_module modules/mod_userdir.so
LoadModule alias_module modules/mod_alias.so
LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule cache_module modules/mod_cache.so
#LoadModule suexec_module modules/mod_suexec.so
LoadModule disk_cache_module modules/mod_disk_cache.so
LoadModule file_cache_module modules/mod_file_cache.so
LoadModule mem_cache_module modules/mod_mem_cache.so
#LoadModule cgi_module modules/mod_cgi.so
LoadModule version_module modules/mod_version.so
Image

Sur CentOs pour décharger Python, Perl et compagnie :
mv /etc/httpd/conf.d/python.{conf,old}
mv /etc/httpd/conf.d/python.{conf,old}
mv /etc/httpd/conf.d/perl.{conf,old}
mv /etc/httpd/conf.d/rpaf.{conf,old}
mv /etc/httpd/conf.d/proxy_ajp.{conf,old}
mv /etc/httpd/conf.d/aclr.{conf,old}
mv /etc/httpd/conf.d/webalizer.{conf,old}

De même au niveau des modules PHP, vous pouvez en désactiver afin de réduire l'utilisation mémoire (Debian : /etc/php5/mods-available/ ).

Sur la machine CentOs :
[root@nsxxxx-xxx ~]# ls -lh /etc/php.d/
total 88K
-rw-r--r-- 1 root root 129 mars 21 19:25 00-ioncube-loader.ini
-rw-r--r-- 1 root root 81 mars 31 2013 apc.ini
-rw-r--r-- 1 root root 49 déc. 11 2013 curl.ini
-rw-r--r-- 1 root root 47 déc. 11 2013 dom.ini
-rw-r--r-- 1 root root 57 déc. 11 2013 fileinfo.ini
-rw-r--r-- 1 root root 45 déc. 11 2013 gd.ini
-rw-r--r-- 1 root root 49 déc. 11 2013 imap.ini
-rw-r--r-- 1 root root 49 déc. 11 2013 json.ini
-rw-r--r-- 1 root root 57 déc. 11 2013 mbstring.ini
-rw-r--r-- 1 root root 53 déc. 11 2013 mysqli.ini
-rw-r--r-- 1 root root 51 déc. 11 2013 mysql.ini
-rw-r--r-- 1 root root 47 déc. 11 2013 pdo.ini
-rw-r--r-- 1 root root 59 déc. 11 2013 pdo_mysql.ini
-rw-r--r-- 1 root root 61 déc. 11 2013 pdo_sqlite.ini
-rw-r--r-- 1 root root 49 déc. 11 2013 phar.ini
-rw-r--r-- 1 root root 79 avril 27 2012 sqlite.ini
-rw-r--r-- 1 root root 49 déc. 11 2013 wddx.ini
-rw-r--r-- 1 root root 59 déc. 11 2013 xmlreader.ini
-rw-r--r-- 1 root root 59 déc. 11 2013 xmlwriter.ini
-rw-r--r-- 1 root root 47 déc. 11 2013 xsl.ini
-rw-r--r-- 1 root root 214 août 15 2013 zend_extensions_psa.ini
-rw-r--r-- 1 root root 47 déc. 11 2013 zip.ini
Vous pouvez aussi charger une page contenant phpinfo(); pour avoir la liste des modules.
Ou encore en ligne de commande avec la commande php -m

Particularité de Debian qui embarque beaucoup de modules par défaut, d'ailleurs dans les informations du package :
Les extensions suivantes sont incorporées : bcmath, bz2, calendar, Core, ctype, date, dba, dom, ereg, exif, fileinfo, filter, ftp, gettext, hash, iconv, json, libxml, mbstring, mhash,
openssl, pcre, Phar, posix, Reflection, session, shmop, SimpleXML, soap, sockets, SPL, standard, sysvmsg, sysvsem, sysvshm, tokenizer, wddx, xml, xmlreader, xmlwriter, zip, zlib.
Il est impossible de décharger les modules, il faut compiler sa propre version de PHP.

Une fois le ménage fait :

Testons la configuration :
service httpd configtest
(Debian : service apache2 configtest)

relançons Apache :
service httpd graceful
(Debian : service apache2 graceful)

Le RES tombe à environ 14/15Mo et le VIRT à ~325Mo

Image

Comme expliqué dans l'introduction, Apache s'adapte au traffic et charge du serveur en chargeant et déchargeant des processus. La configuration est définie par les éléments suivants :
<IfModule prefork.c>
StartServers xxxx
ServerLimit xxxx
MinSpareServers xxxx
MaxSpareServers xxxx
MaxRequestsPerChild 0
MaxClients xxxx
</IfModule>
Pour comprendre :
  • StartServers : StartServers définit le nombre de processus créés au démarrage. Cela ne sert à rien de configurer cette valeur trop haute, si le traffic est trop bas, Apache devra tuer les processus en trop.
  • ServerLimit :
  • MinSpareServers et MaxSpareServers : Ces valeurs définissent le nombre de processus en minimal et maxiaml en attente de requêtes (dormants). MinSpareServers est le nombre de processus minimal créés par le serveur et MaxSpareServers est le nombre de processus maximal. Apache va adapter le nombre de processus créés entre ces deux valeurs selon l'activité du/des site(s).
  • MaxClients : C'est le nombre de processus total au maximum créés. Si la valeur est trop basse et l'activité serveur trop importante, Apache ne pourra plus délivrer les pages. Cette limite permet de protéger le serveur contre une surcharge mémoire Apache.
  • MaxRequestsPerChild : MaxRequestsPerChild définit le nombre total de demandes que chaque processus serveurs fils sert avant de disparaître.
Le serveur Web Apache s'adapte de façon dynamique à la charge reçue en maintenant un nombre de processus serveur de rechange approprié en fonction du trafic. Le serveur vérifie le nombre de processus attendant une requête et en supprime s'ils sont plus nombreux que MaxSpareServers ou en crée s'ils sont moins nombreux que MinSpareServers.

La valeur MinSpareServers par défaut de votre serveur est 5 ; la valeur MaxSpareServers par défaut de votre serveur est 20. Ces paramètres par défaut devraient être appropriés dans presque toutes les situations. Ne définissez pas une valeur très élevée pour MinSpareServers car cela créera une charge de traitement importante sur le serveur, même si le trafic est faible.

En résumé : MinSpareServers, MaxSpareServers et StartServers sont seulement importants pour déterminer les temps de réponses vis-à-vis des clients.
Car la création de processus prend du temps, si les valeurs ne sont pas bonnes, les temps de réponse s'en feront ressentir.
Une mauvaise configuration peux, pour un même traffic, mettre le serveur à genoux comme il peux se porter très bien.

MaxClient lui permet de déterminer la charge total du serveur, d'où le fait qu'un processus Apache doit prendre le minimum de ressources mémoires, ainsi on peux augmenter la valeur de MaxClient.

Ces valeurs diffèrent selon le traffic du serveur.

Lorsque le MaxClient atteint ses limites, on obtient cette erreur dans le fichier error.log
[Fri Aug 04 02:30:02 2006] [error] server reached MaxClients setting, consider raising the MaxClients setting
La valeur MaxClient se calcule de la manière suivante :
((MemoireTotale)(1024)(MB) - Mémoire utilisé par le système) / Memoire RSS/RES

Le script perl suivant permet de calculer les valeurs : http://code.google.com/p/check-httpd-li ... umentation
- HttpdRealAvg : 8.50 MB [excludes shared]
- HttpdSharedAvg : 7.46 MB
- HttpdRealTot : 6347.02 MB [excludes shared]
- HttpdRunning : 733

Httpd Config

- StartServers : 150
- ServerLimit : 2048
- MinSpareServers : 50
- MaxSpareServers : 200
- MaxRequestsPerChild : 0
- MaxClients : 2048

Server Memory

- Cached : 3727.64 MB
- MemFree : 16236.79 MB
- MemTotal : 24165.43 MB
- SwapFree : 1021.27 MB
- SwapTotal : 1021.99 MB

Calculations Summary

- OtherProcsMem : -2153.48 MB (MemTotal - Cached - MemFree - HttpdRealTot - HttpdSharedAvg)
- FreeMemNoHttpd : 26318.91 MB (MemFree + Cached + HttpdRealTot + HttpdSharedAvg)
- MaxLimitHttpdMem : 17415.46 MB (HttpdRealAvg * MaxClients + HttpdSharedAvg)
- AllProcsTotalMem : 15261.98 MB (OtherProcsMem + MaxLimitHttpdMem)

Maximum Values for MemTotal (24165.43 MB)

<IfModule prefork.c>
StartServers 150 # (no change) Default is 5
ServerLimit 3096 # (2048 -> 3096) MaxClients
MinSpareServers 50 # (no change) Default is 5
MaxSpareServers 200 # (no change) Default is 10
MaxRequestsPerChild 0 # (no change) Default is 10000
MaxClients 3096 # (2048 -> 3096) (MemFree + Cached + HttpdRealTot + HttpdSharedAvg) / HttpdRealAvg
</IfModule>

Result

OK: AllProcsTotalMem (15261.98 MB) fits within MemTotal (24165.43 MB).
Le script bash suivant aussi :

Code : Tout sélectionner

#!/bin/bash
tome=$(free -m | grep -i mem | awk '{print $2}')
htps=$(ps -aylC httpd |grep "httpd" |awk '{print $8'} |sort -n |tail -n 1)
mysme=$(ps aux | grep 'mysql' | awk '{print $6}' |sort -n |tail -n 1)
rafa=1024
nmysme=$(expr $mysme / $rafa)
nhtps=$(expr $htps / $rafa)
echo -e "\nTotal Memory = $tome"
echo -e "Largest httpd Process = $nhtps"
echo -e "Mysql Memory = $nmysme"
maxc=`expr $tome - $nmysme`
maxcl=`expr $maxc / $nhtps`
echo -e "\nSo, The MaxClients = $maxcl"
echo -e "(we can use nearest round of value from $maxcl)"
Ce qui donne :
Total Memory = 24165
Largest httpd Process = 17
Mysql Memory = 152

So, The MaxClients = 1412
(we can use nearest round of value from 1412)
Mais la valeur est trop basse en cas de surcharge.

Voici la configuration pour le serveur donné plus haut (24Go) - encore une fois, c'est à titre d'exemple.
Tout dépend de la configuration Apache et des besoins du serveur.
<IfModule prefork.c>
StartServers 150
MinSpareServers 50
MaxSpareServers 200
ServerLimit 2048
MaxClients 2048
MaxRequestsPerChild 0
</IfModule>
La commande watch peux vous aider à déterminer si les valeurs mises sont bonnes.
watch -n 1 "echo -n 'Apache Processes: ' && ps -C httpd --no-headers | wc -l && free -m"
Si le nombre de processus Apache se rapproche du MaxClients et que vous avez encore de la RAM disponible, alors vous pouvez augmenter sa valeur.

Image

Autre élément à tester KeepAlive, ceci permet d'activer la persistence des connexions. Plusieurs requêtes HTTP pourront être envoyées sur une même connexion, si la valeur est à Off, une reconnexion TCP doit être effectué ce qui peux augmenter le délai de délivrance des pages. Cela peux être interressant par exemple si vous avez des pages avec beaucoup d'images.

Exemple de valeurs :
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 3
KeepAliveTimeout est la durée d'attente de la prochaine requête HTTP sur la même connexion, si vous définissez une valeur trop elevé, les processus enfants (MxxSpareServers) seront trop mobilités et vous pouvez avoir une baisse des performances. MaxKeepAliveRequests est le nombre de requête maximum autorisé pour une même connexion TCP.

En général, les valeurs ci-dessous sont suffisantes. Pour les serveurs WEB avec un gros traffic, il peut-être recommandé de limiter les logs voir de les désactiver. Ceci limitera les accès disques. Vous pouvez passer le warn en error pour ne logguer que les erreurs :
LogLevel warn => LogLevel error
Attention aussi au paramètre log_errors dans php.ini qui peux forcer le log.

Optimiser PHP

Vous pouvez adjoindre des cache et autres optimiser tel que : Un peu de compression

Vous pouvez aussi forcer et gérer la compression.
Voici des exemples de fichiers .htaccess qui peuvent être créés à la racine du site.

Pour le header :

Code : Tout sélectionner

<IfModule mod_headers>
  # Mise en cache pour un mois
  <FilesMatch ".(ico|jpe?g|png|gif|swf|flv|gz)$">
  Header set Cache-Control "max-age=2592000"
  </FilesMatch>

  # Mise en cache pour 2 heures
  <filesMatch ".(css|js)$">
  Header set Cache-Control "max-age=7200"
  </filesMatch>

  # Désactive la mise en cache
  <FilesMatch ".(pl|php|cgi)$">
  Header unset Cache-Control
  </FilesMatch>
</IfModule>

Si module gzip :

Code : Tout sélectionner

<IfModule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_dechunk Yes
  mod_gzip_add_header_count Yes
  mod_gzip_send_vary Yes
  mod_gzip_item_exclude reqheader "User-agent: Mozilla/4.0[678]"
  mod_gzip_item_include file .(html?|xml|txt|css|js)$
  mod_gzip_item_include handler ^cgi-script$
  mod_gzip_item_include mime ^text/.*
  mod_gzip_item_include mime ^application/x-javascript.*
  mod_gzip_item_exclude mime ^image/.*
  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>
si module deflate :

Code : Tout sélectionner

<IfModule mod_deflate>
   # Compression avec MOD_DEFLATE
   AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml text/javascript application/x-javascript application/x-httpd-php
 

   #Pour les navigateurs incompatibles
   BrowserMatch ^Mozilla/4 gzip-only-text/html
   BrowserMatch ^Mozilla/4.0[678] no-gzip
   BrowserMatch bMSIE !no-gzip !gzip-only-text/html
   BrowserMatch bMSI[E] !no-gzip !gzip-only-text/html

   # Les proxies ne doivent pas décompresser à la place de l'internaute
   Header append Vary User-Agent env=!dont-vary
</IfModule>

Pour gérer les délai :

Code : Tout sélectionner

<IfModule mod_expires>
  ExpiresActive On
  ExpiresDefault "access plus 7200 seconds"
  AddType image/x-icon .ico
  ExpiresByType image/gif "access plus 2592000 seconds"
  ExpiresByType image/ico "access plus 2592000 seconds"
  ExpiresByType image/jpg "access plus 2592000 seconds"
  ExpiresByType image/png "access plus 2592000 seconds"
  ExpiresByType image/jpeg "access plus 2592000 seconds"
  ExpiresByType image/icon "access plus 2592000 seconds"
  ExpiresByType image/x-icon "access plus 2592000 seconds"
  ExpiresByType text/css "access plus 2592000 seconds"
  ExpiresByType text/html "access plus 7200 seconds"
  ExpiresByType text/javascript "access plus 2592000 seconds"
  ExpiresByType application/xhtml+xml "access plus 7200 seconds"
  ExpiresByType application/x-javascript "access plus 2592000 seconds"
  ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
</IfModule>
Un serveur de cache en front

Vous pouvez aussi installer un serveur de cache en front comme Varnish.

Optimiser MySQL

La théorie est la même que pour Apache, vous devez configurer MySQL selon les besoins en adéquation avec la mémoire disponible. Il existe deux scripts qui peuvent vous aider à optimiser MySQL.
Les deux vous indiquent en rouge les paramètres à modifier.

Image
Image

Une optimisation MySQL peux être nécessaire de temps à autre :
mysqlcheck -o --all-databases -u root -p
Deux autres scripts vous permettent de monitorer l'activité MySQL : Image
Image

Pour identifier les requêtes qui sont trop longues (mal optimisées etc), vous devez activer le slow-log (qu'il convient de désactiver par la suite, puisque cela fera des accès disque) :

Vous devez ajouter/modifier le paramètre :
log-slow-queries = /var/log/mysql/mysql-slow.log
Relancez MySQL :
/etc/init.d/mysql restart
Tester le serveur WEB

Vous pouvez ensuite tester les réponses du serveur WEB.
Il existe beaucoup de programmes notamment ab (package apache2-utils sur Debian).

Exemple :
On obtient :
Document Path: /index.php
Document Length: 281 bytes

Concurrency Level: 30
Time taken for tests: 1.791 seconds
Complete requests: 300
Failed requests: 0
Write errors: 0
Non-2xx responses: 300
Total transferred: 133500 bytes
HTML transferred: 84300 bytes
Requests per second: 167.53 [#/sec] (mean)
Time per request: 179.075 [ms] (mean)
Time per request: 5.969 [ms] (mean, across all concurrent requests)
Transfer rate: 72.80 [Kbytes/sec] received
Vous devez vérifier que vous n'avez pas d'erreur (Failed requests).
Pour le taux de réponse ce qui est important sont les lignes :
Time per request: 179.075 [ms] (mean)
Time per request: 5.969 [ms] (mean, across all concurrent requests)
Conclusion

Une bonne configuration permet de répondre au pic de demandes... une mauvaise configuration permettra le serveur à genoux. La limitation de charge reste la capacité hardware de votre serveur, notamment en mémoire.

Lire : [réseau] Sécuriser un serveur Apache/PHP/MySQL (LAMP)
Première règle élémentaire de sécurité : on réfléchit puis on clic et pas l'inverse - Les fichiers/programmes c'est comme les bonbons, quand ça vient d'un inconnu, on n'accepte pas

Sécuriser son ordinateur (version courte)

Tutoriels Logiciels - Tutoriel Windows - Windows 10

Stop publicités - popups intempestives
supprimer-trojan.com : guide de suppression de malwares

Partagez malekal.com : n'hésitez pas à partager sur Facebook et GooglePlus les articles qui vous plaisent.

Répondre

Revenir vers « Tutoriels et annonces »

Qui est en ligne ?

Utilisateurs parcourant ce forum : Aucun utilisateur inscrit et 1 invité