【问题标题】:Socket connection to postgres is not close when network down or hard boot the server网络关闭或硬启动服务器时,与 postgres 的套接字连接未关闭
【发布时间】:2013-02-10 14:30:13
【问题描述】:

我正在使用 sqlalchemy 创建与 postgresql 的连接并执行简单的命令。

>>> from sqlalchemy import create_engine
>>> c = create_engine('postgres://myuser@myremoteserver/mydb?keepalives_idle=4&keepalives_interval=1&keepalives_count=5')
>>> c.execute('select 1').scalar()
1

它工作正常。

在执行查询时创建连接后,它将创建到 postgres 服务器的套接字,在此示例中,它将创建到 myremoteserver 的套接字。我们可以使用 unix ss 命令检查套接字。 (也可以使用netstat)。

[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,1.319ms,0) users:(("python",4074,3))

如果在创建连接后网络出现故障或 postgres 服务器机器崩溃。

>>> c = create_engine('postgres://myuser@myremoteserver/mydb?keepalives_idle=4&keepalives_interval=1&keepalives_count=5')

(您可以在myremoteserver 上执行ifdown eth0 以防止网络中断)

然后它会在 5 次尝试到服务器后关闭连接。

[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,1.319ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,738ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,2.720ms,0) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,788ms,2) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      0            192.168.1.15:43471       myremoteserver:postgres  timer:(keepalive,191ms,4) users:(("python",4074,3))
[root@myclient ~]# ss -torp | grep python
[root@myclient ~]# ss -torp | grep python

这是我们在连接字符串中设置的连接行为。

如果我们在套接字关闭和服务器关闭之前执行查询,就会出现问题。

# do ifdown eth0 on postgres server to break the network connection.
# execute query before socket close.
>>> c.execute('select 1').scalar()

现在如果你检查套接字然后

[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,1.602ms,3) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,585ms,3) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,2.833ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,1.851ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,808ms,4) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,5.393ms,5) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,3.846ms,5) users:(("python",3098,7))
.................
.................
.................
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,5.268ms,72) users:(("python",3098,7))
[root@myclient ~]# ss -torp | grep python
ESTAB      0      74           192.168.1.15:43471       myremoteserver:postgres  timer:(on,4.804ms,254) users:(("python",3098,7))

根据连接字符串,套接字必须在 5 次尝试后关闭。但我不知道为什么它尝试了 5 次以上并达到 254 次尝试。

即使我们在服务器崩溃和客户端关闭套接字之间执行查询,我必须设置什么才能在 5 次尝试后关闭套接字。

注意:keepalives_idle、keepalives_interval和keepalives_count用于设置TCP连接的keepalive参数。

【问题讨论】:

    标签: python sockets postgresql sqlalchemy psycopg2


    【解决方案1】:

    来自 PostgreSQL 文档:

    控制在客户端与服务器的连接被视为死之前可能丢失的 TCP keepalive 数量。零值使用系统默认值。对于通过 Unix 域套接字建立的连接,或者如果禁用了 keepalive,则忽略此参数。它仅在 TCP_KEEPCNT 套接字选项可用的系统上受支持;在其他系统上,它没有效果。

    换句话说。如果您的系统不支持它,它没有任何效果,将适用正常的超时规则。

    【讨论】:

      猜你喜欢
      • 2017-08-05
      • 2013-02-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-01-22
      • 1970-01-01
      相关资源
      最近更新 更多