Je traite avec un système qui exécute une application Java par client dans sa propre JVM. Nous avons environ une demi-douzaine de serveurs dédiés qui exécutent près de 100 machines virtuelles au total et des ensembles de scripts personnalisés pour la gestion de ces machines virtuelles. À ce stade, cette configuration montre vraiment son âge: la gestion de nombreuses machines virtuelles devient un cauchemar de surveillance/gestion et nous sommes constamment confrontés à des problèmes de taille de tas. Nous aimerions adopter une approche plus moderne et n'exécuter que de nombreuses applications sur un seul serveur d'applications par machine physique. Cependant, le fait de garder les applications séparées présente des avantages distincts en termes d'isolation (par exemple, les erreurs de mémoire insuffisante ne concernent qu'un seul client). La pile logicielle de chaque client a des besoins en mémoire très variables.
Ma question est la suivante: existe-t-il un moyen d’avoir le meilleur des deux mondes et d’exécuter plusieurs applications dans une JVM (serveur d’application) tout en maintenant un certain niveau d’isolation? Ou est-ce simplement un fait moderne de la vie qu'il vous faut aujourd'hui pour gérer les besoins en mémoire d'un ensemble d'applications? Outre un serveur d'applications ou un conteneur Java EE (Wildfly ou Spring, par exemple), y a-t-il d'autres solutions qui me manquent ici? On dirait que ce système est une garantie d'une autre époque!
Commander des machines virtuelles 'multi-locataires'.
JRE d'IBM l'a déjà: http://www.ibm.com/developerworks/library/j-multitenant-Java/
Waratek l'a implémenté sur Oracle JRE et a créé ElastiCat, un fork de Tomcat qui isole différentes applications dans le même conteneur: http://www.elasticat.com/faq/
Selon certaines rumeurs, la multi-location apparaîtrait aussi dans la JVM officielle d’Oracle Java 9.
=============================================== =====
Mise à jour: Java 9 est sorti, mais aucun mot d'Oracle sur la multi-location. Il semble qu'ils préfèrent avoir plusieurs JVM, même plusieurs Containers (par exemple, docker).
Il y a des avantages et des inconvénients de l'une ou l'autre approche:
JVM partagée
JVM séparé
Globalement, je ne définirais pas de politique générale. Recherchez des petits/micro-services ou autres applications à faible utilisation qui peuvent être de bons candidats à partager en premier et à étendre à partir de là.
Jetez un coup d'œil Spring Boot ou Fabric8 pour une approche moderne de l'exécution de Java de manière simple
Une autre raison importante d'avoir plusieurs machines virtuelles au lieu d'une est la confrontation avec les groupes numa. Vous ne pouvez pas distribuer vos threads dans une machine virtuelle Java appropriée sur des groupes numa comme vous pouvez le faire avec plusieurs processus JVM. Au moins, je n'ai jamais trouvé le moyen de le faire.
Nous avons ici des machines avec deux processeurs, chacun ayant 18 cœurs. Cela donne deux groupes numa et nous ne pouvons pas imposer la diffusion de 34 threads sur les deux cpu si une seule machine virtuelle est utilisée. C'est évidemment parce que cela suppose que tous les threads du même processus JVM doivent avoir un accès rapide à la même mémoire, ce qui n'est pas le cas.
Avec 34 processus, le système suppose qu'ils n'ont pas besoin de mémoire partagée et les répartissent ainsi sur les deux processeurs.
Si quelqu'un connaît un meilleur moyen de le faire, je serais très heureux de l'entendre.