Spring Boot JDBCTemplate с пулированием базы данных c3p0 и отработкой отказа - PullRequest
0 голосов
/ 25 июня 2018

Мне нужно установить соединение с БД в приложении SpringBoot (внедренный tomcat) для ibatis с jdbctemplate, который использует c3p0 для пула соединений. Ниже приведены значения applicationaiton.property моего приложения. У меня есть первичные и вторичные базы данных. Если первичные сбои, то вторичные должны использоваться для аварийного переключения соединения с БД во время выполнения. Пожалуйста, помогите мне добиться этого. Я попытался включить несколько URL БД как часть конфигурации, но это не работает.

c3p0 Объединение в пул базы данных Java, настройка отработки отказа 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 голосов
/ 27 июня 2018

Насколько я знаю, конфигурация отработки отказа зависит от драйвера 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:

Обратите внимание, что службаимя должно быть одинаковым во всех базах данных, поэтому я заменил db1 и db2 из вашей конфигурации на db.

Если вы хотите иметь разные имена служб, вы должны настроитьотдельные источники данных программно (как описано Sheetal Mохан Шарма).

Редактировать:

  • Полученная ошибка указывает на то, что вы пытаетесь подключиться к имени службы, которая не существует на сервере - подробнее здесь
  • Сегодня я перечитал документацию (в частности, PDF-файл, на который я ссылался выше) более внимательно, и кажется, что в строке подключения можно указать дополнительное имя службы, так что в вашем случаезапись в tnsnames.ora будет выглядеть следующим образом:

    CONNECTION_WITH_FAILOVER = (ОПИСАНИЕ = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = primary.com) (PORT = 1521)) (ADDRESS = (PROTOCOL = TCP) (HOST = second.com) (PORT = 1521)) (LOAD_BALANCE = нет) (FAILOVER = да)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = db1) (FAILOVER_MODE = (TYPE = select) (METHOD = preconnect) (RETRIES = 180) (DELAY = 10) (BACKUP = db2))))

и в виде URL JDBC в application.properties:

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 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP) (HOST = google.com) (PORT = 1521)) (ADDRESS = (PROTOCOL = TCP) (HOST =my-actual-database) (PORT = my-db-port)) (LOAD_BALANCE = нет) (FAILOVER = yes)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = my-service-name) (FAILOVER_MODE = (TYPE =выберите) (METHOD = preconnect) (RETRIES = 1) (DELAY = 1))))

для имитации основного сбоя соединения (поскольку очевидно, что на google.com не работает Oracle DB)) и мне удалось подключиться к моей базе данных с помощью DataGrip, используя URL-адрес подключения: jdbc:oracle:thin:@CONNECTION_WITH_FAILOVER

Я также попытался выполнить это с дескриптором подключения непосредственно в URL-адресе JDBC:

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 попыток и 10 секундную задержку между попытками, добавив к этому тайм-аут соединения при каждой повторной попытке, и может потребоваться очень много времени, прежде чем драйвер фактическипереключается на аварийное соединение.
0 голосов
/ 27 июня 2018

Вам необходимо определить 2 набора свойств и ссылаться на них отдельно - обратите внимание на разницу в url keys

#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

Но вы можете пометить одно из них как @Primary, если выиспользуя автоматическую конфигурацию по умолчанию для JDBC или JPA (тогда она будет выбрана любыми инъекциями @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();
}

Вы также можете обратиться к пошаговой инструкции здесь .

...