FrankenPHP et Drupal, ça dit quoi côté performances ?

Nous avions déjà assisté à la conférence de Kevin Dunglas sur FrankenPHP lors de la SymfonyCon Disneyland Paris 2022, et avons pu profiter d'une seconde conférence adressée lors du DrupalCamp de Rennes en 2024.

Bien qu'intéressant et prometteur, le projet semblait toutefois bien jeune, et nous ne pouvions imaginer proposer une solution avec si peu de retour d'expériences pour remplacer des stacks éprouvées auprès de nos clients.

FrankenPHP, c'est quoi ?

FrankenPHP est un serveur d'applications PHP écrit en Go. Il s'appuie sur le serveur Caddy et propose un certain nombre de fonctionnalités dont les principales sont :

  • Des performances accrues
  • Fournir un serveur de qualité production
  • Créer des binaires autonomes et auto-executables
  • Une simplicité de configuration
  • Proposer des fonctionnalités actuelles non prises en compte par les systèmes actuels (103 Early hints, Temps réel, etc)

Et FrankenPHP avec Drupal ?

Initié en 2022, le repository github permettant de configurer un FrankenPHP avec Drupal s'est affiné suite au DrupalCamp de Rennes.

Bonne nouvelle, cela fonctionne ! On arrive alors sans effort à faire fonctionner un Drupal avec FrankenPHP.

Et les performances dans tout ça ?

Edit 04/04/2024 : Corrections suite a affinage des tests.

Les tests ont été réalisés depuis et sur un poste de développement avec Docker. Les chiffres sont donc à prendre pour ce qu'ils sont et n'ont pour seul objectif que de se donner un ordre de grandeur des différences entre notre stack habituelle et frankenPHP.

  • Test réalisés via l'image docker Docker-Jmeter.
  • Stack habituelle : Un container PHP-FPM + Nginx
  • Stack FrankenPHP : Un container FrankenPHP

Lors des tests, seuls les containers de la stack à tester sont allumés.

Pour les tests, nous avons installé sur chacune des stacks un Drupal avec le profil d'exemple Umami et y cherchons la chaine "Vegan" sur des tests de perfs pendant 600 secondes avec un appel HTTP (pas de HTTPS), un seul thread et aucun délai. La base de données utilisée dans les 2 cas est une base de données MariaDB située dans un container des stacks respectives.

Les tests ont été réalisés 2 fois pour s'assurer de la cohérence des tests.

Les tests ont été réalisés en tant qu'utilisateur anonyme avec les caches d'activés et sans les caches.

La configuration est la suivante pour les tests avec les caches désactivés de manière à solliciter d'avantage de calcul :

Configuration de settings.nocache.php inclut dans settings.php :

$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['page'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
$settings['container_yamls'][] = $app_root . '/sites/default/services.nocache.yml';

Configuration de services.nocache.yml :

parameters:
  twig.config:
    cache: false
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

Tests avec la stack PHP-FPM

Commençons par la stack que nous utilisons habituellement, à savoir un container PHP-FPM incluant un NGINX configuré et optimisé pour Drupal.

En anonyme, avec les caches désactivés

Image
Tableau recapitulatif Jmeter Nginx PHP-FPM Mariadb anonyme sans cache

Nous arrivons donc à un résultat de :

  • Nombre d'appels : 480
  • Temps minimum de réponse : 181ms
  • Temps maximum de réponse : 282ms
  • Temps moyen de réponse : 202.22ms

En anonyme, avec les caches activés

Image
Tableau recapitulatif Jmeter Nginx PHP-FPM Mariadb anonyme avec cache

Nous arrivons donc à un résultat de :

  • Nombre d'appels : 569
  • Temps minimum de réponse : 3ms
  • Temps maximum de réponse : 45ms
  • Temps moyen de réponse : 5.43ms

Tests avec FrankenPHP

Pour rappel, nous utilisons FrankenPHP avec mariadb (au moment des tests, le github proposait postgresql par défaut, nous verrons ce cas plus tard).

En anonyme, avec les caches désactivés

Image
Tableau Jmeter recapitulatif frankenphp mariadb anonyme sans cache

Nous arrivons donc à un résultat de :

  • Nombre d'appels : 471
  • Temps minimum de réponse : 212ms
  • Temps maximum de réponse : 329ms
  • Temps moyen de réponse : 226.18ms

En anonyme, avec les caches activés

Image
Tableau récapitulatif Jmeter FrankenPHP MariaDB Anonyme avec cache

Nous arrivons donc à un résultat de :

  • Nombre d'appels : 568
  • Temps minimum de réponse : 4ms
  • Temps maximum de réponse : 32ms
  • Temps moyen de réponse : 6.36ms

Comparatif des résultats

Comparatif Anonyme sans caches
 NGINX + PHP-FPMFrankenPHP
Nombre d'appels480471
Temps Min. en ms181212
Temps Max. en ms282329
Temps moyen en ms202.22226.18
Comparatif Anonyme avec caches
 NGINX + PHP-FPMFrankenPHP
Nombre d'appels569568
Temps Min. en ms34
Temps Max. en ms4532
Temps moyen en ms5.436.36
   

Peu de différence entre les 2, mais léger mieux pour NGINX + PHP-FPM, mitigé par le fait que la configuration de cette stack a été d'avantage optimisée et éprouvée que FrankenPHP qui est configuré par défaut (pas de mode worker) et qu'il n'en est qu'à ses début.

Les tests sont ce qu'ils sont, c'est à dire pas grand chose : les tests sont très basiques, effectués sur la même machine, aucune optimisation spécifique, utilisation des caches de Drupal... Mais permettent tout de même de voir une belle différence entre les 2 systèmes, suffisantes pour pousser les tests avec FrankenPHP.

Allons plus loin, et postgreSQL ?

Les premiers tirs ont été effectués avec postgreSQL sur FrankenPHP, la configuration fournie par défaut sur le repo étant postgreSQL. 

Voici donc pour information les tests avec FrankenPHP uniquement et PostgreSQL.

Image
Tableau récapitulatif des tirs de performances Drupal et FrankenPHP et postgreSQL
 FrankenPHP + PostgreSQLFrankenPHP + MariaDB
Nombre d'appels556565
Temps Min. en ms134
Temps Max. en ms5129
Temps moyen en ms28.6410.01

On voit donc une différence cette fois de x2 a x3 en temps de réponse en faveur de mariaDB.

Contribution : Module Lazy service, un peu plus de paresse dans votre Drupal

Contribution : Module Lazy service, un peu plus de paresse dans votre Drupal

FrankenPHP et Drupal, ça dit quoi côté performances ?

FrankenPHP et Drupal, ça dit quoi côté performances ?