Proxies de Conexão
Durante o failover, algo deve enviar as conexões do cliente para o novo primário. HAProxy (ou um balanceador de carga na nuvem) roteia TCP; PgBouncer 1.x agrupa sessões. Eles resolvem camadas diferentes.
Receita
Frontends TCP do HAProxy para escrita (primário) e leitura (réplicas); PgBouncer em modo de pool de transação para workers de aplicação.
# Verificações de backend do HAProxy REST (porta 8008) do Patroni para o líder
# frontend pg_write -> backend patroni_primary (apenas o líder passa na verificação)
# frontend pg_read -> backend patroni_replicas (standbys passam na verificação de réplica)# Trecho do pgbouncer.ini
[databases]
appdb = host=pg-write.internal port=5432 dbname=appdb
[pgbouncer]
listen_port = 6432
pool_mode = transaction
max_client_conn = 2000
default_pool_size = 50
server_lifetime = 300Quando usar isso: Mais de um punhado de servidores de aplicação conectando ao PostgreSQL; o failover não deve exigir alterações na configuração da aplicação.
Exemplo de Funcionamento
Script de verificação do HAProxy Patroni e recarga do PgBouncer após o failover:
#!/usr/bin/env bash
# patroni-primary-check.sh - sai 0 se este nó for o líder do Patroni
LEADER=$(curl -sf http://127.0.0.1:8008/patroni | jq -r .role)
[[ "$LEADER" == "master" || "$LEADER" == "primary" ]]# Trecho do haproxy.cfg
backend patroni_primary
mode tcp
option tcp-check
tcp-check connect port 8008
tcp-check send GET\ /primary\ HTTP/1.0\r\n
tcp-check expect string 200
server pg1 10.0.1.11:5432 check port 8008
server pg2 10.0.1.12:5432 check port 8008
server pg3 10.0.1.13:5432 check port 8008# Após o failover: reinicia o PgBouncer para descartar conexões de servidor obsoletas
psql -h 127.0.0.1 -p 6432 -U pgbouncer pgbouncer -c "RECONNECT;"
# ou: systemctl reload pgbouncerO que isso demonstra:
- O HAProxy usa os endpoints REST
/primarye/replicado Patroni para roteamento de saúde. - As aplicações se conectam a
pg-write.internal:6432(PgBouncer) e não a IPs de nós individuais. RECONNECTou recarga limpam os pools apontando para o primário antigo.
Análise Detalhada
Responsabilidades de Camada
| Componente | Camada OSI | Comportamento em Failover |
|---|---|---|
| HAProxy / NLB | TCP (L4) | Roteia para o líder Patroni saudável |
| PgBouncer 1.x | Pool de Conexões | Reabre backends após mudança de líder |
| RDS Proxy | Pool Gerenciado + IAM | AWS lida com a troca de backend |
| URL JDBC da Aplicação | Cliente | Deve usar nome de host estável + timeouts |
Divisão Leitura/Escrita
- Escritas: Backend único que passa na verificação de primário do Patroni.
- Leituras: Réplicas via verificação
/replica; toleram pequeno atraso para relatórios. - Cuidado: Read-your-writes requer roteamento primário ou ciente de sincronização, não qualquer réplica.
Modos do PgBouncer
| Modo | Nota de HA |
|---|---|
session | Mais seguro para prepared statements; menos conexões salvas |
transaction | Comum para aplicações web; use compatibilidade com DISCARD ALL |
statement | Raro; quebra muitos padrões de ORM |
Armadilhas
- Apenas PgBouncer, sem HAProxy - O pool ainda mira em um nome de host; o DNS deve ser atualizado no failover. Correção: Patroni + HAProxy ou TTL de DNS confiável + verificações de saúde.
- Prepared statements em modo de transação - Erros após reutilização do pool. Correção:
pool_mode = sessionpara aplicações afetadas ou desabilitar prepared statements. - HAProxy verificando apenas a porta PostgreSQL - Tanto o primário quanto a réplica aceitam TCP; roteamento incorreto. Correção: Verificações de saúde HTTP do Patroni na porta 8008.
server_lifetimelongo - Conexões obsoletas ao primário por minutos. Correção: Reduzir o tempo de vida;RECONNECTno callbackon_role_changedo Patroni.- RDS Proxy com Patroni auto-hospedado - Produtos diferentes; não misture padrões. Correção: Escolha uma pilha gerenciada ou auto-hospedada por ambiente.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| VIP + keepalived | Data center legado | LB na nuvem preferível |
| Serviço Kubernetes + endpoints Patroni | PG hospedado em K8s | VMs bare-metal |
| Troca direta de CNAME DNS | Configurações pequenas mais simples | RTO de sub-minuto exigido |
FAQs
Ordem HAProxy vs PgBouncer?
Comum: cliente -> PgBouncer -> HAProxy -> PostgreSQL, ou cliente -> HAProxy -> PgBouncer -> PostgreSQL. Escolha uma topologia e documente-a.
O RDS Proxy substitui o Patroni?
Não. O RDS Proxy agrupa conexões; Aurora/RDS Multi-AZ lida com o failover por baixo.
Conexões de replicação através do PgBouncer?
Não. Replicação streaming e lógica se conectam diretamente à porta 5432 do PostgreSQL.
Terminação SSL?
Termine no HAProxy ou use sslmode=require de ponta a ponta. Atenda aos requisitos de conformidade.
Quantas instâncias do PgBouncer?
Pelo menos duas para HA; cada uma aponta para o mesmo VIP de escrita do HAProxy.
Relacionados
- Patroni & etcd/Consul - eleição de líder
- Noções Básicas de HA - requisitos de retentativa do cliente
- Testes de HA - validação de roteamento em testes
- Matemática de Conexão - dimensionamento de pool
Versões da Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x, e PostGIS 3.5+.