Je crée des services Web qui auraient 2000 utilisateurs simultanés. Les services sont offerts gratuitement et devraient donc bénéficier d'une large base d'utilisateurs. À l'avenir, il sera peut-être nécessaire de faire évoluer jusqu'à 50 000 utilisateurs.
Il y a déjà quelques autres questions qui traitent du problème comme - /programming/2567254/building-highly-scalable-web-services
Cependant, mes exigences diffèrent de la question ci-dessus.
Par exemple - Mon application n'a pas d'interface utilisateur, donc les images, CSS, javascript ne sont pas un problème. Il est en Java, donc des suggestions comme utiliser HipHop pour traduire PHP en code natif sont inutiles.
J'ai donc décidé de poser ma question séparément.
Ceci est la configuration de mon projet -
- Services Web reposant sur Apache CXF
- Hibernate 3.0 (avec des optimisations pertinentes comme le chargement paresseux et HQL personnalisé pour l'optimisation)
- Tomcat 6.0
- MySql 5.5
Quelles sont les meilleures pratiques à respecter pour rendre une application basée sur Java évolutive?
la source
Réponses:
J'ai traité la question dans le passé, mais je sens toujours que j'ai beaucoup à apprendre sur le terrain. Je trouve que c'est l'un des domaines les plus intéressants du développement logiciel de nos jours, voici quelques réflexions à ce sujet:
MySQL est une base de données assez juste , sauf si vous travaillez avec une énorme quantité de données, et dans ce cas, vous pourriez envisager NoSQL mais vous devez examiner attentivement quelle est la meilleure base de données NoSQL pour vos besoins.
Vous devez implémenter la mise en cache sur votre système - essayez de mettre en cache autant de données en lecture seule que possible, ou définir des stratégies de mise en cache - par exemple, nous avions un scénario dans lequel il était valide pour un utilisateur de voir les "anciennes données" comme tant que la récente mise à jour a eu lieu au cours de la dernière heure.
Je considérerais JBoss Cache, ou peut-être Infinispan (qui ressemble plus à une structure de données distribuée) ou un autre cadre de mise en cache populaire pour cela.
De plus, comme vous l'avez mentionné tomcat, je suppose que vous travaillez dans un module de demande-réponse. Essayez d'envisager d'utiliser un cache qui existe dans la portée d'une demande donnée, cela peut même être un simple HashMap associé au stockage local du thread .
Mon idée ici ressemble assez au cache de premier niveau chez Hibernate .
N'oubliez pas que les fichiers, les transactions et les autres ressources coûtent cher pour les garder ouverts. Assurez-vous de fermer les fichiers et les transactions dès que possible, sinon vous vous retrouverez avec des bogues qui se reproduiront sur des configurations à grande échelle
De plus, vous devez comprendre ce que 2000 utilisateurs simultanés - cela signifie-t-il que 2000 utilisateurs accèdent à votre serveur en même temps ou utilisent-ils votre système? Faites la distinction entre les cas où 2 000 utilisateurs tentent d'ouvrir un socket sur votre serveur et un cas où seulement 500, et 1 500 sont actuellement à la recherche de résultats, remplissent l'entrée côté client.
Vous devriez envisager d'utiliser le clustering - vous devrez faire face à des problèmes tels que l'équilibrage de charge , la session persistante (ce qui signifie que l'équilibreur de charge redirigera une demande vers le même serveur pour la même session) et plus encore.
Si vous avez besoin d'un code de synchronisation - choisissez soigneusement la stratégie de synchronisation. J'ai vu certains systèmes dans lesquels un simple verrou était utilisé, mais un ReaderWriterLockaurait pu améliorer les choses, car la plupart des accès étaient en lecture seule.
Envisagez si possible la mise en cache et la validation côté client, essayez d'enregistrer les appels vers le serveur et d'envoyer uniquement les différences de données, au cas où la plupart de votre réponse à une demande avec le même paramètre ne changerait pas.
Par exemple, chez oVirt open source project, nous demandons à obtenir des statistiques sur une machine virtuelle donnée. certaines des données de la VM changent rarement, nous n'en envoyons donc que MD5, si les données changent, la valeur MD5 est également modifiée, nous effectuons une demande pour obtenir les données complètes, et pas seulement le MD5.
J'ai déjà mentionné hibernate - je vous recommanderais de bien réfléchir à son utilisation - si vous avez besoin d'effectuer beaucoup d'écritures et moins de lectures, Hibernate pourrait ne pas être idéal pour vous, et vous devriez peut-être envisager de travailler avec Spring-JDBC comme wrapper. JDBC.
Indexez votre base de données judicieusement et utilisez un schéma de base de données correct. Pensez à utiliser une couche de procédures stockées car elles sont précompilées et optimisées.Je
voudrais dire que par le passé, j'ai traité un système (nœud unique) sur mysql (principalement en lecture seule) avec jboss 4.2.1 et j'ai réussi à atteindre 2000 simultanément utilisateurs
(n'accédant pas à la fois en termes d'ouverture de 2000 sockets sur notre serveur), mais en utilisant / parcourant notre système, en utilisant JBoss Cache et en préchargeant dans le cache certaines des données les plus consultées, ou les données que nous avons réalisées vont être "chaudes et populaires" "mais notre solution était bonne pour notre architecture et nos flux,
donc comme je le dis dans ces cas -
il y a plus de trucs et astuces, mais cela dépend vraiment de votre architecture et des flux dont vous avez besoin dans votre système. Bonne chance!
la source
Bonne question. Difficile probablement de dire quelle est la meilleure approche, mais j'essaierai d'après mon expérience.
La meilleure façon de mettre à l'échelle l'application Web basée sur Java est de l'écrire le plus possible sans état (si vous le pouvez). Cela vous permet de mettre à l'échelle horizontalement l'application, où vous pouvez ajouter des serveurs tomcat s'il y a plus d'utilisateurs simultanés.
Cependant, comme vous l'avez noté, il peut y avoir un problème avec les connexions à la base de données. Mais la question que j'ai est, comment obtenez-vous les données? Est-ce généré par l'utilisateur ou vous obtenez les données d'un tiers? Ceci est très important car, si vous offrez un service à votre utilisateur avec les données agrégées à partir d'une application tierce (par exemple FB, Twitter, etc.), alors ce que vous pouvez suivre, c'est écrire dans la base de données maître et répliquer les données dans des bases de données esclaves qui sont alloués à chaque instance de tomcat. Ensuite, chaque serveur tomcat peut obtenir à partir de sa propre base de données esclave.
Vous pouvez opter pour le cluster MySQL qui a une banque de données en mémoire. Mais gardez à l'esprit que l'application peut nécessiter quelques modifications. Ils
sql joins
ne sont pas bien pris en charge dans le cluster MySQL bien que dans la dernière version il y ait des améliorations pour le même. Si le coût n'est pas un facteur, vous pouvez essayer Oracle.La solution de mise en cache améliorera certainement les performances. Mais alors, tout dépend de l'architecture de l'ensemble de l'application. Vous devez bien savoir quand envoyer des données dans le cache, quand les rendre sales (supprimer du cache).
Concernant la distribution de la charge dans un environnement multi-serveur, je vous suggère d'utiliser l'équilibreur de charge plutôt que d'utiliser Apache pour l'équilibrage de charge.
la source
Je suis en train de mettre en place un système similaire (au niveau professionnel) et c'est le design que j'ai choisi:
Cela permettra d'obtenir une solution redondante, haute disponibilité et évolutive.
Les équilibreurs de charge (sur un matériel décent) équilibreront facilement une ligne saturée de 1 Gbit chacun. C'est également un excellent endroit pour le déchargement SSL.
Vous pouvez enregistrer vos informations de session dans memcached. En cas d'échec d'une instance de tomcat, une autre instance de tomcat peut récupérer les informations de session pertinentes et les clients ne remarqueront rien. N'oubliez pas de combiner cela avec des séances collantes aussi. (Pour limiter le trafic réseau)
Le clustering Tomcat a également une option pour partager les informations de session avec le cluster en temps réel, sans utiliser memcached. Bien que je pense en termes de performances, l'utilisation de Memcached sera meilleure.
Si vous avez besoin de plus de puissance dans l'une de ces applications:
Je ne sais pas comment votre application est construite et quelles sont les grosses ressources de porcs, mais si vous voyez une charge de base de données élevée (pendant vos tests de charge!), L'ajout d'un cache entre l'application et la base de données pourrait certainement améliorer considérablement les performances. Mais n'oubliez pas que tout n'est pas cachable, si vos requêtes sont toujours différentes, la mise en cache n'aidera pas (beaucoup)
Mon conseil serait de télécharger VMware Workbench (ou un logiciel de virtualisation similaire) et d'essayer de créer une configuration simple. Pas d'équilibrage de charge ou de clustering, juste les bases et travaillez à partir de là. Un par un, ajoutez plus de fonctionnalités (équilibrage, mise en cache, mise en cluster, etc.) et assurez-vous de faire des recherches sur chaque sujet, afin que vous sachiez que vous avez fait le bon choix.
Si vous continuez à exécuter les mêmes tests de performances au cours de ce processus, vous pouvez voir par vous-même si l'utilisation de X est meilleure que l'utilisation de Y dans votre configuration, ou quel impact la mise en cache aura, etc.
En fin de compte, une configuration comme celle-ci dépend vraiment des exigences de votre application et de ses clients, tout peut être fait de différentes manières, chacune avec ses propres forces et faiblesses.
Autres questions?
Bonne chance!
Wesley
la source