我正在运行使用 PDO 连接到 postgres 的 PHP Web 应用程序(https://github.com/fusionpbx/fusionpbx/blob/bc1e163c898ea2e410787f8e938ccbead172aa5a/resources/classes/database.php#L202)。
我正在运行一个故障转移集群,所以基本上我只放了 2 个主机名,我的连接字符串如下所示:
“pgsql:host=host1,host2 port=5432 dbname=fusionpbx user=fusionpbx password=password target_session_attrs=read-write”
这可以正常工作,如果主机 1 处于待机状态,则选择主机 2 的延迟非常小。唯一的问题是 host1 无法访问或关闭。在这种情况下,PDO/驱动程序 (?) 总是首先尝试主机 1,等待 30 秒直到超时并转到主机 2。似乎没有记住 host1 不可用的事实。我找到了 3 个解决方法:
- 创建 PDO 时添加 PDO::ATTR_TIMEOUT=2。是的,我知道很愚蠢,但至少允许临时解决方法,以防万一,直到我找到正确的解决方案。
- 外部监控 postgres 并更改连接字符串中的节点顺序,始终将活动节点放在首位。我开始认为这是最少的回避。
- PDO::ATTR_PERSISTENT => true - 我已经对此进行了测试,乍一看它工作得很好,但考虑到我不是真正的 PHP 人,而且应用程序不是我的,而是第 3 方应用程序,我不愿意做出如此有影响力的改变。
也许有人可以分享他们的经验?我很惊讶在网上几乎找不到这件事。此外,在同一个机器上,我正在运行 lua 脚本,也以相同的方式连接到相同的 postgres,并且在处理这种情况下似乎没有问题。它是相同版本的 libpq,因为它是相同的 linux 机器,并且我没有添加任何特定于连接字符串的内容。