2016-11-30 17 views
16

我有两台安装了PostgreSQL 9.5数据库的Linux服务器(AB)。我配置了热备份模式,如documentation中所述。在此设置中,A被配置为主设备,B处于热备份模式。这是行之有效的行为如预期。如何在JavaEE应用程序中为PostgreSQL Hot Standby设置配置连接故障转移?

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

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

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

所以我的问题是:

  1. 如果A向下,B手动切换到正常操作模式,我的应用程序是否仍然能够使用上述的jdbc连接url进行数据库操作?
  2. 我必须配置其他参数/​​库吗?

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

EDIT-1:

我决定测试pgBouncer(如在意见提出)为一种解决方法。它适用于我的使用情况。我写了一个看门狗脚本,它可以自动的手动步骤:

  1. 汽车无校验,如果A仍然活着,并监听传入的连接。
  2. 如果发生故障切换,请将B切换到正常运行模式,并让它成为新的主站并重新启动服务。
  3. pgBouncer设置更改为指向B而不是A并重新启动服务。

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

+2

最简单的设置是在两台服务器之前放置pgBouncer或pgPool之类的东西,让应用程序通过它连接。 –

+0

@a_horse_with_no_name感谢您的提示。你现在有没有什么有用的指南来设置pgPool(来自Ubuntu仓库),你会推荐? – rzo

+1

我有一个主和一个只读热stanby postgresql 9.6服务器的类似设置。有一个pgbouncer在他们面前运行。我可以通过更改pgbouncer配置文件的一行来轻松切换到新的主文件。 我已阅读有关自动故障转移群集(使用corosync和pacemaker)的论文,但对我而言这些文件太复杂。如果您有高级Linux系统管理经验,您应该尝试一下。 http://clusterlabs.org/ –

回答

8

在这种情况下,最好测试一下。

我对PostrgeSQL热备份模式没有“实际操作”经验,但是我已经完成了Java应用程序的数据库故障切换。

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

数据源由TomEE中的数据库连接池支持。 This page列出了TomEE中可用的那些。 但并非所有的数据库连接池都相同,我现在更喜欢HikariCP,因为根据我的经验,它更可预测地处理“数据库关闭”情形。 另请参阅在HikariCP的handling database down页面上测试结果。

不幸的是,HikariCP使用JDBC的get/setNetworkTimeout表现为 和PostgreSQL JDBC驱动程序does not implement this。 因此,为了确保(JavaEE)应用程序线程不会永久挂在数据库操作上,您需要设置connectTimeoutsocketTimeout JDBC驱动程序选项。设置socketTimeout是不稳定的,因为它会自动为数据库的所有查询设置一个时间限制。

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

  • 无效的连接从池中尽快移除,使得应用程序从池中
  • 尽可能少的应用程序的线程挂起(对于最短的时间量大多是有效的连接)当数据库发生故障时

第二个测试依赖于服务器A不可用,因此连接测试查询(由数据库连接池执行)失败。 如果两台服务器保持可用,但主从交换机连接测试查询不起作用 并且数据库连接池将向应用程序提供错误的(现在只读的)数据库连接。 在这种情况下,需要手动干预。 A “故障切换模式” 为HikariCP描述here (仅适用于configuration页中描述的选项allowPoolSuspension):

  • suspendPool()
  • softEvictConnections()
  • 等待,直到activeConnections变为0 。
  • resumePool()

第三次试验将与JavaEE应用和现在,你应该有一个良好的IDE一个期望的问题。 应用程序在这些类型的测试之后得到更新以改进处理“数据库关闭”场景 (例如设置(默认)query-timeouts)并不罕见。 在你的情况下,在手动故障转移期间使用“暂停,刷新和恢复数据库连接池”功能(上述模式)也是可取的。

+0

非常深刻的答案! – MWiesner

+0

谢谢您在答案中的详细解释。这听起来像是开始测试我的设置中的行为的好方法。 – rzo

相关问题