Apache et symfony: optimisation

Je vais vous présentez dans ce billet, les méthodes que j’utilise pour optimiser les réponses d’apache et par la même occasion le rewrite de symfony.

Pour pouvoir effectuer tous les réglages, voici les modules que je charge dans la configuration d’apache

LoadModule deflate_module modules/mod_deflate.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule rewrite_module modules/mod_rewrite.so

Je vais commencer par épurer le log apache. Pour cela, je vais ajouter à la fin de mon fichier de configuration httpd.conf ou apache2.conf (selon les install), les lignes suivantes:

SetEnvIf Request_URI "\.(css|gif|ico|jpg|js|png|txt|xml)$" dontlog
SetEnvIf Request_Method HEAD dontlog

Je vais tout simplement ignorer les fichiers qui contiennent les extensions listées ci-dessus. Ensuite, il suffit d’attribuer cette variable d’environnement à notre paramètre « CustomLog » de notre virtualhost comme ceci:

CustomLog logs/mywebsite.com-access_log combined env=!dontlog

Dès maintenant, Apache prendra moins de temps à écrire ces logs car il ne tiendra plus compte de ces fichiers.

Passons maintenant à la compression des fichiers entre le serveur et le client. Pour cela, j’ai utilisé le code suivant dans la configuration du virtualhost:

<Location />
# ------------- DEFLATE -------------
# http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
<IfModule mod_deflate.c>
  SetOutputFilter DEFLATE
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
  SetEnvIfNoCase Request_URI \
  \.(?:gif|jpe?g|png)$ no-gzip dont-vary
  Header append Vary User-Agent env=!dont-vary
</IfModule>
# ------------- END DEFLATE -------------
</Location>

Cela vous permettra d’économiser un peu de bande passante 😉

Nous allons maintenant nous occuper du cache Apache:

# ------------- EXPIRES RULE -------------
# http://httpd.apache.org/docs/2.0/mod/mod_expires.html
<IfModule mod_expires.c>
  ExpiresActive On

  ExpiresByType text/css "access plus 7 days"
  ExpiresByType application/javascript "access plus 7 days"
  ExpiresByType image/gif "access plus 7 days"
  ExpiresByType image/jpeg "access plus 7 days"
  ExpiresByType image/png "access plus 7 days"
</IfModule>
# ------------- END EXPIRES RULE -------------

Comme vous pouvez le constater ci-dessous, vous avez la possibilité avec la directive « ExpiresByType » de mettre différentes validités selon le type de fichier. Attention quand même lorsque vous utilisez ce genre de cache car il se peut que le serveur ne rende pas toujours le résultat actualisé. Il faut effectuer des tests avant son passage en production.

Passons maintenant à la partie symfony. Par défaut, la configuration du mod_rewrite est située dans le fichier .htaccess à la racine de votre site (dossier web). Apache va lire ce fichier à chaque requête, ce qui prend du temps. Nous allons donc tranférer cela dans notre configuration virtualhost pour l’avoir en mémoire et désactiver la lecture physique:

<Location />
# ------------- REWRITE -------------
<IfModule mod_rewrite.c>
  RewriteEngine On
  
  # Level 0 to 9 [0 = no logging, 9 = all actions] (Default: 0)
  RewriteLogLevel 0
  
  # we check if the .html version is here (caching)
  RewriteRule ^$ index.html [QSA]
  RewriteRule ^([^.]+)$ $1.html [QSA]

  # no, so we redirect to our front web controller
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
# ------------- END REWRITE -------------
</Location>

Dans la directive « <Directory …> », nous allons passer le paramètre « AllowOverride » à none. Vous pouvez ensuite supprimer le fichier .htaccess de votre dossier web.

Pour finir, je vous donne la représentation complète de mon fichier virtualhost:

<VirtualHost *:80>
  ServerName mywebsite.com
  DocumentRoot /www/virtualhosts/mywebsite.com/web
  ErrorLog logs/mywebsite.com-error_log
  CustomLog logs/mywebsite.com-access_log combined env=!dontlog
  RewriteLog logs/mywebsite.com-rewrite.log
  
  Alias /sf /www/virtualhosts/mywebsite.com/lib/vendor/symfony/data/web/sf
  
  <Directory "/www/virtualhosts/mywebsite.com/web">
    Options Indexes FollowSymLinks SymLinksifOwnerMatch
    AllowOverride none
    Allow from All
  </Directory>
  
  <Directory "/www/virtualhosts/mywebsite.com/lib/vendor/symfony/data/web/sf">
    Options Indexes FollowSymLinks SymLinksifOwnerMatch
    AllowOverride none
    Allow from All
  </Directory>

  <Directory "/path/to/my/sfProject/web/uploads">
    php_flag engine off
  </Directory>

  <Location />
    # ------------- REWRITE -------------
    <IfModule mod_rewrite.c>
      RewriteEngine On
      
      # Level 0 to 9 [0 = no logging, 9 = all actions] (Default: 0)
      RewriteLogLevel 0
      
      # we check if the .html version is here (caching)
      RewriteRule ^$ index.html [QSA]
      RewriteRule ^([^.]+)$ $1.html [QSA]

      # no, so we redirect to our front web controller
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteRule ^(.*)$ index.php [QSA,L]
    </IfModule>
    # ------------- END REWRITE -------------
    
    # ------------- DEFLATE -------------
    # http://httpd.apache.org/docs/2.0/mod/mod_deflate.html
    <IfModule mod_deflate.c>
      SetOutputFilter DEFLATE
      BrowserMatch ^Mozilla/4 gzip-only-text/html
      BrowserMatch ^Mozilla/4\.0[678] no-gzip
      BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
      SetEnvIfNoCase Request_URI \
      \.(?:gif|jpe?g|png)$ no-gzip dont-vary
      Header append Vary User-Agent env=!dont-vary
    </IfModule>
    # ------------- END DEFLATE -------------
  </Location>

  # ------------- EXPIRES RULE -------------
  # http://httpd.apache.org/docs/2.0/mod/mod_expires.html
  <IfModule mod_expires.c>
    ExpiresActive On

    ExpiresByType text/css "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"
    ExpiresByType image/gif "access plus 7 days"
    ExpiresByType image/jpeg "access plus 7 days"
    ExpiresByType image/png "access plus 7 days"
  </IfModule>
  # ------------- END REWRITE RULE -------------
  
</VirtualHost>

J’espère que ces petites optimisations pourront vous servir un jour. N’hésitez pas à me faire des remarques et éventuellement me communiquer d’autres astuces Apache/symfony.

Share

10 réflexions sur « Apache et symfony: optimisation »

  1. Bonjour, j’ai modifié mon fichier virtualhost localisé sous /etc/apache2/site-availables, comme indiqué ci-dessus, mais au démarrage de apache j’ai le message d’erreur suivant:
    Starting web server: apache2Syntax error on line 33 of /etc/apache2/sites-enabled/mon_fichier:
    RewriteLogLevel not allowed here
    failed!
    Que dois-je faire exactement?
    Merci pour votre retour.

    • Bonjour,
      Selon les systèmes d’exploitations, le path sur les fichiers de log peuvent changer. Il se peut que vos fichiers soient sous le path /var/log/apache. Si c’est le cas, vous devez personnaliser les directives suivantes dans votre configuration apache: ErrorLog, CustomLog et RewriteLog

  2. Merci, La première partie concernant Apache est très intéressante (je n’avais jamais pensé à jouer un peu sur les logs apache …).

  3. Pour le mod deflate s’il permet d’économiser de la bande passante, il semblerait qu’il augmente aussi la charge sur le serveur à cause de la compression.
    As tu un retour là dessus ?

    • Je surveille ma machine virtuelle avec Zabbix mais je n’ai pas constaté de charge supplémentaire.
      Je vais quand même voir si je peux isoler la chose. Merci pour ton commentaire.

Répondre à Éric Rogé Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *