Spring Boot JPA - otomatik yeniden bağlanmayı yapılandırma


107

Küçük bir Spring Boot JPA web uygulamam var. Amazon Beanstalk üzerinde dağıtılır ve verilerin kalıcı olması için bir Amazon RDS kullanır. Bununla birlikte, bu kadar sık ​​kullanılmaz ve bu nedenle, bu tür bir istisna dışında bir süre sonra başarısız olur:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Sunucudan başarıyla alınan son paket 79.870.633 milisaniye önceydi.
Sunucuya başarıyla gönderilen son paket 79.870.634 milisaniye önceydi. sunucu tarafından yapılandırılan 'wait_timeout' değerinden daha uzun. Bu sorunu önlemek için, uygulamanızda kullanmadan önce bağlantı geçerliliğini sona erdirmeyi ve / veya test etmeyi, istemci zaman aşımları için sunucuda yapılandırılmış değerleri artırmayı veya "autoReconnect = true" Bağlayıcı / J bağlantı özelliğini kullanmayı düşünmelisiniz.

Bu ayarı nasıl yapılandıracağımdan emin değilim ve bununla ilgili bilgileri http://spring.io'da bulamıyorum (yine de çok iyi bir site). Bilgiye yönelik bazı fikirler veya ipuçları nelerdir?


Bunu yazdırmak DataSourceve özelliklerini doğrulamak için kullanın . stackoverflow.com/a/36586630/148844 Bahar Boot değil otomatik olarak yapılandırır edecek DataSourceEğer varsa @Beansbir tanımladığımız DataSource. docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/…
Chloe

Yanıtlar:


141

Önyüklemenin DataSourcesizin için yapılandırdığını varsayıyorum . Bu durumda ve MySQL kullandığınız için aşağıdakileri application.properties1.3'e kadar ekleyebilirsiniz.

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

Djxak yorumunda belirtildiği gibi, dört bağlantı havuzları Yay önyükleme destekler için 1.4 + tanımlar özel ad alanları: tomcat, hikari, dbcp, dbcp2( dbcp1,5 itibariyle önerilmemektedir). Hangi bağlantı havuzunu kullandığınızı kontrol etmeniz ve bu özelliğin desteklenip desteklenmediğini kontrol etmeniz gerekir. Yukarıdaki örnek tomcat içindir, bu yüzden 1.4+ sürümünde aşağıdaki gibi yazmanız gerekir:

spring.datasource.tomcat.testOnBorrow=true 
spring.datasource.tomcat.validationQuery=SELECT 1

Kullanımı unutmayın autoReconnectedilir önerilmez :

Bu özelliğin kullanılması önerilmez, çünkü uygulamalar SQLExceptions'ı düzgün şekilde işlemediğinde oturum durumu ve veri tutarlılığı ile ilgili yan etkileri vardır ve yalnızca uygulamanızı SQLExceptions'dan kaynaklanan SQLExceptions'ı işleyecek şekilde yapılandıramadığınızda kullanılmak üzere tasarlanmıştır. ölü ve eski bağlantılar düzgün.


8
bunun nedeni, belgelere anahtar yazma şeklimizi uyumlu hale getirdik. Biz her zaman bir kullanılan rahat hem böylece bağlayıcı spring.datasource.testOnBorrowve spring.datasource.test-on-borrowsadece iyi çalışacaktır. Kontrol belgelere Daha fazla ayrıntı için.
Stephane Nicoll

17
Başkalarının kafasını karıştırabileceğinden: SELECT 1bağlantının uygulamaya teslim edilmeden önce test edildiğini garanti eder. Kullanılarak testOnBorrow = true, nesneler havuzdan ödünç alınmadan önce doğrulanacaktır. Nesne doğrulanamazsa, havuzdan düşürülecek ve başka bir nesneyi ödünç almaya çalışacaktır. NOT - Gerçek bir değerin herhangi bir etkiye sahip olması için, validationQuery parametresinin boş olmayan bir dizeye ayarlanması gerekir.
Rick

14
Uyarı! Bahar Boot yılında 1.4+ bu oldu değişti : Dört bağlantı havuzları bahar desteklerin için yeni spesifik ad alanlarını orada tanımlandı: tomcat, hikari, dbcp, dbcp2. Dolayısıyla, örneğin tomcat-jdbcbağlantı havuzu için özellikler şöyle olmalıdır: spring.datasource.tomcat.testOnBorrow=trueve spring.datasource.tomcat.validationQuery=SELECT 1.
Ruslan Stelmachenko

1
Kendim iki farklı veri kaynağını yapılandırıyorsam, bu yapılandırmayı nasıl sağlayabilirim? Spring.datasource.mydatasource1.tomcat.testOnBorrow = true spring.datasource.mydatasource1.tomcat.validationQuery = SELECT 1 spring.datasource.mydatasource2.tomcat.testOnBorrow = true spring.datasource gibi her iki veri kaynağı için bu yapılandırmayı sağlamam gerekir mi. mydatasource2.tomcat.validationQuery = SELECT 1 Veya izlenecek başka bir şey var mı?
Nitish Kumar

2
Uyarı! Eğer uygulamanızda herhangi DataSource @Bean tanımlarsanız Bahar Boot olmaz havuzu yapılandırın. docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/… If you define your own DataSource bean, auto-configuration will not occur. OAuth2 için bir kılavuzu izledim ve vardı @Bean(name = "OAuth") public DataSource secondaryDataSource()...ve otomatik olarak yapılandırılmadı veya kullanılmadı testOnBorrow.
Chloe

28

Yukarıdaki öneriler benim için işe yaramadı. Gerçekten işe yarayan şey, aşağıdaki satırların uygulamaya dahil edilmesiydi. Özellikler

spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

Açıklamayı burada bulabilirsiniz


5
Eklediğiniz bağlantıda, eğer veritabanı bağlantısı 8 saatten fazla bir süre aktif değilse, otomatik olarak kapatılır ve yukarıdaki hata meydana gelir. Bu nedenle, çözümünüz bağlantının daha uzun süre devre dışı kalmasına izin vermemektir. Yeniden başlatıldıktan sonra SQL sunucusuna bağlanabilmemin bir yolu var mı?
Akeshwar Jha

9

spring.datasource.tomcat.testOnBorrow=trueApplication.properties dosyasında ayarlama işe yaramadı.

Aşağıdaki gibi programatik olarak ayarlama herhangi bir sorun olmadan çalıştı.

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;    

@Bean
public DataSource dataSource() {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(this.properties.getDatabase().getUrl());         
    poolProperties.setUsername(this.properties.getDatabase().getUsername());            
    poolProperties.setPassword(this.properties.getDatabase().getPassword());

    //here it is
    poolProperties.setTestOnBorrow(true);
    poolProperties.setValidationQuery("SELECT 1");

    return new DataSource(poolProperties);
}

1
Özel bir veri kaynağı bildiriyorsanız, yay varsayılanı .tomcat'i kullanmaya çalışmanız olabilir. Bu nedenle, özel bir Veri Kaynağı çekirdeği oluşturursanız, @ConfigurationProperties (prefix = "spring.datasource.tomcat") DataSource çekirdeğine ekleyin ve ardından bunları uygulama özelliklerinde ayarlamanıza izin vermelidir. Örneğim .. @Bean (name = "managementDataSource") @ConfigurationProperties (prefix = "management.datasource") public DataSource dataSource () {return DataSourceBuilder.create (). Build (); } management.datasource.test-on-borrow = true
Justin

8

Spring Boot 1.4'e yeni taşındım ve bu özelliklerin yeniden adlandırıldığını gördüm:

spring.datasource.dbcp.test-while-idle=true
spring.datasource.dbcp.time-between-eviction-runs-millis=3600000
spring.datasource.dbcp.validation-query=SELECT 1

2
İsimler eşdeğerdir. Spring Boot belgelerindeki özellik adlandırma bölümüne bakın .
Stephen Harrison

@StephenHarrison: 1.4'te eklenen dbcp. * Önekine dikkat edin, bu durumda rahat bağlama geçerli değildir.
YM

1
@Pawel: Projenizde hangi havuzlama uygulamasının mevcut olduğuna bağlı olarak, sizin için dbcp. * Özellikleri olmayabilir , SQL ile Spring boot'a ve ilgili Veri kaynağı özelliklerine bakın
YM

4

whoami'nin cevabı doğru olanıdır. Özellikleri önerildiği gibi kullanarak bunu çalıştıramadım (Spring Boot 1.5.3.RELEASE kullanarak)

Cevabımı eksiksiz bir konfigürasyon sınıfı olduğu için ekliyorum, böylece Spring Boot'u kullanan birine yardımcı olabilir:

@Configuration
@Log4j
public class SwatDataBaseConfig {

    @Value("${swat.decrypt.location}")
    private String fileLocation;

    @Value("${swat.datasource.url}")
    private String dbURL;

    @Value("${swat.datasource.driver-class-name}")
    private String driverName;

    @Value("${swat.datasource.username}")
    private String userName;

    @Value("${swat.datasource.password}")
    private String hashedPassword;

    @Bean
    public DataSource primaryDataSource() {
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setUrl(dbURL);
        poolProperties.setUsername(userName);
        poolProperties.setPassword(password);
        poolProperties.setDriverClassName(driverName);
        poolProperties.setTestOnBorrow(true);
        poolProperties.setValidationQuery("SELECT 1");
        poolProperties.setValidationInterval(0);
        DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
        return ds;
    }
}

Bu özel koda neden ihtiyaç duyulduğunu ve Spring'in neden bu özellikleri özellikler dosyasından okumadığını biliyor musunuz? Dosyamda birkaç veri kaynağı özelliği var ve geri kalanını sorunsuz bir şekilde okuyor.
Uncle Long Hair

3

Benim de benzer bir problemim var. Spring 4 ve Tomcat 8. Sorunu Spring konfigürasyonuyla çözüyorum

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
    <property name="initialSize" value="10" />
    <property name="maxActive" value="25" />
    <property name="maxIdle" value="20" />
    <property name="minIdle" value="10" />
     ...
    <property name="testOnBorrow" value="true" />
    <property name="validationQuery" value="SELECT 1" />
 </bean>

Test ettim. İyi çalışıyor! Bu iki satır, veritabanına yeniden bağlanmak için her şeyi yapar:

<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />

3

Herhangi birinin özel DataSource kullanması durumunda

@Bean(name = "managementDataSource")
@ConfigurationProperties(prefix = "management.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

Özellikler aşağıdaki gibi görünmelidir. Önekli @ConfigurationProperties'e dikkat edin. Ön ek, gerçek mülk adından önceki her şeydir

management.datasource.test-on-borrow=true
management.datasource.validation-query=SELECT 1

Yay Sürümü 1.4.4 için bir referans.


2

Bazı kişilerin daha önce de belirttiği gibi, yaylı önyükleme 1.4+, dört bağlantı havuzu için belirli ad alanlarına sahiptir. Hikaricp varsayılan olarak 2+ yaylı önyüklemede kullanılır. Yani burada SQL'i belirtmeniz gerekecek. Varsayılan değer SELECT 1. Örneğin, DB2 için ihtiyacınız olan şeyler: spring.datasource.hikari.connection-test-query=SELECT current date FROM sysibm.sysdummy1

Uyarı : Sürücünüz JDBC4'ü destekliyorsa, bu özelliği ayarlamamanızı kesinlikle öneririz. Bu, JDBC4 Connection.isValid () API'yi desteklemeyen "eski" sürücüler içindir. Bu, veritabanına bağlantının hala canlı olduğunu doğrulamak için havuzdan size bir bağlantı verilmeden hemen önce yürütülecek sorgudur. Tekrar, havuzu bu özellik olmadan çalıştırmayı deneyin, HikariCP, sürücünüz size bildirmek için JDBC4 uyumlu değilse bir hata günlüğe kaydedecektir. Varsayılan: yok


0

Birden fazla veri kaynağıyla YAML'den yapmak isteyenler için, bununla ilgili harika bir blog yazısı var: https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot -uygulama/

Temel olarak, hem veri kaynağı özelliklerini hem de veri kaynağını şu şekilde yapılandırmanız gerektiğini söylüyor:

@Bean
@Primary
@ConfigurationProperties("app.datasource.member")
public DataSourceProperties memberDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.member.hikari")
public DataSource memberDataSource() {
    return memberDataSourceProperties().initializeDataSourceBuilder()
            .type(HikariDataSource.class).build();
}

@PrimaryDiğer veri kaynaklarından çıkarmayı unutmayın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.