0

我正在使用 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. 我们可以使用 unixss命令检查套接字。(您也可以使用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 eth0myremoteserver网络关闭进行操作)

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

4

1 回答 1

1

来自 PostgreSQL 文档:

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

In other words. if your system doesn't support it, it has no effect and normal timeout rules will apply.

于 2013-04-30T08:51:33.427 回答