如何在 JavaEE 应用程序中为 PostgreSQL 热备用设置配置连接故障转移?

2022-09-02 01:50:58

我有两台安装了数据库的Linux服务器( 和 )。我按照文档中的说明配置了热备用模式。在此设置中,配置为主服务器,处于热备用模式。这运行良好,并且按预期运行。ABPostgreSQL 9.5AB

现在,我想通过/通过数据源将独立应用程序(在另一台计算机上运行)连接到此数据库设置。Java EEHibernateJDBCTomEE

PostgreSQL 驱动程序文档指出,可以在 jdbc 连接 url 中指定多个主机:

jdbc:postgresql://host1:port1,host2:port2/database

所以我的问题是:

  1. 如果 已关闭并手动切换到正常操作模式,我的应用程序是否仍能够使用上述 jdbc 连接 URL 继续数据库操作?AB
  2. 我必须配置其他参数/库吗?

注意:从我了解到的各种来源,不支持自动故障转移(除非该过程涉及第三方软件 - 请参阅下面的评论)。因此,故障转移需要手动执行,这对于此特定用例是可以的。PostgreSQL

编辑-1:

我决定测试(如评论中建议的那样)以获得解决方法。它适用于我的用例。我写了一个看门狗脚本,它自动化了手动步骤:pgBouncer

  1. 持续检查(如果仍处于活动状态)并侦听传入连接。A
  2. 在故障转移的情况下,切换到正常操作模式,让它成为新的主服务器并重新启动服务。B
  3. 将设置更改为指向而不是,然后重新启动服务。pgBouncerBA

但是,我仍然会感兴趣,如果有人有没有第三方软件的经验?


答案 1

在这种情况下,最好进行测试和测量。

我没有PostrgeSQL热备用模式的“实践”经验,但我已经完成了Java应用程序的数据库故障转移。

首先,在 PostgreSQL 驱动程序文档页面上测试有关该参数的声明(在页面底部提到)。
使用 main 方法编写一个小的 Java “PgHsm” 类,该方法通过该方法使用 PostgreSQL JDBC 驱动程序并运行简单的更新查询。
它应该使用服务器 A 来执行更新查询。在服务器A上停止PostgreSQL,运行PgHsm:它应该无法连接,因为服务器B不是主服务器。
使服务器 B 成为主服务器,运行 PgHsm:它应该运行正常。?targetServerType=masterDriverManager.getConnection

数据源由 TomEE 中的数据库连接池提供支持。此页面列出了TomEE中可用的那些。但并非所有数据库连接池都是相等的,我现在更喜欢HikariCP,因为根据我的经验,它可以更可预测地处理“数据库关闭”情况。另请参阅HikariCP处理数据库下页的测试结果。

不幸的是,HikariCP使用JDBC的get/setNetworkTimeout来可预测的行为,而PostgreSQL JDBC驱动程序没有实现这一点(*)。因此,为了确保 (JavaEE) 应用程序线程不会永远挂起在数据库操作上,您需要设置 和 JDBC 驱动程序选项。设置 a 是不稳定的,因为它会自动为数据库的所有查询设置时间限制。connectTimeoutsocketTimeoutsocketTimeout

(*)更新:由于实现了版本网络超时。42.2.x

要执行的第二个测试涉及更新 Java “PgHsm” 类以使用您选择的数据库连接池实现,并启动(至少)两个线程,这些线程在循环中连续运行简单的更新查询(在循环中,从池中获取数据库连接,并在提交/回滚后返回到池)。在关闭服务器 A 并将服务器 B 切换到“主”模式时,请监视“PgHsm”记录的异常以及线程在执行数据库操作时等待/挂起的时间。
测试结果可用于更新 JDBC 驱动程序选项和池设置。关注以下方面的结果:

  • 将尽快从池中删除无效连接,以便应用程序从池中获取大部分有效连接
  • 数据库关闭时,尽可能少的应用程序线程挂起(在最短的时间内)

第二个测试依赖于服务器 A 不可用,因此连接测试查询(由数据库连接池执行)失败。如果两台服务器都保持可用,但主服务器和从服务器切换,则连接测试查询将无济于事,数据库连接池将为应用程序提供错误(现在是只读)的数据库连接。在这种情况下,需要手动干预。此处描述了HikariCP的“故障转移模式”(仅适用于配置页面上描述的选项):allowPoolSuspension

  • 挂起池()
  • softEvictConnections()
  • 等到活动连接变为 0。
  • resumePool()

第三个测试将使用JavaEE应用程序,到现在为止,您应该已经很好地知道会发生什么问题。在这些测试之后,应用程序进行更新以改善对“数据库关闭”情况的处理(例如,设置(默认)查询超时)的情况并不少见。在您的情况下,在手动故障转移期间使用的“挂起、刷新和恢复数据库连接池”功能(如上所述的模式)也是可取的。


答案 2

推荐