O maior portal de MU Online do Brasil — desde 2003
Tutorial Avançado Servidor

Como automatizar testes de carga no GameServer do seu servidor de MU Online

Monte um pipeline de testes de carga que simula centenas de conexões simultâneas no ConnectServer e GameServer do seu servidor de MU Online, medindo latência, uso de CPU/memória e o limite real antes do lançamento.

RO Rodrigo · Atualizado em 28 set 2017 · ⏱ 17 min de leitura
Resposta rápida

Lançar um servidor de MU Online sem saber quantos jogadores simultâneos ele realmente suporta é uma aposta às cegas: o primeiro dia de divulgação, quando mais gente tenta entrar ao mesmo tempo, é justamente o pior momento para descobrir que o ConnectServer trava em 200 conexões ou que o banco de dad

Lançar um servidor de MU Online sem saber quantos jogadores simultâneos ele realmente suporta é uma aposta às cegas: o primeiro dia de divulgação, quando mais gente tenta entrar ao mesmo tempo, é justamente o pior momento para descobrir que o ConnectServer trava em 200 conexões ou que o banco de dados satura o pool antes do esperado. Este tutorial mostra como montar um pipeline de teste de carga automatizado, simulando conexões e ações simultâneas no ConnectServer e GameServer, medindo os indicadores certos e identificando o limite real do seu ambiente antes que os jogadores o façam por você.

Por que testar carga antes do lançamento

Divulgação bem-sucedida (grupos, YouTube, Discord parceiros) costuma gerar um pico de acessos concentrado nas primeiras horas após o lançamento — muito acima da média que o servidor vai sustentar depois. Se o ambiente quebra nesse pico, a primeira impressão dos jogadores é péssima e boa parte não volta a tentar. Testar a carga com antecedência permite corrigir gargalos (configuração de banco, hardware subdimensionado, limite de conexões do SO) enquanto ainda não há jogadores reais em risco.

Diferenciando os tipos de teste

Nem todo teste de carga precisa simular o jogo inteiro. Dividir por camada facilita isolar onde está o gargalo:

Tipo de testeO que simulaFerramenta típica
Teste de conexão (login)Centenas de handshakes simultâneos no ConnectServerScript próprio (Python/C#) emulando o protocolo
Teste de autenticaçãoLogin + seleção de personagem no GameServerScript com o protocolo de login do emulador
Teste de gameplayMovimento, ataque, troca de mapa, uso de NPCBots que jogam de fato (mais custoso)
Teste de banco de dadosConcorrência de leitura/escrita em MEMB_INFO, Charactersysbench ou script SQL direto
Teste de rede/infraBanda, latência, pacotes perdidosiperf3, monitoramento de interface

Preparando o ambiente de staging

Nunca rode o teste de carga contra o banco/servidor de produção — o risco de corromper dados reais ou derrubar o servidor durante divulgação é alto demais. Clone a configuração (mesmas versões de emulador, mesma configuração de banco, hardware o mais parecido possível) em um ambiente isolado, com dados de teste sintéticos:

CREATE DATABASE mu_staging;
-- Restaure um dump limpo/sintético, nunca dados reais de jogadores

Simulando conexões no ConnectServer

O ConnectServer é o primeiro gargalo em um pico de acesso — ele resolve qual GameServer o cliente deve usar e mantém uma fila de conexões. Um script simples em Python, usando sockets crus, pode simular centenas de handshakes:

import socket
import threading
import time

def simular_conexao(host, porta, resultados, i):
    inicio = time.time()
    try:
        s = socket.create_connection((host, porta), timeout=5)
        s.close()
        resultados.append(time.time() - inicio)
    except Exception as e:
        resultados.append(None)

resultados = []
threads = []
for i in range(500):
    t = threading.Thread(target=simular_conexao, args=("staging.meuservidor.com", 44405, resultados, i))
    threads.append(t)
    t.start()
    time.sleep(0.01)  # espaça levemente para simular chegada gradual

for t in threads:
    t.join()

sucesso = [r for r in resultados if r is not None]
print(f"Conexões bem-sucedidas: {len(sucesso)}/{len(resultados)}")
print(f"Latência média: {sum(sucesso)/len(sucesso):.3f}s")

Esse teste básico já revela se o ConnectServer aceita as conexões rapidamente ou começa a enfileirar/recusar acima de determinado volume.

Simulando o fluxo de login completo

Para medir o gargalo real de autenticação (que envolve consulta ao banco de contas), é preciso emular o protocolo de pacotes do seu emulador — a estrutura varia entre IGCN, MuEMU e X-Team, mas o princípio é o mesmo: montar o pacote de login binário e ler a resposta:

import struct

def montar_pacote_login(conta, senha):
    # Estrutura simplificada — ajuste aos offsets reais do seu emulador
    corpo = conta.encode('ascii').ljust(10, b'\x00') + senha.encode('ascii').ljust(10, b'\x00')
    tamanho = len(corpo) + 4
    return struct.pack('BBB', 0xC1, tamanho, 0xF1) + corpo

Rodar esse pacote de forma concorrente contra o GameServer de staging, medindo o tempo até a resposta de sucesso/falha, mostra a real capacidade de autenticação simultânea — geralmente o gargalo aparece primeiro aqui, não na conexão TCP em si.

Testando concorrência no banco de dados

Independente do teste de rede, o banco de dados costuma ser o limite real de escala. Use o sysbench para simular carga de leitura/escrita equivalente ao padrão de acesso do servidor (muitas leituras de personagem, poucas escritas de posição a cada poucos segundos):

sysbench oltp_read_write \
  --db-driver=mysql --mysql-db=mu_staging \
  --mysql-user=teste --mysql-password=senha \
  --tables=10 --table-size=100000 \
  --threads=200 --time=120 \
  run

Compare os resultados de latência (p95, p99) do sysbench com o número de jogadores simultâneos esperado — se o p99 já degrada com 200 threads simuladas e sua meta é 500 CCU, o banco (não o GameServer) é o gargalo a resolver primeiro.

Monitorando recursos durante o teste

Enquanto o teste roda, colete métricas de sistema em paralelo para correlacionar carga com consumo de recurso:

# Em uma janela separada, durante todo o teste:
top -b -n 100 -d 5 | grep -E "GameServer|ConnectServer|mysqld" >> /tmp/monitor_carga.log
vmstat 5 100 >> /tmp/monitor_carga.log
MétricaFerramentaO que indica
CPU do processo GameServertop/htopGargalo de processamento de lógica de jogo
Memória residentetop/psVazamento de memória sob carga prolongada
Conexões ativas no MySQLSHOW PROCESSLIST;Saturação de pool de conexões
Latência de discoiostat -x 5Gargalo de I/O em bancos grandes
Pacotes perdidos/latência de redeiperf3, ping -fLimite de banda ou configuração de rede

Definindo os cenários de teste (rampa gradual)

Em vez de disparar todos os "jogadores simulados" de uma vez (o que não reflete o padrão real de chegada), estruture o teste em rampa — aumentando a carga gradualmente e observando em que ponto cada métrica começa a degradar:

FaseCCU simuladoDuraçãoObjetivo
Aquecimento502 minConfirmar baseline sem carga
Rampa 11505 minMeta mínima de lançamento
Rampa 23005 minMeta esperada de pico
Rampa 35005 minEstresse acima da meta (margem de segurança)
Rampa 4700+até quebrarIdentificar o ponto de ruptura real

Automatizando a execução do pipeline completo

Um script orquestrador simples encadeia as etapas e salva os resultados com timestamp, para comparar execuções ao longo do tempo (ex.: antes e depois de uma otimização de configuração):

#!/bin/bash
DATA=$(date +%F_%H%M)
mkdir -p /tests/$DATA

python3 teste_conexao.py > /tests/$DATA/conexao.log &
sysbench oltp_read_write --threads=200 --time=300 run > /tests/$DATA/banco.log &
top -b -d 5 -n 60 > /tests/$DATA/recursos.log &

wait
echo "Teste de carga $DATA concluído. Resultados em /tests/$DATA/"

Interpretando os resultados e agindo sobre eles

O objetivo final não é só gerar números, é decidir ações concretas. Um resultado típico de análise:

  • Se a latência de login degrada antes da CPU do GameServer saturar, o gargalo é o pool de conexões do banco — aumente max_connections no MySQL/MSSQL e ajuste o pool do emulador.
  • Se a CPU do GameServer satura primeiro, o hardware está subdimensionado para a meta de CCU — considere upgrade de vCPU ou otimização de lógica de eventos que rodam em loop.
  • Se a rede degrada com poucas centenas de conexões, o link contratado pode ser insuficiente para o volume esperado — revise o plano com o provedor.

Erros comuns e soluções

SintomaCausa provávelSolução
Teste derruba o ambiente de staging rapidamenteRampa muito agressiva desde o inícioUse rampa gradual (50 → 150 → 300 → 500)
Resultados não são reprodutíveisAmbiente de staging com hardware diferente da produçãoAlinhe specs de CPU/RAM/disco entre staging e produção
Latência alta mas CPU/memória OKGargalo de banco de dados (pool ou índice)Rode sysbench isolado e revise SHOW PROCESSLIST
Script de simulação trava com erro de socketLimite de conexões do SO (ulimit) atingido no cliente do testeAumente ulimit -n na máquina que gera a carga
Teste não revela nada de útilMétricas de sistema não coletadas durante a execuçãoRode top/vmstat/iostat em paralelo, sempre
Produção quebra mesmo após teste "aprovado"Teste rodou só a camada de conexão, não gameplay realComplemente com teste de bots simulando ações reais

Checklist de teste de carga

  • Ambiente de staging isolado, com specs equivalentes à produção.
  • Script de simulação de conexão no ConnectServer funcionando.
  • Script de simulação de login/autenticação testado.
  • Teste de concorrência de banco (sysbench) executado e analisado.
  • Monitoramento de CPU, memória, conexões e disco coletado durante o teste.
  • Rampa gradual de carga executada até identificar o ponto de ruptura.
  • Ações corretivas definidas com base nos gargalos encontrados.
  • Reteste realizado após ajustes para confirmar melhoria.

Com o limite real do seu ambiente mapeado antes do lançamento, você troca surpresas de produção por decisões de dimensionamento tomadas com dados. Se a base do seu servidor ainda está em configuração inicial, comece pelo tutorial de criação de servidor de MU Online antes de investir tempo em testes de carga avançados.

Perguntas frequentes

Preciso de bots reais logando no jogo, ou dá para simular só o protocolo?

Para testes de carga de conexão (ConnectServer e login), simular o protocolo de rede diretamente com um script é mais eficiente e escalável do que abrir centenas de clientes reais. Para testar comportamento de gameplay (movimento, combate, drop), bots que emulam o protocolo do GameServer são necessários, mas ainda assim mais leves que o cliente completo.

Quantos jogadores simultâneos devo simular no teste?

Comece pela meta realista de lançamento (ex.: 300 CCU) e vá além dela em 50-100% para descobrir a margem de segurança real. Se seu objetivo é 300 online, teste até 450-600 para saber onde o sistema realmente quebra.

O teste de carga pode ser feito no servidor de produção?

Não é recomendado. Use um ambiente de staging com hardware e configuração o mais parecidos possível do de produção. Testar em produção arrisca corromper dados reais de jogadores ou causar uma queda visível durante o teste.

O que exatamente devo medir durante o teste?

No mínimo: uso de CPU e memória do processo do GameServer/ConnectServer, tempo de resposta de login, tempo de resposta de troca de mapa, número de pacotes perdidos/latência de rede e uso de conexões do banco de dados.

Depois do teste, o que fazer com os resultados?

Documente o ponto exato onde a performance degrada (ex.: 'acima de 400 CCU a latência de troca de mapa passa de 2s') e use isso para dimensionar hardware, ajustar configurações do banco (pool de conexões) ou definir um limite de fila de entrada (login queue) antes do lançamento oficial.

RO
Fundador e editor-chefe

Rodrigo mantém o ViciadosMU desde os primórdios do portal. Especialista em criação e administração de servidores de MU Online, história do jogo e a evolução das seasons — escreveu boa parte do acervo antes de 2024.

Continue lendo

Artigos relacionados