Essayez de garder cela aussi simple que possible et les interfaces bien définies et documentées. La maintenance et le débogage d'un système complexe en production se transforment facilement en enfer. Donc, s'il existe une approche simple et complexe, réfléchissez-y à deux fois avant de vous lancer dans l'approche complexe.
Définition des services
Je pense que la première étape consiste à identifier les services et leurs dépendances : contenu statique, authentification, chat local, canaux de chat global, canaux de chat régionaux, liste d'amis, guildes, sac / inventaire, salle des ventes, carte globale, monde, ...
Ensuite, pour chacun de ces services, il a été décidé si le client pouvait leur parler directement. Par exemple, il est assez facile de laisser le client parler directement avec les serveurs responsables des canaux de discussion globaux. Les serveurs mondiaux n'ont pas du tout besoin d'être impliqués dans les messages de chat. Le chat régional peut être implémenté de la même manière, mais les serveurs mondiaux doivent avertir les serveurs de chat lorsque les joueurs changent de région. Encore une fois, ils n'ont pas à se soucier des messages.
La troisième étape consiste à penser à l'équilibrage de charge au sein d'un service . Par exemple, les canaux de discussion mondiaux et régionaux peuvent être répartis sur plusieurs serveurs en fonction de leur nom. C'est probablement une bonne idée de ne pas coder en dur cette division dans le client, mais de fournir un service de recherche.
Serveurs du monde
La partie la plus difficile est généralement les serveurs mondiaux , donc je commence par une approche simple. C'est probablement une bonne idée de laisser le client parler directement au serveur responsable de la région dans laquelle il se trouve. Ainsi, lors de la connexion ou de la région traversée, le client doit être informé du serveur auquel se connecter.
L'approche simple consiste à diviser le monde en régions indépendantes . Avec des régions indépendantes, je veux dire qu'un joueur ne peut pas regarder d'une partie à une autre et que les monstres ne peuvent pas traverser de parties. Ces régions sont différentes des régions que les joueurs voient en fonction du paysage et de l'histoire du monde extérieur. Habituellement, la plupart des monstres sont dans des donjons et les joueurs ont tendance à accepter qu'ils doivent passer par une passerelle pour entrer dans un donjon. Surtout si ces donjons sont instanciés par groupe de joueurs. D'autres exemples sur le monde extérieur sont différents continents et vallées entourées de hautes montagnes.
Une approche mondiale continue devient très rapidement complexe, il est donc logique de bien la planifier: de quelles informations le client a-t-il besoin? Quelles informations les serveurs doivent-ils partager? Le joueur n'interagira principalement qu'avec les objets (y compris les monstres et les PNJ) de la même région. Vous pouvez tricher en plaçant des objets hors de portée de clic à partir de la bordure de la zone. Cela signifie que le client est principalement intéressé par la lecture seule des informations pour les zones voisines. Dans ces cas, les serveurs de zone n'ont rien à coordonner, sauf pour vérifier l'autorisation que le joueur est suffisamment proche pour se connecter à une zone voisine.
Cela ne laisse qu'un très petit nombre de cas difficiles dans lesquels des objets ou des actions doivent traverser une frontière de serveur. Ce qui est une bonne chose car ces cas tels que les flèches et les sorts sont critiques pour les performances. Il peut être judicieux de diviser le combat en attaque et en défense. Ainsi, le serveur d'un lanceur de sorts définira les paramètres d'attaque, y compris la position du lanceur de sorts. Le serveur du défenseur recevra le message de l'attaque et calculera l'impact. Le serveur de l'attaquant n'a pas besoin de connaître l'impact; le client l'apprendra en utilisant sa connexion en lecture seule.
Selon la complexité de votre modèle de lecteur, le transfert vers un autre serveur peut prendre quelques secondes (Second Life a un énorme problème avec cela). Le problème peut être atténué en préparant le transfert à l'avance lorsque le joueur se rapproche d'une frontière virtuelle. De sorte que la plupart des données du lecteur sont déjà mises en cache sur le serveur de destination lorsque le transfert réel se produit.
Sommaire
Divisez le problème en définissant différents services qui peuvent être répartis sur plusieurs serveurs avec peu de dépendances. Au cours de la prochaine étape, examinez la façon d'équilibrer la charge au sein des services critiques. Déléguez le travail d'équilibrage au client en lui demandant de se connecter directement aux serveurs concernés (les serveurs doivent évidemment vérifier les autorisations). Restez aussi simple que possible, documentez bien les responsabilités des différents services et serveurs, offrez l'option d'activer la sortie de débogage.
PS: Certaines de ces techniques peuvent être utilisées pour améliorer la fiabilité. Et vous devez garder cela à l'esprit car l'utilisation de nombreux serveurs implique un risque beaucoup plus élevé de rupture des choses; non seulement au niveau du logiciel mais également au niveau du matériel.
Généralement, le monde est divisé en plusieurs petites régions. Chacune de ces régions est généralement un processus serveur indépendant (les serveurs mondiaux de WoW ou les nœuds Sol d'Eve) et peut s'exécuter sur n'importe quelle machine. Dans certains jeux, il y a des portes explicites entre les cartes (Eve, STO, Guild Wars) tandis que d'autres essaient de masquer cela davantage (WAR, Free Realms). Ceux qui optent pour l'approche plus transparente détectent généralement lorsque vous approchez de la frontière entre deux serveurs et que les deux processus négocient un transfert. Le meilleur endroit pour chercher probablement une description de cela est dans la façon dont les tours cellulaires effectuent les transferts de combinés mobiles. Si la charge d'une seule carte (Jita, Ironforge, Earth Space Dock) devient vraiment importante, vous pouvez parfois décharger des fonctions individuelles sur d'autres serveurs (AI, certaines parties de la gestion des joueurs), mais cela doit être intégré dès le départ ou nécessiterait une sérieuse rénovation. Il est presque toujours plus rentable d'acheter simplement un meilleur matériel à consacrer à ces quelques cartes.
la source
Ce n'est probablement pas aussi courant que vous le pensez; du moins, pas si vous pensez qu'un monde transparent est géré par plusieurs serveurs simultanément.
Sans compter les fragments totalement séparés, il y a 2 directions dans lesquelles vous pouvez diviser un jeu en ligne, qui pourrait être considéré comme "horizontal" et "vertical":
Évidemment, ces approches sont orthogonales et vous pouvez combiner les deux. En fait, il est presque obligatoire d'avoir un serveur de base de données séparé, très courant pour pousser la connexion / l'authentification sur une machine distincte du gameplay, et de plus en plus courant pour éliminer le chat et d'autres communications non critiques, quel que soit votre monde de jeu est divisé.
Mais dans l'ensemble, lorsqu'il y a partitionnement géographique, la plupart des jeux évitent de vous laisser interagir au-delà de ces frontières, car il est difficile de bien faire. Au lieu de cela, ils ont recours à d'autres façons de faire croire que vous êtes toujours dans le même fragment et sur le même serveur, alors qu'en réalité vous ne l'êtes pas. par exemple. - écrans de chargement ou autres animations qui masquent un changement de serveur lors de la transition entre les zones, ou d'un continent à l'autre. - des instances de donjon ou de raid séparées qui sont isolées de tout le monde. Celles-ci sont comme un fragment dans un fragment et peuvent facilement être exécutées sur un serveur distinct, ce qui facilite l'équilibrage de charge.
Je ne peux pas parler avec autorité sur WoW, mais je suppose qu'ils font presque tout ce qui précède: instanciation, zones géographiques distinctes qui ne peuvent pas interagir reliées par des portails d'une certaine sorte, serveurs d'arrière-plan et d'authentification séparés. J'ai entendu dire que les royaumes WoW ont entre 1000 et 10000 joueurs en ligne dans un royaume donné à la fois, ce qui est facilement gérable avec les schémas ci-dessus.
Mais, supposons que vous ayez un seul monde massif et que vous devez autoriser les joueurs un serveur à interagir avec les joueurs sur un serveur adjacent. Ceci est facile à faire en théorie - d'abord, les serveurs doivent coopérer pour partager les détails des objets le long des frontières (donc un objet sur un serveur peut avoir une représentation proxy sur un autre), puis changez simplement toute votre logique en passant des messages, avec si nécessaire, les messages sont acheminés d'un proxy vers la source faisant autorité. Les messages peuvent être transmis entre les serveurs ou au sein d'un serveur de manière assez transparente afin qu'une approche s'adapte à tous les systèmes.
Le problème ici est qu'une logique auparavant simple peut devenir très complexe lorsqu'elle est traduite en messages - par exemple. un échange à 2 joueurs qui peut se produire en toute sécurité et de manière atomique lorsque les deux joueurs sont sur un serveur devient un processus plus long lorsque des messages doivent être envoyés dans les deux sens, revérifiés à chaque envoi et des garanties mises en place pour garantir qu'un joueur ne peut pas exploiter l'autre en changeant de métier pendant qu'un message voyage. Vous ne pouvez même pas supposer que l'autre joueur existera toujours au moment où le message arrivera (car ils pourraient mourir, se déconnecter, etc.), donc le code devient très complexe. Et cela s'appliquera à presque tous les systèmes où 2 ou plusieurs entités peuvent interagir ou coopérer - commerce, combat, groupement, enchères, partage de butin, formation, etc.
Ces problèmes ne sont pas insurmontables, mais pour la plupart des jeux, ils sont trop difficiles à valoir lorsque vous pouvez partager la charge via les autres moyens et conserver toute votre logique de jeu sur un seul serveur. Donc, presque tous les jeux actuels suivent cette voie.
la source
Il existe de nombreuses méthodes d'équilibrage de charge d'un serveur MMO, car il existe un large éventail de données à traiter. Je préfère la méthode d'arborescence de processus bin.
Un serveur global transmet les connexions utilisateur à un bac de processus qui peut gérer plusieurs utilisateurs à la fois. les bacs de processus effectuent tous les traitements complexes et ne répondent au serveur global qu'avec des données pertinentes au niveau mondial telles que le chat et le positionnement global. Cette méthode s'équilibre beaucoup mieux que les serveurs de régions, car les régions peuvent varier considérablement en population, tandis que le traitement global des utilisateurs est suffisamment varié pour s'équilibrer naturellement pour la plupart.
Effectuez simplement un équilibrage de charge de base via le serveur global. Ainsi, lorsqu'un bac de processus atteint une certaine utilisation de mémoire / processeur, vous démarrez un nouveau serveur de bac de processus.
la source