Ao desenvolver um sistema de servidor, para se adaptar a solicitações de dados grandes e simultâneas, geralmente precisamos armazenar os dados de forma assíncrona, especialmente ao trabalhar em um sistema distribuído. Neste momento, não podemos esperar que o banco de dados de inserção retorne o ID automático a ser recuperado. Em vez disso, precisamos gerar um ID exclusivo global antes de inserir o banco de dados, usando o ID exclusivo global. No servidor de jogo, o ID exclusivo global pode ser usado para futuras combinações de servidores e não haverá conflitos importantes. No futuro, no caso de crescimento dos negócios, o banco de dados e a tabela dividida podem ser implementados. Por exemplo, os itens de um usuário devem ser colocados no mesmo fragmento, e esse fragmento pode ser determinado com base no valor do intervalo do ID do usuário, como um ID de usuário com um ID de usuário superior a 1000 e menos de 100000 em um Shard. Atualmente, os seguintes são comumente usados:
1. O próprio Uuid de Java.
Uuid.randomuuid (). ToString () pode ser gerado localmente através do programa de serviço, e a geração de ID não depende da implementação do banco de dados.
Vantagens:
Gere ID localmente e não requer chamadas remotas.
O mundo é o único que não se repete.
A capacidade de expansão horizontal é muito boa.
Desvantagens:
O ID possui 128 bits, que ocupa um grande espaço e precisa ser armazenado como um tipo de string, e a eficiência da indexação é extremamente baixa.
O ID gerado não contém registro de data e hora e a tendência não pode ser garantida para aumentar. É difícil confiar ao dividir bancos de dados do banco de dados.
2. Método de incurt baseado em Redis
O próprio Redis é operado com um thread único e o AUnc garante uma operação atomicamente incrementada. Ele também suporta definir o tamanho da etapa incremental.
Vantagens:
É fácil de implantar e fácil de usar. Você só precisa chamar uma API Redis.
Vários servidores podem compartilhar um serviço Redis para reduzir o tempo de desenvolvimento dos dados compartilhados.
Redis pode ser implantado em clusters para resolver o problema do ponto único de falha.
Desvantagens:
Se o sistema for muito grande, vários serviços solicitam a Redis ao mesmo tempo causarão gargalos de desempenho.
3. Solução de Flicker
Esta solução é baseada no ID de incremento automático do banco de dados, que usa um banco de dados separado especificamente para gerar IDs. Você pode encontrar os detalhes online. Pessoalmente, acho que é bastante problemático usar e não é recomendável usá -lo.
4. Twitter Snowflake
O Snowflake é um algoritmo de geração de identificação distribuído que é de código aberto no Twitter. Sua idéia principal é gerar um ID do tipo longo, usando 41 bits como número de milissegundos, 10 bits como número da máquina e 12 bits como número de série em milissegundos. Esse algoritmo pode teoricamente gerar até 1.000*(2^12) IDs por segundo por máquina, que é de cerca de 400W, que podem atender completamente às necessidades do negócio.
De acordo com a idéia do algoritmo de floco de neve, podemos gerar nossa própria identificação global com base em nossos cenários de negócios. Como o comprimento do tipo longo em Java é de 64 bits, o ID que projetamos precisa ser controlado em 64 bits.
Vantagens: alto desempenho, baixa latência; aplicação independente; ordenado pelo tempo.
Desvantagens: Desenvolvimento e implantação independentes são necessários.
Por exemplo, o ID que projetamos contém as seguintes informações:
| 41 bits: Timestamp | 3 bits: área | 10 bits: Número da máquina | 10 bits: Número de série |
Código Java que gera um ID exclusivo:
/*** Generador de identificação personalizado* Regras de geração de ID: ID até 64 bits ** | 41 bits: Timestamp (MS) | 3 bits: área (sala do computador) | 10 bits: Número da máquina | 10 bits: número de série |*/public classe gameuuid {// tempo de referência privado twepoch longo = 1288834974657l; // qui, 04 de novembro de 2010 01:42:54 gmt // sinalizadores de região dígitos privados final estático long regionIdbits = 3l; // Digits de identificação de máquina Digits privados final estático long WorkerIdBits = 10L; // Número serial Digits privado final estático final Valor máximo do ID da máquina privado final estático longo maxWorkerID = -1L ^ (-1L << WorkerIdBits); // Valor máximo do número de série ID private final estático estático longo RegionIdShift = sequenceBits + WorkerIdBits; // O tempo é deslocado para a esquerda por 23 bits privados final estático de tempo mais longo timestplefShift = sequencebits + workerIdBits + regiãoIDBits; estática privada Last TimeSTamp = -1L; Sequência longa privada = 0L; Private Final Long WorkerID; Região final privada de longa distância; public gameuuid (trabalhador longo, região longa) {// Se fora do alcance, uma exceção é lançada se (trabalhador> maxworkerid || trabalhador <0) {lança nova ilegalArgumentException ("Id do trabalhador não pode ser maior que %d ou menos que 0");} se (região> maxriGionId | Regionid <0) {menos de 0 ");} se (região> maxregionId | região) {menos de 0");} se (região que 0 ");} this.workerid = workerId; this.regionId = RegionId;} public gameuuid (long workerid) {// se fora do alcance for jogado se (trabalhador> maxworkerid || trabalhador <0) {lança novo ilegalArgumentException ("trabalhador não pode ser maior que %d ou menos que 0"); 0);}/*** O código real gerado por @param ispadding* @param busid* @return*/private sincronizado Long NextId (Ispadding booleano, Busid longo) {Long Timestamp = TimeGen (); Long PaddingNum = RegionId; if (isPadding) {Paddingnum = (BusId; para trás. A sequência é de apenas 10 bits, é combinada com o sequenceMask e remova a sequência de alto bit = (sequência + 1) e sequencemask; // julgam se ele transborda, ou seja, excede 1024 em cada milissegundo. When it is 1024, it is combined with sequenceMask, and sequence is equal to 0if (sequence == 0) {//Spin waits until the next millisecond timestamp = tailNextMillis(lastTimestamp);}} else {// If the sequence is different from the last generation time, reset the sequence, which starts in the next millisecond, and the sequence count starts from 0 again. // Para garantir que o Mantissa seja mais aleatório, defina um número aleatório na última sequência de bits = new SecureRandom (). NextInt (10);} LastTimeSTamp = Timestamp; Return ((Timestamp - Twepoch) << TIMESTAMPSUMPSHIFT) | (Paddingnum << RegionIdShift) | (WorkerID << WorkerIdShift) | sequência;} // impedem que o tempo de geração seja menor que o tempo anterior (devido a problemas como o retorno de chamada NTP) e mantenha a tendência incremental. Private Long TailnextMillis (Longtimestamp LongTamMamp) {Timestamp = theTestamp = theTimeGengen; timegen () {return system.currenttimemillis ();}}Algumas coisas a serem observadas ao usar métodos personalizados:
Para manter a tendência de crescimento, é necessário evitar o tempo de alguns servidores mais cedo e alguns servidores atrasados, para que o tempo de todos os servidores precise ser controlado e o tempo em que o servidor NTP Time liga de volta ao servidor é evitado; Ao atravessar milissegundos, o número de série sempre atinge 0, o que fará mais IDs com o número de série 0, resultando em IDs irregulares após o modulação, para que o número de série não pertence a 0 todas as vezes, mas um número aleatório de 0 a 9.
Podemos escolher os métodos mencionados acima de acordo com nossas necessidades. No desenvolvimento do servidor de jogos, você pode escolher de acordo com o seu próprio tipo de jogo, como jogos para celular, e pode usar o método Redis simples, que é simples e não fácil de cometer erros. Como o número de novos IDs criados por servidores únicos nesse tipo de jogo não é muito grande, ele pode atender completamente às necessidades. Para grandes servidores de jogos mundiais, eles são distribuídos principalmente, para que você possa usar o Snowflake. O código de floco de neve acima é apenas um exemplo e precisa ser personalizado de acordo com suas necessidades, para que haja volume adicional de desenvolvimento e você deve prestar atenção às precauções acima.
O exposto acima é um resumo dos métodos de uso do código Java para implementar o servidor de jogos para gerar um ID exclusivo global com base no código Java. Espero que seja útil para todos. Se você tiver alguma dúvida, deixe -me uma mensagem e o editor responderá a todos a tempo. Muito obrigado pelo seu apoio ao site wulin.com!