Comparaison des conteneurs de servlets incorporés au démarrage initial

Comparaison des conteneurs de servlet incorporés au démarrage initial

1. introduction

La popularité croissante des applications et des micro-services en nuage génère une demande accrue de conteneurs de servlets intégrés. Spring Boot permet aux développeurs de créer facilement des applications ou des services à l'aide des 3 conteneurs les plus aboutis disponibles: Tomcat, Undertow et Jetty.

Dans ce didacticiel, nous allons montrer un moyen de comparer rapidement les implémentations de conteneurs à l'aide de métriques obtenues au démarrage et sous une certaine charge.

2. Les dépendances

Notre configuration pour chaque implémentation de conteneur disponible exigera toujours que nous déclarions une dépendance surspring-boot-starter-web dans nospom.xml.

En général, nous voulons spécifier notre parent en tant quespring-boot-starter-parent, puis inclure les démarreurs que nous voulons:


    org.springframework.boot
    spring-boot-starter-parent
    2.0.3.RELEASE
    



    
        org.springframework.boot
        spring-boot-starter
    

    
        org.springframework.boot
        spring-boot-starter-web
    

2.1. Matou

Aucune dépendance supplémentaire n'est requise lors de l'utilisation de Tomcat car elle est incluse par défaut lors de l'utilisation despring-boot-starter-web.

2.2. Jetée

Pour utiliser Jetty, nous devons d'abord exclurespring-boot-starter-tomcat despring-boot-starter-web.

Ensuite, nous déclarons simplement une dépendance surspring-boot-starter-jetty:


    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    


    org.springframework.boot
    spring-boot-starter-jetty

2.3. Reflux

La configuration pour Undertow est identique à Jetty, sauf que nous utilisonsspring-boot-starter-undertow comme dépendance:


    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    


    org.springframework.boot
    spring-boot-starter-undertow

2.4. Actionneur

Nous utiliserons l'actionneur de Spring Boot comme un moyen pratique à la fois de stresser le système et de rechercher des métriques.

Consultezthis article pour plus de détails sur l'actionneur. Nous ajoutons simplement une dépendance dans notrepom pour le rendre disponible:


    org.springframework.boot
    spring-boot-starter-actuator

 2.5. Banc Apache

Apache Bench est un utilitaire de test de charge open source fourni avec le serveur Web Apache.

Les utilisateurs de Windows peuvent télécharger Apache à partir de l'un des fournisseurs tiers liéshere. Si Apache est déjà installé sur votre machine Windows, vous devriez pouvoir trouverab.exe dans votre répertoireapache/bin.

Si vous êtes sur une machine Linux,ab peut être installé en utilisantapt-get avec:

$ apt-get install apache2-utils

3. Métriques de démarrage

3.1. Collection

Afin de collecter nos métriques de démarrage, nous allons enregistrer un gestionnaire d’événements à déclencher sur lesApplicationReadyEvent de Spring Boot.

Nous allons extraire par programmation les métriques qui nous intéressent en travaillant directement avec lesMeterRegistry utilisés par le composant Actuator:

@Component
public class StartupEventHandler {

    // logger, constructor

    private String[] METRICS = {
      "jvm.memory.used",
      "jvm.classes.loaded",
      "jvm.threads.live"};
    private String METRIC_MSG_FORMAT = "Startup Metric >> {}={}";

    private MeterRegistry meterRegistry;

    @EventListener
    public void getAndLogStartupMetrics(
      ApplicationReadyEvent event) {
        Arrays.asList(METRICS)
          .forEach(this::getAndLogActuatorMetric);
    }

    private void processMetric(String metric) {
        Meter meter = meterRegistry.find(metric).meter();
        Map stats = getSamples(meter);

        logger.info(METRIC_MSG_FORMAT, metric, stats.get(Statistic.VALUE).longValue());
    }

    // other methods
}

Nous évitons d’interroger manuellement les points de terminaison Actuator REST ou d’exécuter une console JMX autonome en enregistrant des métriques intéressantes au démarrage dans notre gestionnaire d’événements.

3.2. Sélection

Actuator fournit un grand nombre de métriques prêtes à l'emploi. Nous avons sélectionné 3 mesures qui permettent d’obtenir une vue d’ensemble des principales caractéristiques d’exécution une fois le serveur installé:

  • jvm.memory.used - la mémoire totale utilisée par la JVM depuis le démarrage

  • jvm.classes.loaded - le nombre total de classes chargées

  • jvm.threads.live - le nombre total de threads actifs. Dans notre test, cette valeur peut être considérée comme le nombre de threads «au repos»

4. Métriques d'exécution

4.1. Collection

En plus de fournir des métriques de démarrage, nous utiliserons le point d'envoi/metrics exposé par l'Actuator comme URL cible lorsque nous exécuterons Apache Bench afin de mettre l'application en charge.

Afin de tester une application réelle sous charge, nous pourrions utiliser les points de terminaison fournis par notre application.

Une fois le serveur démarré, nous recevrons une invite de commande et exécuteronsab:

ab -n 10000 -c 10 http://localhost:8080/actuator/metrics

Dans la commande ci-dessus, nous avons spécifié un total de 10 000 demandes utilisant 10 threads simultanés.

4.2. Sélection

Apache Bench est en mesure de nous fournir très rapidement des informations utiles, notamment les temps de connexion et le pourcentage de demandes traitées dans un délai donné.

Pour nos besoins,we focused on requests-per-second and time-per-request (mean).

5. Résultats

Au démarrage, nous avons constaté quethe memory footprint of Tomcat, Jetty, and Undertow was comparable avec Undertow nécessitant un peu plus de mémoire que les deux autres et Jetty nécessitant la plus petite quantité.

Pour notre benchmark, nous avons trouvé quethe performance of Tomcat, Jetty, and Undertow was comparable mais queUndertow was clearly the fastest and Jetty only slightly less fast. 

Métrique

Matou

Jetée

Reflux

jvm.memory.used (MB)

168

155

164

jvm.classes.loaded

9869

9784

9787

jvm.threads.live

25

17

19

Demandes par seconde

1542

1627

1650

Temps moyen par requête (ms)

6.483

6.148

6.059

Notez que les métriques sont, bien entendu, représentatives du projet sans système d'exploitation; les métriques de votre propre application seront certainement différentes.

6. Discussion sur le benchmark

Développer des tests de benchmark appropriés pour effectuer des comparaisons approfondies des implémentations de serveurs peut devenir compliqué. Afin d'extraire les informations les plus pertinentes,it’s critical to have a clear understanding of what’s important for the use case in question.

Il est important de noter que les mesures de référence collectées dans cet exemple ont été prises en utilisant une charge de travail très spécifique composée de requêtes HTTP GET à un point de terminaison Actuator.

It’s expected that different workloads would likely result in different relative measurements across container implementations. Si des mesures plus robustes ou plus précises étaient nécessaires, il serait très judicieux d’établir un plan de test plus adapté à l’utilisation en production.

De plus, une solution d'analyse comparative plus sophistiquée telle queJMeter ouGatling donnerait probablement des informations plus précieuses.

7. Choisir un conteneur

Selecting the right container implementation should likely be based on many factors that can’t be neatly summarized with a handful of metrics alone. Le niveau de confort, les fonctionnalités, les options de configuration disponibles et la stratégie revêtent souvent la même importance, voire davantage.

8. Conclusion

Dans cet article, nous avons examiné l'implémentation des conteneurs de servlets intégrés Tomcat, Jetty et Undertow. Nous avons examiné les caractéristiques d'exécution de chaque conteneur au démarrage avec les configurations par défaut en examinant les métriques exposées par le composant Actionneur.

Nous avons exécuté une charge de travail artificielle sur le système d'exploitation, puis mesuré les performances à l'aide d'Apache Bench.

Enfin, nous avons discuté des avantages de cette stratégie et indiqué quelques points à prendre en compte lors de la comparaison des critères de mise en œuvre. Comme toujours, tout le code source peut être trouvéover on GitHub.