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

rzo*_*rzo 20 java postgresql hibernate jdbc tomee

我有两个安装了数据库的Linux服务器(AB)PostgreSQL 9.5.我按照文档中的说明配置了热备用模式.在此设置中,配置为主设备,处于热备用模式.这样做效果很好,表现得像预期的那样.AB

现在,我想Java EE通过Hibernate/ JDBC通过TomEE数据源连接一个独立的应用程序(在不同的机器上运行)到这个数据库设置.

PostgreSQL驱动文档状态,使多台主机可以在JDBC连接URL指定:

jdbc:postgresql://host1:port1,host2:port2/database
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

  1. 如果A是关闭并B手动切换到正常操作模式,我的应用程序是否仍然可以使用jdbc连接URL继续进行数据库操作,如上所述?
  2. 我是否必须配置其他参数/​​库?

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

编辑-1:

我决定测试pgBouncer(如评论中所建议的)解决方法.它适用于我的用例.我写了一个看门狗脚本,它自动执行手动步骤:

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

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

van*_*kel 10

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

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

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

数据源由TomEE中的数据库连接池支持.此页面列出了TomEE中可用的页面.但并非所有数据库连接池都是相同的,我现在更喜欢HikariCP,因为根据我的经验,它更可预测地处理"数据库关闭"场景.另请参阅HikariCP 处理数据库下页的测试结果.

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

(*)更新:自版本42.2.x网络超时实施.

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

  • 尽快从池中删除无效连接,以便应用程序从池中获得大部分有效连接
  • 当数据库出现故障时,尽可能少的应用程序线程挂起(最短的时间)

第二个测试依赖于服务器A不可用,因此连接测试查询(由数据库连接池执行)失败.在两个服务器仍然可用但主交换机和从交换机的情况下,连接测试查询将无济于事,数据库连接池将提供与应用程序的错误(现在只读)数据库连接.在这种情况下,需要人工干预.此处描述了HikariCP的"故障转移模式" (仅适用allowPoolSuspension配置页面中描述的选项):

  • suspendPool()
  • softEvictConnections()
  • 等到activeConnections变为0.
  • resumePool()

第三个测试将使用JavaEE应用程序,到现在为止,您应该知道会遇到什么问题.应用程序在这些类型的测试之后进行更新以改进处理"数据库关闭"方案(例如设置(默认)查询超时)并不罕见.在您的情况下,还需要在手动故障转移期间使用"挂起,刷新和恢复数据库连接池"功能(上述模式).