web-dev-qa-db-fra.com

Quelle est la différence entre le connecteur BIO de Tomcat et le connecteur NIO?

J'aimerais connaître les composants internes du connecteur Tomcat NIO. Comment utilise-t-on exactement les threads lorsque nous créons un servlet qui implémente CometProcessor? Est-ce toujours un thread par connexion?

D'après ce que j'ai lu, la conversation se passe comme ceci

  1. Le client se connecte à un servlet

  2. Le servlet s'accroche à la connexion jusqu'à ce que toutes les données soient disponiblesau client connecté

  3. Lorsque les données sont prêtes, le serveur écrit dans httpResponse et le supprime Cela déconnecte réellement la connexion?

  4. Le client envoie une autre demande à laquelle le serveur se bloque à nouveau.

Combien de threads sont utilisés quand cela continue à arriver?

51
user1456150

NIO et Comet sont complètement indépendants: vous pouvez les combiner.

L'utilisation du connecteur NIO (ou APR d'ailleurs) vous permet de traiter plus de demandes avec moins de threads en raison du modèle de threading. Voir http://Tomcat.Apache.org/Tomcat-7.0-doc/config/http.html#Connector_Comparison pour une comparaison entre les connecteurs.

Comet (et Websocket) ont un modèle de répartition complètement différent qui nécessite une architecture d'application différente et permet d'atteindre un débit supérieur d'une manière différente.

Le scénario que vous posez dans votre question est le modèle typique à un thread par requête bloquant. À l'étape 4, le connecteur Java BIO (qui est la valeur par défaut pour Tomcat 7) continue d'attendre les demandes supplémentaires sur le connecteur existant, à savoir les demandes HTTP persistantes. Si le client ne définit pas Connection:close sur la demande précédente et ne ferme pas la connexion, le thread se bloque jusqu'à ce que le délai de conservation soit atteint. Si vous utilisez le connecteur NIO, le thread retournera dans le pool de threads immédiatement après l'envoi de la réponse et vous ne "gaspillerez" pas un thread sur des requêtes keepalive qui risquent de ne jamais arriver.

Comet/Websocket fonctionne de manière totalement différente en transmettant un message à un servlet spécialement écrit (et à des filtres facultatifs). Les threads ne sont utilisés que lorsqu'il existe des messages à envoyer ou des données à écrire.

UPDATE 2016-08-19

Tomcat 8.5 et 9.0 ont complètement abandonné le connecteur BIO. En effet, bon nombre des nouvelles API et technologies (par exemple, Websocket) nécessitent une sémantique non bloquante et il est très difficile de créer un service non bloquant au-dessus d’une API bloquante. Le code requis pour effectuer le travail rendait le reste du code Tomcat très laid, etc., et la décision fut donc prise de laisser tomber complètement le connecteur BIO. Ainsi, pour Tomcat 8.5 et les versions ultérieures, seuls les connecteurs NIO, NIO2 et APR sont disponibles.

Notez que, également avec Tomcat 8.5 et 9.0, la prise en charge de Comet _ a été supprimée. Les utilisations de Comet devraient toutes être remplacées par Websocket, qui est un protocole plus standard.

53

NIO utilise moins de thread, cela signifie que le port TCP/IP est moins utilisé.

Vous savez que le port est compris entre 1 et 65534, nous pouvons donc dire que NIO peut atteindre un TPS (Transactions par seconde) plus élevé que BIO

J'ai testé les protocoles :HTTP/1.1 et org.Apache.coyote.http11.Http11NioProtocol.__ avec le même projet Web, le même hôte et le même serveur.xml, mais avec le protocole.

Utilisez jmeter pour le test.

J'ai mis la tâche 1000 à exécuter la requête, lorsque HTTP/1.1 dans quelques minutes, le port d'utilisation de l'hôte est supérieur à 30000 et le TPS est à 300 uniquement!

Lorsque org.Apache.coyote.http11.Http11NioProtocol, le nombre maximal de ports d’utilisation n’est jamais supérieur à 3000 et le tps dépasse 1200!

5
toby941

Ajouter tard à cette discussion - Dans ce contexte de comparaison des performances entre le blocage IO et le NIO asynchrone - une excellente lecture est "L'ancienne méthode d'écriture de serveurs est nouvelle" . En résumé, il a été constaté que le modèle thread par connexion était plus performant et facile à écrire par rapport à La version NIO - contrairement à la croyance populaire.

4
user6369908

Voici deux bons articles sur le connecteur NIO au cas où cela aiderait quelqu'un à prendre en compte les différences entre BIO (le traitement de la requête doit accepter le thread) et NIO (le traitement de la requête est passé sur un autre thread de travail) dans Tomcat.

0
Mike Barlotta