19.2. Configuration de connecteur

19.2.1. Définir les pools de thread pour le connecteur HTTP dans JBoss EAP 6

Résumé

Les pools de threads de JBoss EAP 6 peuvent être partagés parmi les différents éléments à l'aide du modèle Executor. Ces pools peuvent être partagés non seulement par les différents connecteurs (HTTP), mais aussi par d'autres composants de JBoss EAP 6 qui prennent en charge le modèle Executor. Obtenir le pool de threads de connecteurs HTTP qui corresponde à vos exigences de performance web actuel est un travail délicat qui nécessite une étroite surveillance du pool de threads en cours et des exigences de charge web en cours ou anticipées. Dans cette tâche, vous allez apprendre à définir un pool de threads de connecteur HTTP en utilisant le modèle Executor. Vous apprendrez comment définir cela en utilisant à la fois l'interface en ligne de commande et en modifiant le fichier de configuration XML.

Procédure 19.1. Installation d'un pool de threads pour un connecteur HTTP

  1. Définir une usine de threads

    Ouvrir votre fichier de configuration (standalone.xml si vous modifiez un serveur autonome ou domain.xml si vous modifiez une configuration basée domaine. Ce fichier se trouve dans le dossier EAP_HOME/standalone/configuration ou dans EAP_HOME/domain/configuration).
    Ajouter l'entrée de sous-système suivante, en modifiant les valeurs en fonction de vos besoins de serveur.
    <subsystem xmlns="urn:jboss:domain:threads:1.0">
        <thread-factory name="http-connector-factory" thread-name-pattern="HTTP-%t" priority="9" group-name="uq-thread-pool"/>
    </subsystem>
    
    Si vous préférez utiliser le CLI pour cette tâche, alors exécutez la commande suivante dans une invite de commande CLI :
    [standalone@localhost:9999 /] ./subsystem=threads/thread-factory=http-connector-factory:add(thread-name-pattern="HTTP-%t", priority="9", group-name="uq-thread-pool")
  2. Créer un exécuteur

    Vous pouvez utiliser une des six classes d'exécuteur intégrées pour qu'elle agisse en tant qu'exécuteur pour cette usine :
    • unbounded-queue-thread-pool : Ce type de pool de threads accepte toujours les tâches. Si une valeur moindre que la valeur maximale de threads est en cours d'exécution, un nouveau thread démarre pour exécuter la tâche soumise. Sinon, la tâche sera placée dans une file d'attente FIFO illimitée qui sera exécutée lorsqu'un thread sera disponible.

      Note

      Le type d'exécuteur en single-thread fourni par Executors.singleThreadExecutor() est essentiellement un exécuteur de file d'attente illimitée avec une limite de thread d'un. Ce type d'exécuteur est déployé par l'élément unbounded-queue-thread-pool-executor.
    • bounded-queue-thread-pool : ce type d'exécuteur maintient une file d'attente de longueur fixe et deux tailles de pool : une taille de base core et une taille maximale maximum. Lorsqu'une tâche est acceptée, si le nombre de pool de threads en cours d'exécution est inférieur à la taille de core, un nouveau thread est démarré pour exécuter la tâche. Si l'espace reste dans la file d'attente, la tâche est placée dans la file d'attente. Si le nombre de pool de threads en cours d'exécution est inférieur à la taille maximum, un nouveau thread est démarré pour exécuter la tâche. Si un blocage est activé sur l'exécuteur, le thread appelant se bloque jusqu'à ce que l'espace soit rendu disponible dans la file d'attente. La tâche est déléguée à l'exécuteur de la procédure de transfert si un exécuteur de la procédure de transfert est configuré. Dans le cas contraire, la tâche sera rejetée.
    • blocking-bounded-queue-thread-pool : un exécuteur de pool de thread avec une file d'attente délimitée où les tâches de soubmission des threads peuvent bloquer. Un tel pool de threads a une taille de base et une taille maximum, ainsi qu'une longueur de la file d'attente spécifiée. Lorsqu'une tâche est soumise, si le nombre de threads en cours d'exécution est inférieur à la taille de base, un nouveau thread sera créé. Sinon, s'il y a de la place dans la file d'attente, la tâche sera mise en file d'attente. Dans le cas contraire, si le nombre de threads en cours d'exécution est inférieur à la taille maximale, un nouveau thread sera créé. Dans le cas contraire, l'appelant sera bloqué jusqu'à ce que de la place se libère dans la file d'attente.
    • queueless-thread-pool : parfois, il faut un pool de threads simple pour exécuter des tâches dans des threads séparés, en réutilisant les threads ayant terminé leurs tâches sans aucune file d'attente intermédiaire. Ce type de pool est idéal pour le traitement des tâches qui sont longues, en utilisant sans doute des E/S bloquantes, puisque les tâches sont toujours démarrées immédiatement après l'acceptation plutôt que d'accepter une tâche et puis retarder son exécution avant que d'autres tâches en cours d'exécution soient terminées. Ce type d'exécuteur est déclaré à l'aide de l'élément queueless-thread-pool-executor.
    • blocking-queueless-thread-pool : un exécuteur de pool de thread sans file d'attente où les tâches de submission de threads puissent bloquer. Lorsqu'une tâche est soumise, si le nombre de threads en cours d'exécution est inférieur à la taille maximum, un nouveau thread sera créé. Dans le cas contraire, l'appelant sera bloqué jusqu'à ce qu'un autre thread se termine et accepte le nouveau.
    • scheduled-thread-pool : il s'agit d'un type spécial d'exécuteur dont le but est d'exécuter des tâches à des moments et intervalles précis, basés sur la classe java.util.concurrent.ScheduledThreadPoolExecutor. Ce type d'exécuteur est configuré dans l'élément scheduled-thread-pool-executor :
    Dans cet exemple, nous utiliserons unbounded-queue-thread-pool comme exécuteur. Modifier les valeurs des paramètres max-threads et keepalive-time selon les besoins de votre serveur.
    <unbounded-queue-thread-pool name="uq-thread-pool">
      <thread-factory name="http-connector-factory" />
      <max-threads count="10" />
      <keepalive-time time="30" unit="seconds" />
    </unbounded-queue-thread-pool>
    
    Ou bien, si vous préférez utiliser le CLI :
    [standalone@localhost:9999 /] ./subsystem=threads/unbounded-queue-thread-pool=uq-thread-pool:add(thread-factory="http-connector-factory", keepalive-time={time=30, unit="seconds"}, max-threads=30)
  3. Forcez le connecteur web HTTP à utiliser ce pool de threads

    Dans le même fichier de configurations, cherchez l'élément de connecteur HTTP dans le sous-système web et modifiez-le en utilisant le pool de threads défini dans les étapes suivantes.
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" executor="uq-thread-pool" />
    Si vous préférez utiliser le CLI :
    [standalone@localhost:9999 /] ./subsystem=web/connector=http:write-attribute(name=executor, value="uq-thread-pool")
  4. Redémarrer le serveur

    Redémarrer le serveur (autonome ou domaine) pour que les changements puissent prendre effet. Utiliser les commandes CLI suivantes pour confirmer si les changements des étapes ci-dessus ont eu lieu :
    [standalone@localhost:9999 /] ./subsystem=threads:read-resource(recursive=true)
    {                  
        "outcome" => "success",
        "result" => {
            "blocking-bounded-queue-thread-pool" => undefined,
            "blocking-queueless-thread-pool" => undefined,
            "bounded-queue-thread-pool" => undefined,
            "queueless-thread-pool" => undefined,
            "scheduled-thread-pool" => undefined,
            "thread-factory" => {"http-connector-factory" => {
                "group-name" => "uq-thread-pool",
                "name" => "http-connector-factory",
                "priority" => 9,
                "thread-name-pattern" => "HTTP-%t"
            }},
            "unbounded-queue-thread-pool" => {"uq-thread-pool" => {
                "keepalive-time" => {
                    "time" => 30L,
                    "unit" => "SECONDS"
                },
                "max-threads" => 30,
                "name" => "uq-thread-pool",
                "thread-factory" => "http-connector-factory"
            }}
        }
    }
    [standalone@localhost:9999 /] ./subsystem=web/connector=http:read-resource(recursive=true)
    {
        "outcome" => "success",
        "result" => {
            "configuration" => undefined,
            "enable-lookups" => false,
            "enabled" => true,
            "executor" => "uq-thread-pool",
            "max-connections" => undefined,
            "max-post-size" => 2097152,
            "max-save-post-size" => 4096,
            "name" => "http",
            "protocol" => "HTTP/1.1",
            "proxy-name" => undefined,
            "proxy-port" => undefined,
            "redirect-port" => 443,
            "scheme" => "http",
            "secure" => false,
            "socket-binding" => "http",
            "ssl" => undefined,
            "virtual-server" => undefined
        }
    }
    
Résultat

Vous avez pu créer une usine de threads et un exécuteur, tout en modifiant votre connecteur HTTP pour qu'il utilise ce pool de threads.