当网络关闭或硬启动服务器时,与postgres的套接字连接不会关闭

时间:2013-02-25 12:35:25

标签: python sockets postgresql sqlalchemy psycopg2

我正在使用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')

(您可以ifdown eth0 myremoteserver进行网络关闭)

然后它将在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参数。

1 个答案:

答案 0 :(得分:1)

来自PostgreSQL文档:

  

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

换句话说。如果您的系统不支持它,则它不起作用,并且将应用正常的超时规则。