2017-04-21 91 views
0

我试图建立一个引用我们的主数据库的连接池,直到它变得不健康,然后池发生故障转移,填满我们的备份。到现在为止我一直在服用我们的应用程序服务器的JNDI数据源的无证功能,让我正是如此指定2 JDBC连接URL字符串的优势:具有主数据库/备份数据库的单个JDBC OracleDataSource/HikariCP

jdbc:oracle:thin:@primary:1521:DB|jdbc:oracle:thin:@backup:1521:DB 

我有下面的代码,无疑部分地从一些阿光那儿剽窃/几个月前的Spring文档。

@Bean(name = "dataSource") 
public DataSource dataSource() throws SQLException { 
    String userName = "user"; 
    String password = "pass"; 
    String server = "primary"; 
    String database = "DB"; 

    OracleDataSource ods = new OracleDataSource(); 
    ods.setServerName(server); 
    ods.setDatabaseName(database); 
    ods.setNetworkProtocol("tcp"); 
    ods.setUser(userName); 
    ods.setPassword(password); 
    ods.setPortNumber(1521); 
    ods.setDriverType("thin"); 

    HikariConfig hkConfig = new HikariConfig(); 
    hkConfig.setDataSource(ods); 
    hkConfig.setDataSourceClassName("oracle.jdbc.pool.OracleDataSource"); 
    hkConfig.setPoolName("springHikariRECPool"); 
    hkConfig.setMaximumPoolSize(15); 
    hkConfig.setMinimumIdle(3); 
    hkConfig.setMaxLifetime(1800000); // 30 minutes 

    return new HikariDataSource(hkConfig); 
} 

我的Google-Fu失败了我。有没有人有关于如何实现故障转移功能的任何想法?

编辑 - 重新。 @M。 Deinum“删除OracleDataSource的构建,并在HikariConfig上设置url。”

HikariConfig hkConfig = new HikariConfig(); 
hkConfig.setUsername(userName); 
hkConfig.setPassword(password); 
hkConfig.setJdbcUrl("jdbc:oracle:thin:@primary:1521:DB|jdbc:oracle:thin:@backup:1521:DB"); 
hkConfig.setDataSourceClassName("oracle.jdbc.pool.OracleDataSource"); 
hkConfig.setPoolName("springHikariRECPool"); 
hkConfig.setMaximumPoolSize(15); 
hkConfig.setMinimumIdle(3); 
hkConfig.setMaxLifetime(1800000); 

不幸的是,这会产生一个相当长的堆栈,它的基础是这样的:

Caused by: java.sql.SQLException: Invalid Oracle URL specified: OracleDataSource.makeURL 
    at oracle.jdbc.pool.OracleDataSource.makeURL(OracleDataSource.java:1277) 
    at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:185) 
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:356) 
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:199) 
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:444) 
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:515) 

here - Hikaricp Oracle connection issue的调查here - Invalid Oracle URL specified: OracleDataSource.makeURL使我增加一些额外的属性。

hkConfig.addDataSourceProperty("portNumber", "1521"); 
hkConfig.addDataSourceProperty("driverType", "thin"); 

现在用炸弹:

Caused by: java.net.UnknownHostException: null: Name or service not known 
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) 
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) 
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) 
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1192) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1126) 
    at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:117) 
    at oracle.net.nt.ConnOption.connect(ConnOption.java:133) 
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:370) 

的JDBC URL不再被引用,它会出现。 。 。并确认 - 我从URL中取出了备份连接字符串,并通过标准的单一服务器连接到达了相同的异常。因此,看起来ODS需求被配置为最初完成(或模仿属性)。

至于该方法的最后关头,我想设置为ServerName属性“初级|待机”,正如预期的那样,炸毁了还有:

Caused by: java.net.UnknownHostException: primary|backup: Name or service not known 
    at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) 
    at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:928) 
    at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1323) 
    at java.net.InetAddress.getAllByName0(InetAddress.java:1276) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1192) 
    at java.net.InetAddress.getAllByName(InetAddress.java:1126) 
    at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:117) 
    at oracle.net.nt.ConnOption.connect(ConnOption.java:133) 
    at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:411) 
    ... 56 more 

我未能远,从而注意我正在使用ojdbc7.jar

+0

删除'OracleDataSource'的构造,并在'HikariConfig'上设置url。 –

+0

@ M.Deinum问题在回复中更新。感谢您的输入。 –

回答

1

使用标准方式。支持DataGuard,故障转移,RAC是Oracle JDBC驱动程序的本地功能。

这里描述"How to connect JDBC to tns oracle"

第二采用多台主机tnsnames.ora中第一次使用的tnsnames.ora:

DB = 
(DESCRIPTION= 
(ADDRESS_LIST= 
    (LOAD_BALANCE=off) 
    (FAILOVER=ON) 
    (ADDRESS=(PROTOCOL=TCP)(HOST=primary)(PORT=1521)) 
    (ADDRESS=(PROTOCOL=TCP)(HOST=backup)(PORT=1521))) 
(CONNECT_DATA=(SERVICE_NAME=DB))) 

Oracle JDBC驱动程序会连接到主机,其中数据库是 “OPEN” 和名为“DB”的服务存在。 PS:您也可以将整个tns连接字符串作为参数直接传递给jdbc驱动程序。

url="jdbc:oracle:thin:@(DESCRIPTION= 
    (LOAD_BALANCE=on) 
    (ADDRESS_LIST= 
    (ADDRESS=(PROTOCOL=TCP)(HOST=primary)(PORT=1521)) 
    (ADDRESS=(PROTOCOL=TCP)(HOST=secondary)(PORT=1521))) 
    (CONNECT_DATA=(SERVICE_NAME=DB)))" 
+0

我会喜欢一个'简单'版本,不包括安装Oracle客户端等,但似乎确实是另一种路径。它是中间件或客户端。谢谢! –