Je suis en train de choisir une bibliothèque réseau pour implémenter un système client/serveur qui ne peut épargner aucune microseconde. Il implémentera son propre protocole pour envoyer et recevoir des messages. Je recherche un bon framework NIO qui me permettra de développer facilement le serveur et le client, sans avoir à trop se soucier des détails du sélecteur de bas niveau. Tout le monde me recommande Netty mais j'aimerais expérimenter 2 ou 3 autres alternatives avant d'engager mon équipe avec un framework. Une chose que je n'aimais pas beaucoup à propos de Netty est la façon dont il gère les ByteBuffers avec sa propre implémentation ByteBuf et le comptage des références. Quelqu'un peut-il partager vos pensées et vos alternatives?
Nous avons développé une bibliothèque de mise en réseau NIO qui fonctionne en moins de 2 microsecondes en boucle sans produire de déchets pour le GC. Comme Peter Lawrey l'a mentionné, le sélecteur JDK natif produit beaucoup de déchets mais nous avons corrigé toutes ces fuites de déchets en implémentant notre propre sélecteur epoll. Occupé à attendre le thread de sélection est idéal pour la latence, mais il doit y avoir un équilibre pour ne pas brûler la puce ou consommer beaucoup d'énergie. Notre implémentation de sélecteur utilise des astuces de bas niveau pour implémenter une sorte de mode d'économie d'énergie qui prend en charge cet équilibre.
Outre CoralReactor , vous pouvez également jeter un œil à Grizzly et Mina , mais nous n'avons pas encore joué avec ces cadres.
Pour certains Netty TCP benchmarks de performance, vous pouvez jeter un oeil ici .
Cela suppose que vous souhaitiez vraiment économiser chaque micro-seconde. La plupart des applications n'ont pas d'exigences aussi strictes.
Si vous voulez économiser des micro-secondes, vous voudrez utiliser NIO non bloquant en attente occupé pour les threads sur les processeurs dédiés. Cela n'évolue pas bien car vous devez avoir beaucoup de CPU, mais minimise la latence pour la gestion des E/S. Je vous suggère également de lier les CPU isolés pour minimiser la gigue.
Vous voudrez éviter d'utiliser des sélecteurs car ils bloquent et/ou créent pas mal de déchets en ajoutant aux pauses du GC.
Pour minimiser la latence, vous souhaiterez également utiliser une carte réseau de contournement du noyau à faible latence telle que Solarflare.
Vous voudrez utiliser un analyseur Push pour que les longs messages puissent être décodés/analysés pendant leur téléchargement. c'est-à-dire que vous ne voudrez pas attendre que tous les messages soient reçus avant de commencer.
L'utilisation de ces astuces en combinaison permet d'économiser de 10 à 30 micro-secondes sur chaque demande ou événement entrant.
Netty est une meilleure solution d'évolutivité, c'est-à-dire un débit net plus élevé, mais à un faible coût pour la latence, comme le font la plupart des cadres basés sur des services Web de support où des retards de quelques secondes sont tolérables.
Si vous êtes d'accord pour utiliser au moins du Scala, Spray est une excellente alternative à Netty. À long terme, le framework Play a par exemple l'intention de migrer de Netty vers Spray. Spray propose différents niveaux d'abstractions TCP. Ce sont:
Plus vous creusez profondément dans la pile, plus les informations fournies sont brutes. Dans l'API de niveau de bloc, vous vous rapprochez assez des tampons d'octets d'origine. Je n'ai jamais utilisé ce faible niveau d'abstraction moi-même, mais j'ai entendu de bonnes choses.
Spray se construit au-dessus d'Akka IO qui est à nouveau construit au-dessus de Java NIO. Toutes les fonctionnalités entourent les abstractions d'acteur, ce qui facilite la construction d'applications parallèles à l'aide de Spray. Je pense qu'un serveur de chat serait un cas d'utilisation parfait. Comme Akka propose une API Java, vous devriez pouvoir utiliser Spray avec principalement cette API. Cependant, vous devrez probablement lire quelques Scala sources de temps en temps. Finalement, Spray fusionnera complètement dans Akka.
Edit: Citation du site Web de Spray: "Spray n'est plus maintenu et a été remplacé par Akka HTTP . Playframework a commencé à prendre en charge expérimentalement le backend Akka HTTP Server à partir de Play 2.4.X =. Dans les versions Play 2.6.X , play a complètement migré vers le backend du serveur HTTP Akka.