Estou executando o pgBouncer na frente de um banco de dados postgres 9 ocupado. Na maioria das vezes funciona bem. Mas, a cada poucas horas, recebo um e-mail de erro do meu aplicativo, com exceção do psycopg2:
OperationalError('não foi possível conectar ao servidor: não é possível atribuir o endereço solicitado O servidor está sendo executado no host "neo-hulk" e aceita conexões TCP/IP na porta 6432?')
Este é um aplicativo python com vários trabalhadores de aipo executando tarefas. Quando esses erros chegam, verifico o pgbouncer db e o tamanho do pool está dentro dos limites. Depois de algumas experiências, defini o tamanho máximo do pool para 400 e o tamanho do pool para 200. O modo pool é "sessão" (as solicitações são, em sua maioria, de confirmação automática, quase sem transações).
O que faz o pgBouncer 'desaparecer' assim? é apenas por curtos períodos de tempo (e, no total, estamos falando de uma pequena quantidade de solicitações em comparação com o grande volume de solicitações atendidas), mas as solicitações que falham são importantes.
Obrigado!
A parte " Não é possível atribuir o endereço solicitado " na mensagem de erro vem da pilha TCP do kernel. Quando encontrado de forma intermitente, isso normalmente significa que o espaço de soquetes disponíveis está esgotado devido a muitos soquetes em estado de espera (
TIME_WAIT
, ou menos provavelmenteFIN_WAIT_1
ouFIN_WAIT_2
)A faixa de portas de soquete pode ser gerada por
cat /proc/sys/net/ipv4/ip_local_port_range
. O valor padrão em um kernel padrão do Linux é geralmente32768 61000
.Você pode verificar o resultado
netstat -ton|grep WAIT
no(s) cliente(s) e no host do pgBouncer quando o sistema estiver ocupado. O-o
sinalizador mostrará os contadores de timeout relacionados aos estados de espera.Se o número total de soquetes TCP estiver próximo
61000-32768=28232
, o problema provavelmente será o esgotamento desse intervalo. Como um soquete fechado gasta 60 segundos noTIME_WAIT
estado em condições normais, se um host cliente se conectar mais de 28232 vezes em um minuto, novas conexões falharão com o erro mencionado até que as portas sejam liberadas.Como primeira solução alternativa, o intervalo de portas TCP pode ser estendido:
Se não for satisfatório, verifique os sinalizadores
tcp_tw_recycle
e , também sintonizáveis por e .tcp_tw_reuse
/proc/sys/net/ipv4
sysctl
Eles são definidos como (de
man tcp
):Pessoalmente, tive sucesso
tcp_tw_recycle
quando enfrentei esse problema com um aplicativo cliente MySQL, mas não tome isso como uma recomendação, pois meu entendimento do TCP é, na melhor das hipóteses, superficial.