NGINX 1.9.1 introduit une nouvelle fonctionnalité permettant d’utiliser l’option de socket SO_REUSEPORT, disponible dans les versions récentes de nombreux systèmes d’exploitation, notamment DragonFly BSD et Linux (noyau version 3.9 ou ultérieure). Cette option permet à plusieurs sockets d’écouter sur la même combinaison d’adresse IP et de port. Le noyau répartit ensuite la charge des connexions entrantes entre les sockets.
Note de l’éditeur – Pour les utilisateurs de NGINX Plus, cette fonctionnalité est prise en charge à partir de NGINX Plus version 7 (R7). Pour un aperçu de toutes les nouvelles fonctionnalités de cette version, consultez l’article « Annonce de NGINX Plus R7 » sur notre blog.
L’option de socket « SO_REUSEPORT » offre de nombreuses possibilités d’application concrètes. D’autres services peuvent l’utiliser pour effectuer facilement des mises à niveau progressives des exécutables (NGINX prend déjà en charge les mises à niveau progressives par d’autres moyens). Pour NGINX, l’activation de cette option de socket peut améliorer les performances dans certains cas en réduisant la contention des verrous.
Comme l’illustre la figure, lorsque l’option SO_REUSEPORT n’est pas activée, un seul socket d’écoute informe les processus de travail des connexions entrantes, et chacun d’eux tente de prendre en charge une connexion.

Lorsque l’option SO_REUSEPORT est activée, plusieurs sockets d’écoute sont disponibles pour chaque combinaison d’adresse IP et de port, à raison d’une par processus de travail. Le noyau détermine quelle socket d’écoute disponible (et, par conséquent, quel processus de travail) reçoit la connexion. Cela peut réduire les conflits de verrouillage entre les processus de travail qui acceptent de nouvelles connexions et améliorer les performances sur les systèmes multicœurs. Toutefois, lorsqu’un processus de travail est bloqué par une opération bloquante, ce blocage peut affecter non seulement les connexions qu’il a déjà acceptées, mais aussi les demandes de connexion que le noyau lui a attribuées depuis le début du blocage.

Configuration du partitionnement des sockets
Pour activer l’option de socket SO_REUSEPORT, ajoutez le nouveau paramètre reuseport à la directive listen pour le trafic HTTP ou TCP (module stream), comme dans les exemples suivants :
http { server {
listen 80 reuseport;
server_name localhost;
# ...
}
}
stream {
server {
listen 12345 reuseport;
# ...
}
}L’ajout du paramètre « reuseport » désactive également la directive « accept_mutex » pour le socket, car le mutex est redondant avec « reuseport ». Il peut néanmoins être utile de définir « accept_mutex » si certains ports n’utilisent pas « reuseport ».
Évaluation des performances avec reuseport
J’ai effectué un benchmark wrk avec 4 workers NGINX sur une instance AWS à 36 cœurs. Pour éliminer les effets du réseau, j’ai exécuté le client et NGINX sur localhost, et configuré NGINX pour qu’il renvoie la chaîne OK au lieu d’un fichier. J’ai comparé trois configurations NGINX : la configuration par défaut (équivalente à accept_mutex on), avec accept_mutex off, et avec reuseport. Comme le montre la figure, reuseport multiplie par 2 à 3 le nombre de requêtes par seconde et réduit à la fois la latence et son écart-type.

J’ai également effectué un test de performances similaire, avec le client et NGINX sur des hôtes distincts, et NGINX renvoyant un fichier HTML. Comme le montre le tableau suivant, avec reuseport, la réduction de la latence était comparable à celle du test précédent, tandis que l’écart-type a diminué de manière encore plus spectaculaire (presque d’un facteur dix). Les autres résultats (non présentés dans le tableau) étaient également encourageants. Avec reuseport, la charge était répartie uniformément entre les processus de travail. Dans la configuration par défaut (équivalente à accept_mutex on), certains processus recevaient une part plus importante de la charge, tandis qu’avec accept_mutex off, tous les processus étaient soumis à une charge élevée.
Latence (ms) Écart-type de la latence (ms) Charge CPUPar défaut 15.65 26.59 0.3accept_mutex off 15.59 26.48 10reuseport 12.35 3.15 0.3
Dans ces tests de performance, le taux de demandes de connexion est élevé, mais les requêtes ne nécessitent pas de traitement intensif. D’autres tests préliminaires indiquent également que reuseport améliore surtout les performances lorsque le trafic correspond à ce profil. (Le paramètre reuseport n’est par exemple pas disponible pour la directive listen dans le contexte mail, car le trafic de messagerie ne correspond clairement pas à ce profil.) Nous vous recommandons de tester reuseport afin de déterminer s’il améliore les performances de votre déploiement NGINX, plutôt que de l’appliquer systématiquement. Pour obtenir quelques conseils sur les tests de performance de NGINX, consultez la présentation de Konstantin Pavlov à nginx.conf 2014.
Remerciements
Merci à Yingqi Lu d’Intel et à Sepherosa Ziehau, qui ont chacun proposé au projet NGINX une solution permettant d’utiliser l’option de socket « SO_REUSEPORT ». L’équipe NGINX a combiné les idées issues de ces deux contributions pour créer ce que nous considérons comme une solution idéale.
À propos de l’auteur
Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.
Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.
Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.
Caches partagés avec les clusters de cache NGINX Plus, partie 1
Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.
Introduction aux microservices
Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.