Dans notre application, nous devons traiter des volumes de demandes supérieurs à 5 000 demandes par seconde. On nous a dit que cela est possible avec Jetty dans notre type d'application (où nous devons exposer une API JSON-HTTP à un système distant, qui initiera ensuite les demandes entrantes et les connexions avec nous).
Nous recevons plusieurs milliers de connexions HTTP entrantes, dont chacune est persistante et dure environ 30 secondes. Le serveur distant nous envoie ensuite des requêtes aussi rapidement que nous pouvons y répondre sur chacune de ces connexions. Après 30 secondes, la connexion est fermée et une autre est ouverte. Nous devons répondre en moins de 100 ms (y compris le temps de transit du réseau).
Notre serveur fonctionne en EC2 avec 8 Go de RAM, dont 4 Go sont alloués à notre Java VM (des recherches antérieures ont suggéré que vous ne devriez pas allouer plus de la moitié) le RAM disponible sur la JVM).
Voici comment nous initialisons actuellement Jetty en fonction de divers conseils que nous avons lus sur le Web:
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(config.listenPort);
connector.setThreadPool(new QueuedThreadPool(5120));
connector.setMaxIdleTime(600000);
connector.setRequestBufferSize(10000);
server.setConnectors(new Connector[] { connector });
server.setHandler(this);
server.start();
Notez que nous n'avions à l'origine que 512 threads dans notre pool de threads, nous avons essayé d'augmenter à 5120 mais cela n'a pas aidé de façon notable.
Nous constatons qu'avec cette configuration, nous avons du mal à gérer plus de 300 demandes par seconde. Nous ne pensons pas que le problème soit notre gestionnaire car il ne fait que quelques calculs rapides et une sérialisation/désérialisation Gson.
Lorsque nous faisons manuellement une demande HTTP de notre propre chef pendant qu'il essaie de gérer cette charge, nous constatons que cela peut prendre plusieurs secondes avant de commencer à répondre.
Nous utilisons Jetty version 7.0.0.pre5.
Toutes suggestions, que ce soit pour une solution ou des techniques pour isoler le goulot d'étranglement, seraient appréciées.
Tout d'abord, Jetty 7.0.0.pre5 est [~ # ~] très [~ # ~] très ancien. Jetty 9 est maintenant sorti et a beaucoup optimisations de performances.
Téléchargez une version plus récente de la ligne 7.x sur https://www.Eclipse.org/jetty/previousversions.html
Les conseils suivants sont documentés à l'adresse
Assurez-vous de les lire.
Ensuite, la taille du pool de threads est pour la gestion des demandes acceptées, 512 est élevé. 5120 est ridicule. Choisissez un nombre supérieur à 50 et inférieur à 500.
Si vous avez un nœud EC2 basé sur Linux, assurez-vous de configurer la mise en réseau pour un bénéfice maximal au niveau du système d'exploitation. (Voir le document intitulé "Charge élevée" dans la liste mentionnée ci-dessus pour plus de détails)
Assurez-vous que vous utilisez un JRE/JDK récent, tel que Oracle Java 1.6u38 ou 1.7u10. De plus, si vous avez un système d'exploitation 64 bits, utilisez le JRE/JDK 64 bits.
Définissez votre nombre d'accepteurs, SelectChannelConnector.setAcceptors (int) pour être une valeur comprise entre 1 et (number_of_cpu_cores - 1).
Enfin, configurez Garbage Collection optimisé et activez GC Logging pour voir si les problèmes que vous rencontrez concernent la jetée ou le GC de Java. Si vous voyez via la journalisation du GC qu'il y a des événements massifs "arrêter le monde" du GC prenant beaucoup de temps, alors vous connaissez une autre cause de vos problèmes de performances.