HikariCP 未检测到数据库 DNS 更改
HikariCP doesn't detect DB DNS change
在我们的应用程序中,我们将 HikariCP 与 Postgres 结合使用。应用程序通过 CNAME 连接到 DB(DB 在 CNAME 后面)。
将 CNAME 的值更改为不同的数据库(在我们的例子中,副本被提升为主)不会反映在我们的连接池中。查询仍然尝试从旧数据库中获取数据。 HikariCP 仅在 maxLifeTime
结束或我们重新启动应用程序时进行更改。
maxLifeTime
设置为30分钟,idleTimeout
设置为10分钟(这是HikariCP的默认值)。
问题: 有没有办法让 HikariCP 发现连接丢失并从传递的 serverName
重新创建新连接而不用等到 maxLifeTime
过期了吗?
我尝试了什么: 我将 maxLifeTime
设置为 2 分钟。在最坏的情况下,我的应用程序将关闭 2 分钟,直到建立新连接。但是将它设为 2 分钟,我们指示 HikariCP 每 2 分钟建立一次新连接。这是一个好方法吗?我看到有人建议给一个值介于 15-20 分钟之间或小于数据库连接 maxLifeTime
.
的值
P.S。该应用程序在 clojure-1.7、HikariCP-1.7、postgres-9.6
编辑:澄清为什么我将数据库放在 CNAME 后面是为了创建与具有多 AZ 环境的 AWS RDS 类似的设置,如果主数据库用于备份,另一个数据库开始为请求提供服务。
Is there a way for the HikariCP to find out if the connection is lost and need to recreate fresh connections from the passed serverName without waiting till expiring of maxLifeTime reaches?
当您更改 CNAME 时,之前命名的数据库(及其连接)仍然存在,对吧?我假设当 DNS 更改时连接并不是真的 lost; CNAME 只是指向不同的数据库 replica/instance。 HikariCP 不检查 DNS 记录是否已更改,它只关心连接是否有效。
这里有一个想法:您可以在程序中使用其他线程轮询 CNAME 更改,并在发生更改时在您的池中调用 softEvictConnections()
。这将立即关闭任何 idle/reservable 连接并将任何其他连接标记为逐出。
或者如果您手动更改 CNAME,我想您可以手动戳您的应用程序来执行此操作,而不是从内部进行轮询。
如果您想在发生这种情况时停止您的数据库访问,您也可以 suspendPool()
和 resumePool()
。
你的答案在这里... Setting the JVM TTL for DNS Name Lookups.
简而言之,如果 JVM 长时间缓存 DNS 查找,HikariCP 将无能为力。您需要在 JVM 级别解决这个问题。此外,上游 DNS 服务器的 TTL 也会产生重大影响——也会缓存直到本机 DNS TTL 过期。
编辑:抱歉,我错过了问题的关键部分。正如 Taylor 所说,您可以暂停池(您需要启用 allowPoolSuspension
),软逐出连接,然后恢复池。在驱逐时 "in-flight" 的连接将正常完成,然后在 return 到池时立即被驱逐。
在我们的应用程序中,我们将 HikariCP 与 Postgres 结合使用。应用程序通过 CNAME 连接到 DB(DB 在 CNAME 后面)。
将 CNAME 的值更改为不同的数据库(在我们的例子中,副本被提升为主)不会反映在我们的连接池中。查询仍然尝试从旧数据库中获取数据。 HikariCP 仅在 maxLifeTime
结束或我们重新启动应用程序时进行更改。
maxLifeTime
设置为30分钟,idleTimeout
设置为10分钟(这是HikariCP的默认值)。
问题: 有没有办法让 HikariCP 发现连接丢失并从传递的 serverName
重新创建新连接而不用等到 maxLifeTime
过期了吗?
我尝试了什么: 我将 maxLifeTime
设置为 2 分钟。在最坏的情况下,我的应用程序将关闭 2 分钟,直到建立新连接。但是将它设为 2 分钟,我们指示 HikariCP 每 2 分钟建立一次新连接。这是一个好方法吗?我看到有人建议给一个值介于 15-20 分钟之间或小于数据库连接 maxLifeTime
.
P.S。该应用程序在 clojure-1.7、HikariCP-1.7、postgres-9.6
编辑:澄清为什么我将数据库放在 CNAME 后面是为了创建与具有多 AZ 环境的 AWS RDS 类似的设置,如果主数据库用于备份,另一个数据库开始为请求提供服务。
Is there a way for the HikariCP to find out if the connection is lost and need to recreate fresh connections from the passed serverName without waiting till expiring of maxLifeTime reaches?
当您更改 CNAME 时,之前命名的数据库(及其连接)仍然存在,对吧?我假设当 DNS 更改时连接并不是真的 lost; CNAME 只是指向不同的数据库 replica/instance。 HikariCP 不检查 DNS 记录是否已更改,它只关心连接是否有效。
这里有一个想法:您可以在程序中使用其他线程轮询 CNAME 更改,并在发生更改时在您的池中调用 softEvictConnections()
。这将立即关闭任何 idle/reservable 连接并将任何其他连接标记为逐出。
或者如果您手动更改 CNAME,我想您可以手动戳您的应用程序来执行此操作,而不是从内部进行轮询。
如果您想在发生这种情况时停止您的数据库访问,您也可以 suspendPool()
和 resumePool()
。
你的答案在这里... Setting the JVM TTL for DNS Name Lookups.
简而言之,如果 JVM 长时间缓存 DNS 查找,HikariCP 将无能为力。您需要在 JVM 级别解决这个问题。此外,上游 DNS 服务器的 TTL 也会产生重大影响——也会缓存直到本机 DNS TTL 过期。
编辑:抱歉,我错过了问题的关键部分。正如 Taylor 所说,您可以暂停池(您需要启用 allowPoolSuspension
),软逐出连接,然后恢复池。在驱逐时 "in-flight" 的连接将正常完成,然后在 return 到池时立即被驱逐。