【问题标题】:How to allow Tomcat to connect to more than one Databases?如何让 Tomcat 连接多个数据库?
【发布时间】:2014-08-21 23:49:55
【问题描述】:

我们有两个具有相同数据的生产数据库,并且一个 tomcat 服务器当前将连接到其中一个以提供 Web 服务。

生产数据库将一次更新(需要相当长的时间)。因此,为了最大限度地减少停机时间,我们必须在运行更新时手动切换到另一个数据库。这是一个相当繁琐的过程。

所以问题是数据源层中是否存在任何负载平衡/容错以允许这种情况自动发生?即,当一个数据库关闭时,会自动使用另一个数据库。

我们用的是Oracle数据库,也想知道是不是可以在数据库连接层做点什么。

为了澄清,我们只需要对数据库的读取权限,因此不涉及任何事务。

【问题讨论】:

  • 为什么不使用好的旧数据库集群?
  • 您目前如何告诉 Tomcat 连接到其中一个?如果 Tomcat 只连接到其中一个,这两个数据库如何使用?

标签: java database oracle tomcat datasource


【解决方案1】:

我会强烈建议反对任何引入Java 实现与数据源之间的耦合的解决方案并坚持遵循关注点分离的原则。

具体来说,我会设置一个 TCP 代理(如 HAProxy)来平衡您的两个 Oracle 数据库并配置 Tomcat 以连接到代理。这样一来,如果您在 HAProxy 中启用这两个数据库,并且如果您需要单独升级它们,您将获得负载平衡,您只需在代理中一次干净地将它们分阶段关闭,而 Tomcat 不会注意到任何事情。

如果您不需要负载平衡,代理仍可用于直接连接到一个或另一个数据库。

当然,根据您的问题,主-主复制也可能值得研究。不过,这不会抹黑使用代理。高温


备注:如果您在 Tomcat 中使用连接池,则需要注意一些细节。即,将池配置为定期执行空闲连接的保活 ping,并确保频率低于代理的频率。否则代理可能会在池注意到它之前默默地破坏连接。小伙子,调试起来简直就是一场噩梦。


FWIW,看看这个walkthrough 用两个 MySQL 服务器设置 HAProxy。使用 Oracle 应该不会差太多。

【讨论】:

    【解决方案2】:

    据我了解,这并不容易,你应该非常小心。 我将解释一个想法,我们使用了一些东西来提醒我你的问题。

    因此,如果您不想使用某些特定于数据库的解决方案(我敢肯定,Oracle 在这里可以提供一些东西),您可能希望在 java 层实现它。 基本上你应该实现自己的数据源,它比现成的数据源更智能。

    基本上,数据源背后的主要思想是根据请求提供连接。 因此,当第一个数据库进行维护时,应该通知数据源(可能是手动或其他,您需要开发一些功能),然后对数据源的所有后续请求都将被重定向到新数据库。

    class MyDatasource implements javax.sql.DataSource {
    
        private DataSource firstDatasource = ...;
        private DataSource secondDatasource = ...;
    
        private boolean isMainDbAccessible = true; 
    
        public Connection getConnection() {
               if(isMainDbAccessible) {
    
                  return firstDatasource.getConnection();
               }
               else {
                  return secondDatasource.getConnection();
               }
        }
    
        public void startMainDbMaintenance() {
             isMainDbAccessible = false;
             // maybe you should passivate somehow the first DS, like close its connections and so forth
        }
    
        public void endMainDbMaintenance() {
            isMainDbAccessible = true;
            // again, check the connections state here
        }
    }
    

    技术实现实际上取决于您实际使用数据源的方式,您是否定义了特定于 tomcat 的 Resource 并从 JNDI 获取数据源?或者,也许您在这里不使用 tomcat,而是使用提供对数据源的访问权限的 Spring? 有很多可能的配置,所以我不能在这里更具体。

    但我想,你已经明白了。

    顺便说一句,类似的解决方案也可以在 Java Driver 级别实现(维护 2 个驱动程序实例)

    希望对你有帮助

    【讨论】:

      【解决方案3】:

      更安全的方法是在 Oracle 数据库端启用故障转移支持,因为您可以从 Oracle 数据库开箱即用地获得更好的连接/会话管理,而不必在 Jdbc 数据源级别进行处理。

      有一个很好的blog post

      【讨论】:

        猜你喜欢
        • 2010-12-27
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2010-09-06
        • 2015-06-23
        • 1970-01-01
        • 2014-06-03
        • 1970-01-01
        相关资源
        最近更新 更多