我们有两个具有相同数据的生产数据库,并且tomcat服务器当前将连接到其中一个以提供Web服务。
生产数据库将一次更新(需要相当长的时间才能完成)。因此,为了最大限度地减少停机时间,我们必须在运行更新时手动切换到其他数据库。这是一个相当繁琐的过程。
所以问题是DataSource层中是否存在任何负载平衡/容错,以允许这种情况自动发生?即,当一个数据库关闭时,另一个数据库将自动使用。
我们正在使用Oracle数据库,也想知道它是否可以在数据库连接层中完成。
为了澄清,我们只需要对数据库的读访问权限,因此不涉及任何事务。
答案 0 :(得分:2)
我强烈建议 反对 在Java实现和数据源之间引入耦合的任何解决方案分离关注点的原则。
具体来说,我设置了一个TCP代理(如HAProxy)来对两个Oracle数据库进行负载平衡,并配置Tomcat连接到代理。这样,如果您在HAProxy中启用两个数据库,并且需要单独升级它们,您将获得负载平衡,您只需在代理中一次一个地清除它们,而Tomcat不会注意到任何内容。
如果您不需要负载平衡,代理仍然可以用于指向一个数据库或另一个数据库的连接。
当然,根据您的问题,主 - 主复制也可能值得研究。但是,这并不会使用代理进行诋毁。 HTH
备注:如果您在Tomcat中使用连接池,则需要注意细节。即,配置池以定期执行空闲连接的保持活动ping,并确保频率低于代理的频率。否则,代理可能会在池注意到之前以静默方式销毁连接。那个小伙子,是调试的噩梦。
FWIW ,看一下这个walkthrough,用两台MySQL服务器设置HAProxy。使用Oracle不应该与它相去甚远。
答案 1 :(得分:0)
更安全的方法是在Oracle数据库端启用故障转移支持,因为您可以从Oracle数据库中获得更好的连接/会话管理,而不必在Jdbc DataSource级别处理它。
有一个很好的blog post。
答案 2 :(得分:0)
据我了解,这并不容易,你应该非常小心这样做。 我会解释一个想法,我们使用的东西让我想起你的问题。
因此,如果您不想使用某些特定于数据库的解决方案(我确定,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的资源并从JNDI获取数据源?或许你可能不会在这里使用tomcat,而是使用Spring来提供对数据源的访问? 有很多可能的配置,所以我不能在这里更具体。
但我想,你已经明白了。
顺便说一下,类似的解决方案也可以在Java Driver级别实现(维护2个驱动程序实例)
希望这有帮助