pgBouncer 运行良好,但有时不可用

Har*_*rel 11 postgresql python pgbouncer

我在繁忙的 postgres 9 数据库前运行 pgBouncer。在大多数情况下,它运行良好。但是每隔几个小时我就会收到一封来自我的应用程序的错误电子邮件,但 psycopg2 除外:

OperationalError('无法连接到服务器:无法分配请求的地址服务器是否在主机“neo-hulk”上运行并接受端口 6432 上的 TCP/IP 连接?')

这是一个 python 应用程序,其中有一堆 celery 工人正在运行任务。当这些错误到达时,我检查 pgbouncer db 并且池大小在限制范围内。经过一些实验,我将池最大大小设置为 400,池大小设置为 200。池模式是“会话”(请求主要是自动提交,几乎没有事务)。

是什么让 pgBouncer 像那样“消失”?它只是在很短的时间内(总的来说,与它处理的大量请求相比,我们谈论的是极少量的请求),但那些失败的请求很重要。

谢谢!

Dan*_*ité 19

错误消息中的“无法分配请求的地址”部分来自内核 TCP 堆栈。当间歇性遇到时,这通常意味着可用套接字的空间已耗尽,因为处于等待状态的套接字过多(TIME_WAIT,或不太可能FIN_WAIT_1FIN_WAIT_2

可以通过 输出套接字端口的范围cat /proc/sys/net/ipv4/ip_local_port_range。股票 Linux 内核的默认值通常是32768 61000.

netstat -ton|grep WAIT当系统繁忙时,您可以在客户端和 pgBouncer 的主机上检查结果。该-o标志将显示与等待状态相关的超时计数器。

如果 TCP 套接字的总数接近 ,61000-32768=28232那么这个范围的用尽可能是您的问题。由于一个关闭的套接字TIME_WAIT在正常情况下需要 60 秒的状态,如果客户端主机在一分钟内连接超过 28232 次,新连接将失败并出现上述错误,直到端口被释放。

作为第一个解决方法,可以扩展 TCP 端口范围:

 # echo "1025 65535" >/proc/sys/net/ipv4/ip_local_port_range
Run Code Online (Sandbox Code Playgroud)

如果不满意,请检查tcp_tw_recycletcp_tw_reuse标志,也可以通过/proc/sys/net/ipv4和 进行调整sysctl

它们被定义为(来自man tcp):

       tcp_tw_recycle(布尔值;默认值:禁用;自 Linux 2.4 起)
              启用 TIME_WAIT 套接字的快速回收。启用这个
              不推荐选项,因为这会导致工作时出现问题?
              使用 NAT(网络地址转换)。

       tcp_tw_reuse(布尔值;默认值:禁用;自 Linux 2.4.19/2.6 起)
              允许为新连接重用 TIME_WAIT 套接字
              从协议的角度来看是安全的。不应该改变它
              技术专家的建议/请求。

我个人tcp_tw_recycle在使用 MySQL 客户端应用程序遇到这个问题时取得了成功,但不要将此作为建议,我对 TCP 的理解充其量只是肤浅的。

  • 好的!你想把设置在 `/etc/sysctl.conf` 中作为 `net.ipv4.ip_local_port_range = 1025 65535` 让它在重启后保持不变。 (2认同)