Lors du développement d'un système de serveur, afin de nous adapter aux demandes de données grandes et simultanées, nous devons souvent stocker les données de manière asynchrone, en particulier lorsque nous travaillons dans un système distribué. Pour le moment, nous ne pouvons pas attendre que la base de données d'insertion renvoie l'ID automatique à récupérer. Au lieu de cela, nous devons générer un ID unique global avant d'insérer la base de données, en utilisant l'ID unique global. Dans le serveur de jeux, l'ID unique mondial peut être utilisé pour les futures combinaisons de serveurs et il n'y aura pas de conflits clés. À l'avenir, en cas de croissance de l'entreprise, la base de données et la table partagée peuvent être implémentées. Par exemple, les éléments d'un utilisateur doivent être placés dans le même fragment, et ce rayon peut être déterminé en fonction de la valeur de plage de l'ID utilisateur, comme un ID utilisateur avec un ID utilisateur supérieur à 1000 et moins de 100000 dans un éclat. Actuellement, les éléments suivants sont couramment utilisés:
1. Java de l'UUID.
UUid.randomuuid (). ToString () peut être généré localement via le programme de service, et la génération d'ID ne dépend pas de l'implémentation de la base de données.
Avantages:
Générez l'ID localement et ne nécessite pas d'appels distants.
Le monde est le seul qui ne se répète pas.
La capacité d'expansion horizontale est très bonne.
Inconvénients:
L'ID a 128 bits, qui occupe un grand espace et doit être stocké sous forme de type de chaîne, et l'efficacité d'indexation est extrêmement faible.
L'ID généré ne contient pas d'horodatage et la tendance ne peut être garantie d'augmenter. Il est difficile de compter lors de la division des bases de données de base de données.
2. Méthode incr
Redis lui-même exploite un seul thread et augmente et augmente une opération atomiquement incrémentée. Il prend également en charge la définition de la taille incrémentielle de l'étape.
Avantages:
Il est facile à déployer et facile à utiliser. Il vous suffit d'appeler une API Redis.
Plusieurs serveurs peuvent partager un service Redis pour réduire le temps de développement des données partagées.
Redis peut être déployé en clusters pour résoudre le problème du point d'échec unique.
Inconvénients:
Si le système est trop grand, plusieurs services de service à Redis en même temps entraîneront des goulots d'étranglement de performances.
3. Solution de Flicker
Cette solution est basée sur l'ID d'incrémentation automatique de la base de données, qui utilise une base de données distincte spécifiquement pour générer des ID. Vous pouvez trouver les détails en ligne. Je pense personnellement qu'il est assez gênant à utiliser et il n'est pas recommandé de l'utiliser.
4. Twitter Snowflake
Snowflake est un algorithme de génération d'identité distribué qui est open source sur Twitter. Son idée principale est de générer un ID de type long, en utilisant 41bit comme nombre de millisecondes, 10 bits comme numéro de machine et 12 bits comme numéro de série en millisecondes. Cet algorithme peut théoriquement générer jusqu'à 1 000 * (2 ^ 12) IDS par seconde par machine, soit environ 400W, ce qui peut répondre pleinement aux besoins de l'entreprise.
Selon l'idée de l'algorithme Snowflake, nous pouvons générer notre propre ID unique mondial en fonction de nos scénarios commerciaux. Parce que la longueur du type long en Java est de 64bits, l'ID que nous avons conçu doit être contrôlé à 64bits.
Avantages: haute performance, faible latence; application indépendante; ordonné par le temps.
Inconvénients: le développement et le déploiement indépendants sont nécessaires.
Par exemple, l'ID que nous avons conçu contient les informations suivantes:
| 41 bits: horodatage | 3 bits: zone | 10 bits: numéro de machine | 10 bits: numéro de série |
Code Java qui génère un ID unique:
/ *** Générateur d'ID personnalisé * Règles de génération d'ID: ID jusqu'à 64 bits ** | 41 bits: horodatage (MS) | 3 bits: zone (salle informatique) | 10 bits: numéro de machine | 10 bits: Numéro de série | * / classe publique GameUUID {// Time de référence Long TwePoch = 1288834974657L; // Thu, 04 novembre 2010 01:42:54 GMT // Région FlagGits Private Private Final Static Long RegionIdBits = 3l; // Digits d'identification de la machine Final Final Long Workingbits = 10L; // Numéro de série Digits Final Final Static Long Sequence Bits = 10l; // Valeur maximum de la région ID de la région STATIQUE FINAL Long maxregionID = -1L ^ (-1L Valeur maximale de l'ID de machine privé final final long maxworkerid = -1l ^ (-1l << workingidBits); // valeur maximale de l'identifiant de numéro de série privé statique statique long Sequencemask = -1l ^ (-1l << SequenceBits); // L'ID de la machine est décalé 10 bits vers le service final privé à gauche de la longueur pour les séquences privés) RegionIdShift = SequenceBits + WorkingIdBits; // Le temps est décalé laissé par 23 bits privé final statique long timestampleftShift = SequenceBits + WorkIdbits + RegionIdBits; Private Static Long LastTimeStamp = -1L; séquence longue privée = 0l; Final Long WorkerID privé; final privé long régionid; GameUUID public (Long WorkerId, Long RegionId) {// Si hors de portée, une exception est lancée if (WorkerId> MaxWorkerid || WorkerId <0) {Throw New illégalArgumentException ("Worker Id ne peut pas être supérieur à% D ou moins que 0");} if (RegionId> MaxregionId || Régionid <0) {Throw New IllegalArgumentException ("DataConter ID de%) {ne peut-être pas entièrement illégala ou moins de 0 ");} this.workerid = workerId; this.regionId = RegionId;} public GameUuid (Long WorkerId) {// Si hors de portée est lancé if (WorkerId> MaxWorkerid || WorkerId <0) {Throw New IllégalArgumentException ("Worker Id ne peut pas être supérieur à% d ou moins que 0");} this.workerid = workerId; this.regionId = 0;} public Generate () {Retour. 0);} / *** le code réel généré par @param ispadding * @param busId * @ return * / private synchronisé long nextId (booléen ispadding, long busId) {long halestamp = timegen (); long paddingNum = RegionId; if (ispadding) {paddingnum = busid;} if (timestamp <nortimetim en arrière. est seulement 10 bits, il est combiné avec SequenceMask et supprime la séquence haut de gamme = (séquence + 1) & Sequencemask; // juger si elle déborde, c'est-à-dire qu'elle dépasse 1024 en chaque milliseconde. Lorsqu'il est 1024, il est combiné avec Sequencemask et la séquence est égale à 0if (séquence == 0) {// Spin Waits jusqu'à la prochaine milliseconde horlogéne = TailNextMillis (LastTimestamp);}} else {// Si la séquence est différente du dernier temps de génération, réinitialise la séquence, qui commence dans le prochain millionconde, et le comte de séquence recommence. // Afin de s'assurer que la mantissa est plus aléatoire, définissez un nombre aléatoire dans la dernière séquence de bit = new SecureRandom (). NextInt (10);} LastTimeStamp = TimeStamp; Return ((TimeStamp - TwePoch) << TimestampleftShift) | (PaddingNum << RegionIdShift) | (WorkerId << WorkerIdShift) | Séquence;} // Empêcher le temps de génération étant plus petit que la durée précédente (en raison de problèmes tels que le rappel NTP) et maintenir la tendance incrémentielle. TimeGen () {return System.currentTimemillis ();}}Certaines choses à noter lors de l'utilisation de méthodes personnalisées:
Afin de maintenir la tendance de croissance, il est nécessaire d'éviter le temps de certains serveurs tôt et de certains serveurs en retard, de sorte que le temps de tous les serveurs doit être contrôlé, et le moment où le serveur NTP Time rappelle sur le serveur est évité; Lors du passage des millisecondes, le numéro de série atteint toujours 0, ce qui fera plus d'ID avec le numéro de série 0, ce qui entraîne des ID inégaux après modulo, de sorte que le numéro de série n'appartient pas à 0 à chaque fois, mais un nombre aléatoire de 0 à 9.
Nous pouvons choisir les méthodes mentionnées ci-dessus selon nos besoins. Dans le développement du serveur de jeux, vous pouvez choisir en fonction de votre propre type de jeu, tel que les jeux mobiles, et vous pouvez utiliser la méthode Redis simple, qui est simple et pas facile à faire des erreurs. Étant donné que le nombre de nouveaux ID créés par des serveurs uniques dans ce type de jeu n'est pas trop grand, il peut répondre complètement aux besoins. Pour les grands serveurs de jeux mondiaux, ils sont principalement distribués, vous pouvez donc utiliser des flocons de neige. Le code de flocon de neige ci-dessus est juste un exemple et doit être personnalisé en fonction de vos besoins, il y a donc un volume de développement supplémentaire, et vous devez prêter attention aux précautions ci-dessus.
Ce qui précède est un résumé des méthodes d'utilisation du code Java pour implémenter le serveur de jeux pour générer un ID unique global basé sur le code Java. J'espère que ce sera utile à tout le monde. Si vous avez des questions, veuillez me laisser un message et l'éditeur répondra à tout le monde à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!