代码之家  ›  专栏  ›  技术社区  ›  sunleo

带c3p0数据库池和故障转移的spring-boot jdbctemplate

  •  6
  • sunleo  · 技术社区  · 6 年前

    我需要用jdbtemplate在ibatis的springboot应用程序(嵌入式tomcat)中建立db connection failover,jdbtemplate使用c3p0进行连接池。下面是我的应用程序的applicaton.properties。我有主数据库和辅助数据库。如果主数据库失败,那么应该在运行时使用辅助数据库进行db connection failover。请帮助我实现这一点。我试图在配置中包含多个数据库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 回复  |  直到 6 年前
        1
  •  6
  •   Konrad Botor    6 年前

    据我所知,故障转移配置依赖于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 
    

    当然,您可能没有或不想使用 特恩斯纳姆斯·奥拉 ,在这种情况下,可以将连接描述符用作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))))
    

    有关连接描述符的详细信息,请参见这些链接, 特恩斯纳姆斯·奥拉 以及为Oracle DB配置故障转移:

    注意,所有数据库上的服务名称必须相同,所以我替换了 db1 db2 从您的配置 db 是的。

    如果要使用不同的服务名,必须以编程方式配置不同的数据源(如sheetal mohan sharma所述)。

    编辑:

    • 收到的错误表明您正试图连接到服务器上不存在的服务名称-更多 here
    • 我今天重读文档(特别是上面链接的PDF),并且似乎可以在连接字符串中指定辅助服务名称,因此在您的情况下,TnNAMS.ORA中的条目将是:

      带故障转移的连接= (说明= (地址列表= (地址=(协议=TCP)(主机=primary.com)(端口=1521)) (地址=(协议=TCP)(主机=secondary.com)(端口=1521)) (负载平衡=否) (故障转移=是) ) (连接数据= (服务器=专用) (服务名称=db1) (故障转移模式= (类型=选择) (方法=预连接) (重试次数=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中:

      带故障转移的连接= (说明= (地址列表= (地址=(协议=TCP)(主机=谷歌.com)(端口=1521)) (地址=(协议=TCP)(主机=我的实际数据库)(端口=我的数据库端口) (负载平衡=否) (故障转移=是) ) (连接数据= (服务器=专用) (服务名=我的服务名) (故障转移模式= (类型=选择) (方法=预连接) (重试次数=1) (延迟=1) ) ) )

    要模拟主连接失败(因为google.com上显然没有运行oracle db),并使用连接url通过datagrip连接到我的数据库: jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER

    我还尝试了直接在jdbc url中使用connect描述符:

    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 参数以满足您的需要-特别考虑失效和延迟值-在我提供的示例中,我使用了180次重试和10秒重试之间的延迟,再加上每次重试时的连接超时,在驱动程序真正切换到故障转移连接之前可能需要很长时间。
        2
  •  1
  •   Sheetal Mohan Sharma    6 年前

    您需要定义两组属性并分别引用它们-请注意 网址 钥匙

    #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的默认自动配置,则可以将其中的一个标记为“主”(然后将由任何“自动注销”来获取)。

    参考- 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 是的。