Como balancear carga entre múltiplos GameServers no MU Online
Distribua seus jogadores entre vários GameServers para suportar mais players simultâneos, reduzir lag e evitar que um único processo trave o servidor inteiro.
Quando um servidor de MU Online cresce, chega o momento em que um único GameServer não dá conta. O processo começa a consumir CPU perto do limite, o ping sobe nos horários de pico, eventos lotados geram engasgos e, no pior caso, um travamento derruba todos os jogadores de uma vez. A resposta de infr
Quando um servidor de MU Online cresce, chega o momento em que um único GameServer não dá conta. O processo começa a consumir CPU perto do limite, o ping sobe nos horários de pico, eventos lotados geram engasgos e, no pior caso, um travamento derruba todos os jogadores de uma vez. A resposta de infraestrutura para isso é distribuir a carga entre múltiplos GameServers — vários processos de jogo, cada um cuidando de uma fatia dos jogadores, coordenados pelos servidores de login e conectados ao mesmo banco de dados.
Balancear carga no MU não é como balancear um site HTTP, onde um load balancer distribui requisições soltas. Aqui, cada conexão de jogador é stateful: o jogador escolhe um canal (subservidor), entra nele e permanece ali durante a sessão. O "balanceamento" acontece principalmente no momento da escolha do servidor e na forma como você organiza canais, mapas e eventos. Este tutorial mostra os modelos reais de distribuição, como configurar múltiplos GameServers, como direcionar jogadores de forma equilibrada e como monitorar para saber quando escalar. Portas, IPs e limites são exemplos e variam por provedor/versão do seu emulador.
Por que balancear e o que exatamente se distribui
O objetivo é evitar o ponto único de saturação e o ponto único de falha. Ao dividir os jogadores em vários processos, você ganha três coisas: mais capacidade total, isolamento de falhas (se um canal cai, os outros seguem) e melhor uso de CPU multi-core, já que cada GameServer normalmente é limitado por poucos núcleos.
O que se distribui não é uma requisição, e sim a presença do jogador. Existem modelos diferentes:
| Modelo | Como distribui | Vantagem | Cuidado |
|---|---|---|---|
| Canais espelhados | Vários servidores idênticos (Sub 1, Sub 2...) | Jogador escolhe onde entrar; simples | Personagens precisam ser globais no banco |
| Mapas dedicados | Cada servidor cuida de mapas específicos | Menos carga por processo | Transição entre mapas fica mais complexa |
| Eventos isolados | Um servidor só para eventos pesados | Evento não trava o jogo normal | Requer coordenação de agendamento |
| Híbrido | Combina canais + servidor de evento | Flexível, escala bem | Mais partes móveis para gerenciar |
O modelo de canais espelhados é o mais comum e o mais didático, então ele guia este tutorial, com notas sobre os demais.
Pré-requisitos
Antes de começar:
- Um servidor de MU funcional com ConnectServer, JoinServer, DataServer e ao menos um GameServer estáveis. Se ainda está montando a base, comece por como criar servidor de MU Online.
- Banco de dados centralizado acessível por todos os GameServers. O balanceamento pressupõe que todos os processos leem e escrevem o mesmo banco de contas e personagens.
- Hardware com folga: para rodar N GameServers na mesma máquina, some a RAM e a CPU que cada um consome. Exemplo de referência: reservar de 1 a 2 núcleos e alguns GB de RAM por GameServer ativo (varia por versão e por população).
- Acesso aos arquivos de configuração: ServerList do ConnectServer, GameServerInfo de cada GameServer, e as configs de porta e código de servidor.
- Uma ferramenta de monitoramento (mesmo que básica) para CPU, RAM, rede e contagem de jogadores por canal.
Deixe planejado o esquema de portas e códigos. Cada GameServer precisa de um código único (ServerCode) e de uma porta única se estiver na mesma máquina. Anote isso numa tabela antes de configurar.
Passo 1 — Planejar o esquema de canais
Antes de tocar em qualquer arquivo, desenhe a topologia. Decida quantos canais, com quais códigos e portas, e em quais máquinas. Um exemplo de planejamento para três canais na mesma máquina:
| Canal | ServerCode | Porta | Máquina | Limite de players (exemplo) |
|---|---|---|---|---|
| Sub 1 | 0 | 55901 | GameHost A | 400 |
| Sub 2 | 1 | 55902 | GameHost A | 400 |
| Sub 3 | 2 | 55903 | GameHost A | 400 |
Se for distribuir em máquinas diferentes, o IP muda também. Os limites de players por canal são exemplos; o número real depende do que seu hardware e emulador aguentam sem lag, então valide na prática.
O ponto crítico do planejamento: códigos e portas nunca se repetem. Código duplicado confunde o ConnectServer e o JoinServer; porta duplicada na mesma máquina impede o segundo processo de subir.
Passo 2 — Configurar o DataServer/JoinServer para múltiplos canais
Os servidores de coordenação — DataServer (acesso ao banco) e JoinServer (autenticação/entrada) — precisam saber que existirão vários GameServers. Em geral eles são centralizados e únicos: um DataServer e um JoinServer atendem todos os canais. O que muda é que cada GameServer aponta para esse mesmo par.
Verifique nas configs:
- O DataServer está configurado para aceitar conexões de todos os GameServers (por IP/porta interna).
- O JoinServer conhece o mesmo conjunto de servidores e coordena a entrada.
- As portas internas de comunicação entre GameServer e Data/Join estão liberadas no firewall entre as máquinas, se forem separadas.
Como esses componentes e nomes de arquivo variam bastante entre emuladores (Season 6, versões mais novas, forks específicos), localize o equivalente na sua distribuição. O princípio é constante: coordenação central, jogo distribuído.
Passo 3 — Duplicar e configurar cada GameServer
Agora você cria os processos de jogo. Na abordagem de mesma máquina, isso costuma ser feito copiando a pasta do GameServer e ajustando a configuração de cada cópia.
Para cada GameServer:
- Copie a pasta do GameServer para uma nova (ex.:
GameServer_Sub2). - Ajuste o ServerCode para o valor único planejado.
- Ajuste a porta de escuta para a porta única.
- Confirme que ele aponta para o mesmo DataServer/JoinServer e o mesmo banco.
- Ajuste, se necessário, o nome/título do canal exibido.
Um trecho ilustrativo de configuração de um GameServer (o formato varia por emulador):
[GameServerInfo]
ServerName = Sub 2
ServerCode = 1
GamePort = 55902
DataServerIP = 10.0.0.30
JoinServerIP = 10.0.0.30
; aponta para o mesmo banco central via DataServer
Repita para cada canal, mudando ServerName, ServerCode e GamePort. Suba os processos um a um e confira nos logs que cada um conecta ao DataServer sem erro.
Passo 4 — Registrar os canais na ServerList do ConnectServer
O ConnectServer é quem apresenta a lista de servidores ao jogador. Cada canal precisa aparecer ali com o endereço correto — que, se você usa proxy para esconder o IP, deve ser o IP do proxy com a porta de cada canal.
Um exemplo de entrada na ServerList:
; Formato ilustrativo — varia por emulador
ServerCode ServerName IP Port
0 Sub 1 191.0.0.10 55901
1 Sub 2 191.0.0.10 55902
2 Sub 3 191.0.0.10 55903
Aqui 191.0.0.10 é um IP público de exemplo (idealmente o do proxy). O jogador verá três canais e escolherá um. É nesse momento de escolha que o balanceamento efetivamente acontece.
Passo 5 — Distribuir os jogadores de forma equilibrada
Como cada jogador escolhe o canal, o balanceamento depende de indução, não de imposição. Técnicas reais:
- Percentual de lotação visível: o MU costuma mostrar a ocupação de cada canal (barra ou porcentagem). Jogadores tendem a evitar canais cheios, o que gera um balanceamento natural. Garanta que esse indicador esteja funcionando.
- Limite de conexões por canal: configure o máximo de players por GameServer para que, ao lotar, novos jogadores sejam empurrados a outros canais.
- Ordem e nomeação: nomear canais de forma neutra (Sub 1, Sub 2...) evita que todos corram para o "principal".
- Incentivos suaves: alguns administradores dão pequenos bônus rotativos por canal para espalhar a população, mas isso é opcional e varia por servidor.
Evite forçar o jogador ao canal errado para o seu grupo, pois grupos e guildas querem estar juntos. O equilíbrio ideal deixa espaço para escolha e ainda assim distribui a carga.
Passo 6 — Isolar eventos pesados
Eventos como invasões, Blood Castle, Chaos Castle e Castle Siege concentram muitos jogadores e cálculos ao mesmo tempo, e são os maiores causadores de picos de CPU. Uma estratégia poderosa é isolar eventos em um GameServer dedicado ou distribuir os horários.
Opções:
- Servidor de evento dedicado: um canal reservado aos eventos mais pesados, para que o lag do evento não afete o jogo normal.
- Escalonamento de horários: evitar que vários eventos pesados rodem no mesmo minuto em todos os canais, distribuindo os agendamentos.
- Limitar participantes por instância de evento, quando o emulador permite.
Isso reduz o pior caso de carga, que geralmente é o que define o dimensionamento do hardware.
Passo 7 — Monitorar e decidir quando escalar
Balancear sem medir é chutar. Monitore por canal e no total:
| Métrica | O que observar | Sinal de que precisa escalar |
|---|---|---|
| CPU por processo | Uso de cada GameServer | Perto do limite de núcleo em horário normal |
| RAM total | Soma de todos os processos | Uso alto com pouca folga |
| Players por canal | Distribuição da população | Canais cronicamente lotados |
| Latência | Ping médio dos jogadores | Sobe em pico mesmo fora de evento |
| Rede | Banda de entrada/saída | Saturação do link |
Quando um canal vive lotado e a CPU trabalha alto fora de evento, é hora de adicionar mais um GameServer (novo código, nova porta, nova entrada na ServerList) ou de mover canais para outra máquina. A vantagem da arquitetura distribuída é que essa expansão costuma ser feita sem derrubar os canais existentes.
Passo 8 — Escalar horizontalmente para outra máquina
Quando uma máquina satura, a próxima etapa é colocar GameServers em uma segunda máquina, apontando para o mesmo DataServer/JoinServer e banco. Requisitos:
- Baixa latência de rede entre as máquinas e o banco (idealmente rede privada na mesma região).
- Firewall liberando as portas internas de comunicação entre GameServer e Data/Join só entre as máquinas.
- Códigos e portas ainda únicos no conjunto todo, mesmo em máquinas diferentes.
Assim você deixa de escalar verticalmente (uma máquina cada vez maior) e passa a escalar horizontalmente (mais máquinas), que é como servidores grandes de MU sustentam milhares de jogadores.
Erros comuns e soluções
| Erro | Sintoma | Solução |
|---|---|---|
| Códigos de servidor duplicados | Canais se confundem ou não aparecem | Garantir ServerCode único por GameServer |
| Portas repetidas na mesma máquina | Segundo processo não sobe | Atribuir porta única a cada canal |
| GameServer aponta para banco errado | Personagens somem ou divergem | Todos os canais no mesmo DataServer/banco central |
| Indicador de lotação quebrado | Todos entram no mesmo canal | Corrigir a contagem de players exibida |
| Evento em todos os canais ao mesmo tempo | Pico de CPU generalizado | Escalonar horários ou isolar eventos |
| Rede lenta até o banco | Lag em máquinas remotas | Rede privada e baixa latência com o DataServer |
| Sem limite por canal | Um canal lota e trava | Definir máximo de players por GameServer |
Checklist de lançamento
- Topologia de canais planejada (código, porta, máquina, limite)
- ServerCodes únicos em todo o conjunto
- Portas únicas por máquina
- DataServer e JoinServer centralizados e acessíveis por todos os canais
- Cada GameServer configurado e conectando ao banco central
- Todos os canais registrados na ServerList do ConnectServer
- Endereços anunciados corretos (IP do proxy, se houver)
- Indicador de lotação por canal funcionando
- Limite de players por canal definido
- Estratégia de isolamento de eventos pesados aplicada
- Monitoramento de CPU, RAM, players e latência ativo
- Firewall entre máquinas liberando só as portas internas necessárias
- Plano de adicionar novo GameServer sem downtime documentado
Conclusão
Balancear carga no MU Online é, no fundo, uma questão de organização: dividir a população em canais bem planejados, coordená-los por um núcleo central de login e banco, e induzir os jogadores a se espalharem em vez de amontoarem tudo em um processo. Quando bem feito, você suporta muito mais players simultâneos, isola falhas para que um canal problemático não derrube o servidor inteiro e ganha um caminho claro de crescimento — basta acrescentar canais e, depois, máquinas. Trate os códigos, portas e limites deste guia como exemplos e ajuste à sua Season, mas mantenha a disciplina de unicidade, coordenação central e monitoramento constante. É assim que um servidor deixa de ser um hobby frágil e passa a aguentar uma comunidade de verdade.
Perguntas frequentes
Quantos jogadores um GameServer aguenta?
Depende do emulador, do hardware e da quantidade de eventos ativos. Um valor de referência comum é algumas centenas por processo, mas isso varia muito por versão e configuração.
Preciso de várias máquinas para ter vários GameServers?
Não necessariamente. Você pode rodar vários GameServers na mesma máquina se ela tiver CPU e RAM suficientes, ou distribuí-los em máquinas diferentes para escalar mais.
Os personagens ficam presos a um GameServer específico?
Depende da arquitetura. Em muitos emuladores os personagens são globais no banco e podem entrar em qualquer canal; em outros há mapas dedicados por servidor. Confirme na sua versão.
Load balancing resolve lag de CPU?
Ajuda ao dividir a carga entre processos e núcleos, mas não conserta código ineficiente nem consultas lentas de banco. Balancear é parte da solução, não a solução inteira.
Posso adicionar GameServers com o servidor no ar?
Sim, geralmente adicionar um novo canal na ServerList e subir o processo é possível sem derrubar os demais, desde que o banco e o JoinServer suportem a nova instância.