具有c3p0数据库池和故障转移功能的Spring Boot JDBCTemplate

时间:2018-06-25 12:30:48

标签: java spring-boot jdbc spring-jdbc c3p0

我需要在ibatis的SpringBoot应用程序(嵌入式tomcat)中使用j3c0建立连接连接池的jdbctemplate建立数据库连接故障转移。下面是我的应用程序的applicaiton.properties。我有主数据库和辅助数据库。如果主数据库失败,那么辅助数据库应该用于运行时的数据库连接故障转移。请帮助我实现这一目标。我尝试在配置中包含多个数据库URL,但无法正常工作。

c3p0 Java Database Pooling, failover configuration https://docs.genesys.com/Documentation/Composer/8.1.4/Help/ConnectionPooling

application.properties :(错误即将来临)

#      connection properties for data source
##########################################################################################################
spring.datasource.c3p0.driverClass=oracle.jdbc.driver.OracleDriver
spring.datasource.c3p0.maxConnectionAge=3600
spring.datasource.c3p0.maxIdleTime=600
spring.datasource.c3p0.initialPoolSize=5
spring.datasource.c3p0.maxPoolSize=10
spring.datasource.c3p0.minPoolSize=5
spring.datasource.c3p0.acquireIncrement=1

##########################################################################################################


spring.datasource.url=jdbc:oracle:thin:@primary.com:1521:db1,jdbc:oracle:thin:@secondary.com:1521:db2
spring.datasource.username=user
spring.datasource.password=password

2 个答案:

答案 0 :(得分:5)

据我所知,故障转移配置取决于JDBC驱动程序。如果是Oracle,则可以使用连接描述符对其进行配置。因此,根据您的情况,您可以将其放在tnsnames.ora中:

CONNECTION_WITH_FAILOVER = 
    (DESCRIPTION =
        (ADDRESS_LIST =
            (ADDRESS = (PROTOCOL = TCP)(HOST = primary.com)(PORT = 1521))
            (ADDRESS = (PROTOCOL = TCP)(HOST = secondary.com)(PORT = 1521))
            (LOAD_BALANCE = no)
            (FAILOVER = yes)
        )
        (CONNECT_DATA =
            (SERVER = DEDICATED)
            (SERVICE_NAME = db)
            (FAILOVER_MODE =
                (TYPE = select)
                (METHOD = preconnect)
                (RETRIES = 180)
                (DELAY = 10)
            )
        )
    )

,然后在您的配置中:

spring.datasource.url=jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER 

当然,您可能没有或不想使用tnsnames.ora,在这种情况下,可以将连接描述符用作JDBC连接字符串的一部分:

spring.datasource.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=primary.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=secondary.com)(PORT=1521))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=180)(DELAY=10))))

有关连接描述符,tnsnames.ora和为Oracle DB配置故障转移的更多详细信息,请参见以下链接:

请注意,所有数据库上的服务名称都必须相同,因此我将您配置中的db1db2替换为db

如果要使用其他服务名称,则必须以编程方式配置单独的数据源(如Sheetal Mohan Sharma所述)。

编辑:

  • 所收到的错误表明您正在尝试连接到服务器上不存在的服务名称-更多here
  • 我今天更加仔细地阅读了文档(尤其是我上面链接的PDF),似乎可以在连接字符串中指定辅助服务名称,因此在您的情况下,tnsnames.ora中的条目为:

    CONNECTION_WITH_FAILOVER =     (说明=         (ADDRESS_LIST =             (地址=(协议= TCP)(主机= primary.com)(端口= 1521))             (地址=(协议= TCP)(主机= secondary.com)(端口= 1521))             (LOAD_BALANCE =否)             (FAILOVER =是)         )         (CONNECT_DATA =             (服务器=专用)             (SERVICE_NAME = db1)             (FAILOVER_MODE =                 (TYPE =选择)                 (方法=预连接)                 (重试= 180)                 (延迟= 10)                 (备份= db2)             )         )     )

并作为application.properties中的JDBC URL:

spring.datasource.url=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=primary.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=secondary.com)(PORT=1521))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=db1)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=180)(DELAY=10)(BACKUP = db2))))
  • 我目前没有配置此类设置,因此将其放在tnsnames.ora中:

    CONNECTION_WITH_FAILOVER =     (说明=         (ADDRESS_LIST =             (地址=(协议= TCP)(主机= google.com)(端口= 1521))             (地址=(协议= TCP)(主机=我的实际数据库)(端口=我的数据库端口))             (LOAD_BALANCE =否)             (FAILOVER =是)         )         (CONNECT_DATA =             (服务器=专用)             (SERVICE_NAME =我的服务名称)             (FAILOVER_MODE =                 (TYPE =选择)                 (方法=预连接)                 (重试= 1)                 (延迟= 1)             )         )     )

模拟主要连接失败(因为显然没有在google.com上运行Oracle DB),并设法通过DataGrip使用连接URL:jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER

连接到我的数据库

我也直接在JDBC URL中使用连接描述符尝试了此操作:

jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=google.com)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=my-actual-database)(PORT=my-db-port))(LOAD_BALANCE=no)(FAILOVER=yes))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=my-service-name)(FAILOVER_MODE=(TYPE=select)(METHOD=preconnect)(RETRIES=1)(DELAY=5))))

它也能正常工作,尽管两次建立连接都花了很多时间(但这可能与我的网络配置或驱动程序的连接超时值有关)

  • 确保配置FAILOVER_MODE参数以满足您的需要-特别考虑RETIRES和DELAY值-在我提供的示例中,我使用了180次重试和两次重试之间的延迟,此外,每次连接超时重试,驱动程序实际切换到故障转移连接可能需要很长时间。

答案 1 :(得分:1)

您需要定义两组属性并分别引用它们-注意 url

#set1
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30

#set2
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.maximum-pool-size=30

但是,如果您对JDBC或JPA使用默认的自动配置,则可以将其中一个标记为@Primary(然后,任何@Autowired注入都会使用其中的一个)。

ref-Spring docs

@Bean
@Primary
@ConfigurationProperties(prefix="datasource.primary")
public DataSource primaryDataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
@ConfigurationProperties(prefix="datasource.secondary")
public DataSource secondaryDataSource() {
    return DataSourceBuilder.create().build();
}

您还可以参考分步指南here