Estoy ejecutando pgBouncer frente a una base de datos de Postgres 9 ocupada. La mayor parte del tiempo funciona bien. Pero cada pocas horas recibiré un correo electrónico de error de mi aplicación con una excepción de psycopg2:
OperationalError ('no se pudo conectar al servidor: no se puede asignar la dirección solicitada ¿El servidor se ejecuta en el host "neo-hulk" y acepta conexiones TCP / IP en el puerto 6432?')
Esta es una aplicación de Python con un montón de trabajadores de apio ejecutando tareas. Cuando llegan esos errores, verifico el pgbouncer db y el tamaño del grupo está dentro de los límites. Después de experimentar un poco, configuré el tamaño máximo del grupo en 400 y el tamaño del grupo en 200. El modo de grupo es "sesión" (las solicitudes son en su mayoría de confirmación automática, casi no hay transacciones).
¿Qué hace que pgBouncer 'desaparezca' así? es solo por cortos períodos de tiempo (y en total estamos hablando de una pequeña cantidad de solicitudes en comparación con el gran volumen de solicitudes que se están entregando) pero esas solicitudes que fallan son importantes.
¡Gracias!
fuente
-vvv
y ver si puede hacer coincidir la salida de registro anómala con sus errores a tiempo.Respuestas:
La parte " No se puede asignar la dirección solicitada " en el mensaje de error proviene de la pila TCP del núcleo. Cuando se encuentra de forma intermitente, esto generalmente significa que el espacio de los sockets disponibles se agota debido a demasiados sockets en estado de espera (
TIME_WAIT
o menos probableFIN_WAIT_1
oFIN_WAIT_2
)El rango de puertos de socket se puede generar mediante
cat /proc/sys/net/ipv4/ip_local_port_range
. El valor predeterminado en un núcleo Linux de stock es generalmente32768 61000
.Puede verificar el resultado
netstat -ton|grep WAIT
en el cliente (s) y en el host de pgBouncer cuando el sistema está ocupado. La-o
bandera mostrará los contadores de tiempo de espera relacionados con los estados de espera.Si el número total de sockets TCP está cerca,
61000-32768=28232
entonces el agotamiento de este rango es probablemente su problema. Dado que un socket cerrado pasa 60 segundos enTIME_WAIT
estado normal, si un host cliente se conecta más de 28232 veces en un minuto, las nuevas conexiones fallarán con el error mencionado hasta que se liberen los puertos.Como primera solución, el rango de puertos TCP puede extenderse:
Si no es satisfactorio, verifique las banderas
tcp_tw_recycle
ytcp_tw_reuse
, también ajustables a través de/proc/sys/net/ipv4
ysysctl
.Se definen como (desde
man tcp
):Personalmente tuve éxito
tcp_tw_recycle
cuando me enfrenté a este problema con una aplicación cliente MySQL, pero no tome esto como una recomendación, ya que mi comprensión de TCP es superficial en el mejor de los casos.fuente
/etc/sysctl.conf
quenet.ipv4.ip_local_port_range = 1025 65535
tener que persista tras los reinicios.