O ApsaraDB RDS for PostgreSQL permite implementar failover automático e separação de leitura e escrita na camada de driver, sem exigir alterações na lógica da aplicação. Tanto a libpq (biblioteca cliente C do PostgreSQL) quanto o Java Database Connectivity (JDBC) oferecem suporte a esse recurso a partir do PostgreSQL 10.
Referência rápida: escolha seu driver
|
Driver |
Linguagem |
Failover |
Balanceamento de carga |
|
libpq |
C, Python, PHP e qualquer linguagem que utilize a biblioteca C |
Sim |
Não |
|
JDBC |
Java |
Sim |
Sim (via |
Usar libpq para failover automático e separação de leitura e escrita
A libpq aceita uma lista de hosts separados por vírgula na string de conexão. Se um host ficar indisponível, o driver se conectará automaticamente ao próximo host disponível, eliminando a necessidade de lógica de reconexão na aplicação.
Formato da string de conexão
postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...]
Exemplo
A string de conexão a seguir conecta um cliente a uma instância primária e duas instâncias somente leitura. Desde que pelo menos uma instância esteja disponível, as solicitações de leitura terão êxito.
postgres://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/postgres?target_session_attrs=any
Parâmetro target_session_attrs
O parâmetro target_session_attrs controla a qual tipo de instância o cliente se conecta.
|
Valor |
Comportamento |
|
|
Conecta-se a qualquer instância disponível. Se a conexão for interrompida, o driver se reconectará a outra instância da lista. |
|
|
Conecta-se apenas a uma instância que aceite operações de leitura e escrita. O driver tenta cada host em ordem e ignora instâncias que não suportem essas operações. |
Para obter a referência completa dos parâmetros, consulte Strings de conexão.
Determinar se uma conexão é com uma instância primária ou somente leitura
Chame pg_is_in_recovery() na aplicação para verifique se a instância conectada é primária (false) ou somente leitura (true). Use essa verificação para direcionar o tráfego de escrita e leitura à instância correta.
Exemplo em Python
import psycopg2
conn = psycopg2.connect(
database="postgres",
host="pgm-bpxxx1.pg.rds.aliyuncs.com,pgm-bpxxx2.pg.rds.aliyuncs.com,pgm-bpxxx3.pg.rds.aliyuncs.com",
user="testxxx",
password="xxxxxx",
port="3433",
target_session_attrs="read-write"
)
cur = conn.cursor()
cur.execute("select pg_is_in_recovery(), pg_postmaster_start_time()")
row = cur.fetchone()
print("recovery =", row[0])
print("time =", row[1])
Saída esperada:
recovery = False
time = 2020-07-09 15:33:57.79001+08
O exemplo utiliza a sintaxe de impressão do Python 3. Para Python 2, substitua print("recovery =", row[0]) por print "recovery =",row[0].
Exemplo em PHP
<?php
$conn = pg_connect("host=pgm-bpxxx1.pg.rds.aliyuncs.com,pgm-bpxxx2.pg.rds.aliyuncs.com,pgm-bpxxx3.pg.rds.aliyuncs.com port=3433 dbname=postgres user=testxxx password=xxxxxx target_session_attrs=read-write") or die("Could not connect");
$status = pg_connection_status($conn);
if ($status === PGSQL_CONNECTION_OK) {
print "Connection status ok\n";
} else {
print "Connection status bad\n";
}
$sql = pg_query($conn, "select pg_is_in_recovery()");
while ($row = pg_fetch_row($sql)) {
echo "Recovery-status: $row[0]\n";
}
?>
Saída esperada:
Connection status ok
Recovery-status: f
Server: xxx.xxx.xx.xx
Usar JDBC para failover automático e separação de leitura e escrita
O driver JDBC do PostgreSQL aceita uma lista de hosts separados por vírgula. Ele tenta cada host sequencialmente até estabelecer uma conexão bem-sucedida. Se todos os hosts estiverem indisponíveis, o driver retornará um erro.
Formato da string de conexão
jdbc:postgresql://node1,node2,node3/accounting?targetServerType=preferSlave&loadBalanceHosts=true
Exemplo
jdbc:postgresql://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/accounting?targetServerType=preferSlave&loadBalanceHosts=true
Parâmetros de conexão JDBC
targetServerType
Define a qual tipo de instância o driver JDBC se conecta.
|
Valor |
Comportamento |
|
|
Conecta-se a qualquer instância disponível. |
|
|
Conecta-se exclusivamente à instância primária, que suporta operações de escrita. |
|
|
Conecta-se apenas a uma instância secundária. Instâncias secundárias não suportam operações de escrita. |
|
|
Prioriza a conexão com uma instância secundária; caso nenhuma esteja disponível, recorre à instância primária. |
loadBalanceHosts
Especifica a ordem de conexão quando há múltiplos hosts listados.
|
Valor |
Comportamento |
|
|
Estabelece a conexão seguindo a ordem definida na string de conexão. |
|
|
Realiza conexões em ordem aleatória, distribuindo a carga entre as instâncias. |
Implementar separação de leitura e escrita com dois pools de conexão
Configure strings de conexão distintas para o tráfego de escrita e de leitura. Todos os exemplos abaixo listam os mesmos três hosts; o parâmetro targetServerType determina a qual tipo de instância cada pool se conecta.
Pool de escrita — conecta-se apenas à instância primária:
jdbc:postgresql://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/accounting?targetServerType=master
Pool de leitura — conecta-se a instâncias secundárias, com balanceamento de carga e fallback para a primária:
jdbc:postgresql://pgm-bpxxx1.pg.rds.aliyuncs.com:3433,pgm-bpxxx2.pg.rds.aliyuncs.com:3433,pgm-bpxxx3.pg.rds.aliyuncs.com:3433/accounting?targetServerType=preferSlave&loadBalanceHosts=true
Direcione as operações de escrita pelo pool de escrita e as operações de leitura pelo pool de leitura. Para verifique em qual tipo de instância uma conexão está estabelecida, chame pg_is_in_recovery(). Essa função retorna false para instâncias primárias e true para instâncias secundárias ou somente leitura.
Observações de uso
Pool de leitura durante failover: Durante uma janela de failover, um pool de leitura configurado com
targetServerType=preferSlavepode se conectar brevemente à nova instância primária promovida, caso nenhuma secundária esteja disponível no momento. Esse comportamento é esperado e se resolve automaticamente assim que uma instância secundária entrar online.Instâncias de escrita versus leitura: Instâncias primárias suportam operações de escrita. Instâncias secundárias e somente leitura não aceitam escritas — utilize
targetServerType=masterpara qualquer conexão que execute operações de escrita.