Cómo Configurar Sub-Servidores y Balanceo de Carga en tu Servidor MU
Aprende a configurar sub-servidores y balanceo de carga en tu servidor MU Online para soportar alta concurrencia de jugadores con máxima estabilidad.
Arquitectura de Sub-Servidores en MU Online
Un servidor de MU Online privado estándar está compuesto por varios procesos que cooperan entre sí: el ConnectServer, el JoinServer, uno o más procesos GameServer, el DataServer y servicios auxiliares como el EventServer y el CastleServer. La mayoría de las instalaciones iniciales utilizan un solo GameServer, lo que funciona bien para comunidades pequeñas pero se convierte en un cuello de botella a medida que la cantidad de jugadores concurrentes supera los doscientos o trescientos.
Los sub-servidores son instancias adicionales de GameServer que funcionan en paralelo al servidor principal. Desde la perspectiva del jugador, aparecen como canales separados en la pantalla de selección de servidor (por ejemplo, "Servidor 1 — Loto", "Servidor 2 — Vid"). El tráfico se distribuye entre ellos, reduciendo la carga sobre cada proceso individual y mejorando la capacidad de respuesta general del servidor.
El balanceo de carga en MU Online está gestionado principalmente por el componente JoinServer, que registra cuántos jugadores están conectados a cada GameServer y dirige las solicitudes de ingreso nuevas en consecuencia. Comprender cómo se interrelacionan estos componentes es esencial antes de realizar cualquier cambio en la configuración.
Planificación del Esquema de Sub-Servidores
Antes de editar cualquier archivo de configuración, planifica tu esquema con cuidado:
- ¿Cuántas instancias de GameServer necesitas? Estima tu pico de jugadores concurrentes esperado. Una instancia bien ajustada maneja entre 500 y 800 jugadores con comodidad. Dos instancias cubren hasta aproximadamente 1.500.
- ¿Los sub-servidores correrán en la misma máquina o en hosts separados? Los esquemas en la misma máquina son más simples pero comparten CPU y RAM. Los hosts separados requieren enrutamiento correcto de LAN/WAN entre el GameServer y el JoinServer/DataServer central.
- ¿Cómo nombrarás y numerarás las instancias? Cada GameServer debe tener un Código de Servidor (ID numérico) único. Asígnalos antes de comenzar para evitar conflictos en la lista del ConnectServer.
Un esquema habitual con dos servidores se ve así:
ConnectServer (público, puerto 44405)
└── JoinServer (interno, puerto 55557)
├── GameServer 0 → "Loto" → puerto 55901, código 0
└── GameServer 1 → "Vid" → puerto 55902, código 1
DataServer (interno, puerto 55980)
SQL Server (interno, puerto 1433)
Configuración del ConnectServer
El ConnectServer (ConnectServer/ConnectServer.cfg o el archivo XML equivalente según tu versión de temporada) mantiene la lista de GameServer disponibles que se muestra a los clientes. Cada entrada necesita un nombre, una dirección IP, un puerto y un código de servidor.
Abre el archivo de configuración de la lista de servidores y agrega una entrada por cada sub-servidor:
; ConnectServer → configuración de ServerList
; Formato: CódigoServidor → Nombre → IP → PuertoCliente → EsVisible
[ServerList]
Server0_Code = 0
Server0_Name = Loto
Server0_IP = 127.0.0.1 ; IP pública si el servidor es remoto
Server0_Port = 55901
Server0_Show = 1
Server1_Code = 1
Server1_Name = Vid
Server1_IP = 127.0.0.1 ; IP pública si el servidor es remoto
Server1_Port = 55902
Server1_Show = 1
; Conexión al JoinServer → uso interno del ConnectServer
JoinServerIP = 127.0.0.1
JoinServerPort = 55557
> [!ATENCION] > No reutilices un código de servidor ya asignado. Los códigos duplicados hacen que el JoinServer enrute mal los tokens de inicio de sesión, lo que provoca que los jugadores sean desconectados inmediatamente después de seleccionar un personaje. Siempre incrementa el valor del código para cada nueva instancia.
Configuración del JoinServer
El JoinServer actúa como intermediario de sesiones. Recibe los tokens de autenticación del ConnectServer después de que un jugador inicia sesión y luego lo redirige al GameServer apropiado. No requiere configuración individual por cada GameServer — en cambio, cada GameServer se registra automáticamente en el JoinServer al iniciarse.
Verifica estos parámetros en JoinServer/JoinServer.cfg:
; JoinServer → configuración principal
ListenPort = 55557 ; puerto al que se conecta el ConnectServer
MaxConnections = 10000 ; capacidad total de tokens entre todos los servidores
LoadBalanceMode = 1 ; 0 = primer disponible, 1 = menos conexiones
TokenExpireSeconds = 30 ; tiempo de vida de un token de inicio de sesión
; Registro de eventos
LogLevel = 2 ; 1=solo errores, 2=info, 3=detallado
LogPath = logs/joinserver.log
LoadBalanceMode = 1 indica al JoinServer que enrute cada nuevo ingreso al GameServer que actualmente tiene menos conexiones activas. Esta es la configuración recomendada para una distribución equilibrada.
Configuración de Cada Instancia de GameServer
Cada instancia de GameServer necesita su propio directorio de trabajo con sus propios archivos de configuración. El enfoque más limpio es copiar tu carpeta GameServer existente y renombrarla (por ejemplo, GameServer0 y GameServer1).
Dentro de cada carpeta, edita el archivo de configuración principal (GameServer.cfg o Setup/GameServerInfo.ini según tu compilación):
; GameServer1 → instancia Vid
; Parámetros que DEBEN diferir entre instancias
ServerCode = 1 ; único por instancia → debe coincidir con lista del ConnectServer
ServerName = Vid
ListenPort = 55902 ; único por instancia → puerto de conexión del cliente
InternalPort = 44902 ; único por instancia → comunicación con JoinServer
; Parámetros que apuntan a servicios compartidos
JoinServerIP = 127.0.0.1
JoinServerPort = 55557
DataServerIP = 127.0.0.1
DataServerPort = 55980
; Asignación de mapas (opcional → asigna mapas específicos a cada servidor)
; Deja vacío para replicar todos los mapas o restringe para reducir el uso de memoria
EnabledMaps = 0,1,2,3,4,7,8 ; Lorencia, Dungeon, Devias, Noria, Lost Tower, Atlans, Tarkan
MaxPlayers = 800
LogPath = logs/gameserver1.log
> [!CONSEJO] > Asignar mapas diferentes a cada sub-servidor (fragmentación de mapas) es una técnica avanzada que reduce el uso de memoria por proceso. Por ejemplo, el GameServer 0 podría alojar Lorencia, Dungeon y Devias, mientras que el GameServer 1 aloja Lost Tower, Atlans y Tarkan. Los jugadores que se desplazan entre mapas son transferidos de forma transparente al servidor correcto por el JoinServer. Esta técnica requiere planificación cuidadosa de dónde se alojan los mapas de eventos como Kalima, Crywolf y el Asedio del Castillo.
Reglas de Firewall y Red
Cada instancia de GameServer debe ser accesible en su propio puerto. Abre lo siguiente en tu firewall para cada instancia:
- El
ListenPortorientado al cliente (TCP entrante) — los jugadores se conectan aquí - El
InternalPortinterno (TCP entrante solo desde el host del JoinServer) — mantenlo restringido a tu red interna
Si tu servidor está detrás de NAT, agrega reglas de reenvío de puertos en tu router para cada ListenPort. Los puertos internos no necesitan reenvío a menos que el JoinServer corra en una máquina física separada fuera de tu LAN.
Para el Firewall de Windows mediante PowerShell, agrega una regla para cada nueva instancia:
# Agregar regla de entrada para el puerto de cliente del GameServer1
New-NetFirewallRule -DisplayName "MU GameServer1 Cliente" `
-Direction Inbound -Protocol TCP `
-LocalPort 55902 -Action Allow
Inicio y Monitoreo de Sub-Servidores
Inicia los procesos del servidor en este orden para evitar fallos de registro:
- DataServer
- JoinServer
- ConnectServer
- GameServer 0 (principal)
- GameServer 1 (Vid), luego cualquier instancia adicional
Cada GameServer imprime una línea de confirmación de registro en su log cuando se conecta exitosamente al JoinServer:
[INFO] Conectado al JoinServer en 127.0.0.1:55557
[INFO] Servidor registrado → Código: 1, Nombre: Vid, Puerto: 55902
[INFO] Listo para aceptar conexiones de jugadores
Monitorea estos logs después del inicio para confirmar que todas las instancias están registradas antes de anunciar el servidor como disponible.
JoinServerIP y JoinServerPort sean correctos en la configuración del GameServer, y que ninguna regla de firewall esté bloqueando el puerto interno entre los dos procesos.Mantenimiento Continuo y Ajuste de Rendimiento
Una vez que los sub-servidores estén en funcionamiento, revisa la configuración periódicamente:
- Logs de distribución de jugadores — Revisa
joinserver.logsemanalmente para verificar si un servidor recibe consistentemente más conexiones. Si hay desbalance, comprueba si un mapa popular está fijado exclusivamente a una sola instancia. - Techo de MaxPlayers — Ajusta los límites por servidor a medida que crece tu comunidad. Elevarlos demasiado sin hardware correspondiente provoca encolamiento de paquetes y lag visible para los jugadores.
- Reinicios programados — Cada instancia de GameServer debe reiniciarse de forma regular (la mayoría de los administradores eligen una ventana de mantenimiento nocturno). Escalonar los reinicios con 5 minutos de diferencia garantiza que los jugadores siempre tengan al menos un servidor disponible.
- Hosting de eventos — Blood Castle, Devil Square y Chaos Castle suelen alojarse en un servidor designado. Anuncia qué servidor ejecuta los eventos para que los jugadores sepan dónde estar.
La configuración correcta de sub-servidores es el paso más efectivo para escalar una comunidad MU Online en crecimiento. La arquitectura fue diseñada para este caso de uso — una vez que tus configuraciones son correctas, agregar una tercera o cuarta instancia sigue el mismo esquema con un esfuerzo adicional mínimo.
Perguntas frequentes
¿Cuántos jugadores puede manejar un solo proceso GameServer?
Un proceso GameServer.exe bien configurado soporta entre 500 y 800 conexiones simultáneas de forma estable, dependiendo del hardware disponible. Por encima de ese rango, el servidor comienza a encolar paquetes de combate y el movimiento en mapas con alta densidad de jugadores se vuelve errático. Para comunidades que superen los 500 jugadores pico, se recomienda dividir la carga en al menos dos sub-servidores.
¿Los sub-servidores comparten la misma base de datos?
Sí. Todos los procesos GameServer se conectan al mismo JoinServer y DataServer, que a su vez apuntan a una única instancia de SQL Server. Los sub-servidores no administran bases de datos independientes — son procesos de red separados que comparten la misma capa de datos, lo que permite que los personajes se muevan entre servidores sin pérdida de información.
¿Qué puertos debo abrir para cada sub-servidor adicional?
Cada instancia de GameServer necesita su propio puerto de escucha para clientes (normalmente en el rango 55901–55910) y un puerto interno para comunicarse con el JoinServer. Ambos deben estar abiertos en el firewall del sistema operativo. Si tu máquina está detrás de NAT, debes agregar reglas de reenvío de puertos en el router para los puertos de cliente. Los puertos internos solo necesitan reenvío si el JoinServer corre en una máquina física diferente fuera de tu LAN.
¿Cómo verifico que el balanceo de carga está funcionando correctamente?
Conecta varias cuentas de prueba desde equipos distintos y revisa los logs del JoinServer (logs/joinserver.log). El archivo debe mostrar el conteo de conexiones por servidor y cómo se distribuye cada nuevo ingreso. También puedes consultar la página de estado del ConnectServer o comparar los contadores de jugadores activos en cada instancia de GameServer desde el panel de administración.