Cluster AppServer com load balancer
Setup de varios AppServers atras de HAProxy/Nginx pra alta disponibilidade e escalabilidade horizontal. Configuracao, session affinity, deploy rolling.
1 AppServer = single point of failure. Em base com 100+ usuarios concorrentes ou regras criticas, cluster e default. Padrao: 2-4 AppServers atras de load balancer com session affinity.
Arquitetura tipica
┌──────────────┐
┌───→ │ HAProxy/LB │ ←─── Usuarios SmartClient
│ └──────────────┘
│ │ │
│ ┌───────┘ └────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ AppSrv 1 │ │ AppSrv 2 │ │ AppSrv 3 │
└──────────┘ └──────────┘ └──────────┘
│ │ │
└─────────────┼─────────────┘
▼
┌───────────────┐
│ Banco (PG/SQL)│
└───────────────┘
Pre-requisitos
- Servidores Linux/Windows identicos (mesma versao Protheus)
- RPO compartilhado via NFS/CIFS OU sincronizado via rsync
- Banco unico (todos AppServers apontando)
- Load balancer (HAProxy, Nginx, ALB AWS, etc)
Etapa 1: Configurar AppServers identicos
; appserver.ini de cada no
[General]
; Apontar pra storage compartilhado
RootPath=/mnt/shared/protheus_data
SourcePath=/mnt/shared/protheus_data/system
RpoCustom=cliente.rpo
; Banco compartilhado
DBHOST=banco.empresa.com.br
DBPORT=5432
; ID unico por no (importante!)
LICENSESERVER=10.0.0.10
INSTANCEID=node1 ; node1, node2, node3 em cada
Etapa 2: HAProxy config
# /etc/haproxy/haproxy.cfg
frontend smartclient
bind *:6717
mode tcp
option tcplog
default_backend appservers
backend appservers
mode tcp
balance leastconn ; menos conexoes ganha
# Session affinity por IP cliente
stick-table type ip size 200k expire 30m
stick on src
server node1 10.0.0.21:6717 check
server node2 10.0.0.22:6717 check
server node3 10.0.0.23:6717 check
Etapa 3: Rolling deploy zero-downtime
#!/bin/bash
# /scripts/rolling-deploy.sh
NODES=(node1 node2 node3)
NEW_RPO=$1 # passa o arquivo .rpo novo
for node in "${NODES[@]}"; do
echo "=== Atualizando $node ==="
# 1. Tirar do LB
ssh haproxy "echo 'disable server appservers/$node' | socat /var/run/haproxy.sock stdio"
# 2. Esperar sessoes ativas (max 5 min)
sleep 300
# 3. Atualizar RPO
scp $NEW_RPO $node:/mnt/shared/protheus_data/apo/
# 4. Restart
ssh $node "systemctl restart appserver"
sleep 30
# 5. Validar
ssh $node "curl -s http://localhost:8080/health | grep ok" || exit 1
# 6. Voltar pro LB
ssh haproxy "echo 'enable server appservers/$node' | socat /var/run/haproxy.sock stdio"
sleep 10
done
Pegadinhas
- Variavel Private/Public: nao migra entre nos. Sessao precisa ficar no mesmo no (session affinity).
- Schedule/JOB: configure pra rodar em 1 no especifico, nao distribuir.
- Cache local: cada no tem cache proprio. Em troca de RPO, todos precisam UpdRPOData().
- Licenca: TOTVS Licence Server centralizado controla licencas — cluster nao multiplica licencas.
- Storage compartilhado: NFS pode ser gargalo. Em base grande, sincronizar via rsync e mais robusto.
Monitoramento
- HAProxy stats dashboard — conexoes ativas, response time
- Logs centralizados via FwLogger → ELK
- Alarme se um no cair (Prometheus + AlertManager)
Custo/beneficio
| Cenario | Cluster vale? |
|---|---|
| < 20 usuarios, 1 filial | Nao — single AppServer ok |
| 20-100 usuarios, 1-3 filiais | Talvez — analise SLA |
| 100+ usuarios, multi-filial | Sim — HA obrigatorio |
| Cloud (AWS/Azure) | Sim — barato e nativo |