Come configuro HikariCP nella mia app Spring Boot nei miei file application.properties?

Sto cercando di configurare HikariCP nella mia app Spring Boot (1.2.0.M1) in modo da poter testare l’utilizzo al posto di Tomcat DBCP. Mi piacerebbe configurare il pool di connessioni nel mio file application.properties come stavo facendo con Tomcat, ma non riesco a capire come dovrei farlo. Tutti gli esempi che ho trovato mostrano uno stile di JavaConfig o l’utilizzo di un file di proprietà HikariCP separato. Qualcuno può aiutarmi a capire i nomi delle proprietà per configurarlo in application.properties? Mi piacerebbe anche passare dall’utilizzo dell’approccio driverClassName all’approccio DataSourceClassName poiché sembra più pulito e consigliato. Questo è anche ansible nei miei file application.properties?

Ecco cosa ho avuto per Tomcat DBCP (solo alcune configurazioni di base, non completamente svuotate)

spring.datasource.validation-query=SELECT 1 spring.datasource.max-active=10 spring.datasource.max-idle=8 spring.datasource.min-idle=8 spring.datasource.initial-size=5 spring.datasource.test-on-borrow=true spring.datasource.test-on-return=true 

E attualmente sto utilizzando driverClassName e jdbc url per configurare la connessione:

 spring.datasource.url=jdbc:mysql://localhost:3306/myDb spring.datasource.driverClassName=com.mysql.jdbc.Driver 

 @Configuration @ConfigurationProperties(prefix = "params.datasource") public class JpaConfig extends HikariConfig { @Bean public DataSource dataSource() throws SQLException { return new HikariDataSource(this); } } 

application.yml

 params: datasource: driverClassName: com.mysql.jdbc.Driver jdbcUrl: jdbc:mysql://localhost:3306/myDb username: login password: password maximumPoolSize: 5 

AGGIORNATO! Dalla versione Spring Boot 1.3.0 :

  1. Basta aggiungere HikariCP alle dipendenze
  2. Configura application.yml

application.yml

 spring: datasource: type: com.zaxxer.hikari.HikariDataSource url: jdbc:h2:mem:TEST driver-class-name: org.h2.Driver username: username password: password hikari: idle-timeout: 10000 

AGGIORNATO! Dalla versione Spring Boot 2.0.0 :

Il pool di connessione predefinito è cambiato da Tomcat a Hikari 🙂

Potresti semplicemente utilizzare solo application.yml / application.properties. Non è necessario creare in modo esplicito alcun DataSource Bean

È necessario escludere tomcat-jdbc come menzionato da ydemartino

  org.springframework.boot spring-boot-starter-jdbc   org.apache.tomcat tomcat-jdbc    

Poiché non creerai bean DataSource , devi specificare esplicitamente l’uso di Hikari tramite spring.datasource.type con valore com.zaxxer.hikari.HikariDataSource in application.yml / application.properties

 spring: datasource: hikari: connection-test-query: SELECT 1 FROM DUAL minimum-idle: 1 maximum-pool-size: 5 pool-name: yourPoolName auto-commit: false driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/myDb username: login password: password type: com.zaxxer.hikari.HikariDataSource 

Nel tuo file application.yml / application.properties, puoi configurare parametri specifici di Hikari come la dimensione del pool ecc spring.datasource.hikari.*

Mi sono imbattuto in HikariCP e sono rimasto stupito dai benchmark e volevo provarlo al posto della mia scelta predefinita C3P0 e con mia sorpresa ho faticato per ottenere le configurations corrette probabilmente perché le configurazioni differiscono in base a quale combinazione di stack tecnologico si sta utilizzando.

Ho installato il progetto Spring Boot con JPA, Web, Security starters (usando Spring Initializer ) per usare PostgreSQL come database con HikariCP come pool di connessioni.
Ho usato Gradle come strumento di costruzione e mi piacerebbe condividere ciò che ha funzionato per me per le seguenti ipotesi:

  1. Spring Boot Starter JPA (Web & Security – opzionale)
  2. Costruisci anche Gradle
  3. PostgreSQL in esecuzione e installazione con un database (es. Schema, utente, db)

È necessario il seguente build.gradle se si utilizza Gradle o pom.xml equivalente se si utilizza Maven

 buildscript { ext { springBootVersion = '1.5.8.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'org.springframework.boot' apply plugin: 'war' group = 'com' version = '1.0' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-aop') // Exclude the tomcat-jdbc since it's used as default for connection pooling // This can also be achieved by setting the spring.datasource.type to HikariCP // datasource see application.properties below compile('org.springframework.boot:spring-boot-starter-data-jpa') { exclude group: 'org.apache.tomcat', module: 'tomcat-jdbc' } compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') runtime('org.postgresql:postgresql') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.springframework.security:spring-security-test') // Download HikariCP but, exclude hibernate-core to avoid version conflicts compile('com.zaxxer:HikariCP:2.5.1') { exclude group: 'org.hibernate', module: 'hibernate-core' } // Need this in order to get the HikariCPConnectionProvider compile('org.hibernate:hibernate-hikaricp:5.2.11.Final') { exclude group: 'com.zaxxer', module: 'HikariCP' exclude group: 'org.hibernate', module: 'hibernate-core' } } 

Ci sono un sacco di esclusioni nel build.gradle sopra e questo perché

  1. Prima esclusione, indica a gradle che esclude il pool di connessioni jdbc-tomcat durante il download delle dipendenze spring-boot-starter-data-jpa . Questo può essere ottenuto impostando spring.datasource.type=com.zaxxer.hikari.HikariDataSource ma, non voglio una dipendenza extra se non ne ho bisogno
  2. Second exclude, ordina a gradle di escludere hibernate-core quando scarica la dipendenza da com.zaxxer e questo perché hibernate-core è già stato scaricato da Spring Boot e non vogliamo finire con versioni diverse.
  3. Terza esclusione, ordina a gradle di escludere hibernate-core quando scarica il modulo hibernate-hikaricp che è necessario per fare in modo che HikariCP usi org.hibernate.hikaricp.internal.HikariCPConnectionProvider come provider di connessione invece di deprecato com.zaxxer.hikari.hibernate.HikariConnectionProvider

Una volta capito il build.gradle e cosa tenere e cosa no, ero pronto per copiare / incollare una configurazione di datasource nella mia application.properties e mi aspettavo che tutto funzionasse a build.gradle , ma non proprio e mi sono imbattuto in quanto segue problemi

  • Spring boot che non riesce a trovare i dettagli del database (es. Url, driver) quindi, non è in grado di configurare jpa e hibernate (perché non ho chiamato i valori delle chiavi di proprietà a destra)
  • HikariCP torna a com.zaxxer.hikari.hibernate.HikariConnectionProvider
  • Dopo aver istruito Spring a utilizzare il nuovo provider di connessione per la configurazione automatica di hibernate / jpa, HikariCP non è riuscito perché cercava qualche key/value application.properties e si lamentava di dataSource, dataSourceClassName, jdbcUrl . Ho dovuto eseguire il debug in HikariConfig, HikariConfigurationUtil, HikariCPConnectionProvider e HikariConfig, HikariConfigurationUtil, HikariCPConnectionProvider scoperto che HikariCP non poteva trovare le proprietà da application.properties perché era denominato diversamente.

Ad ogni modo, questo è il HikariCP per cui ho dovuto fare affidamento su prove ed errori e assicurarmi che HikariCP sia in grado di scegliere le proprietà (ad esempio l’origine dati che contiene i dettagli db, così come le proprietà di pool) e Sping Boot si comportano come previsto e sono finito con il seguente file application.properties .

 server.contextPath=/ debug=true # Spring data source needed for Spring boot to behave # Pre Spring Boot v2.0.0.M6 without below Spring Boot defaults to tomcat-jdbc connection pool included # in spring-boot-starter-jdbc and as compiled dependency under spring-boot-starter-data-jpa spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.url=jdbc:postgresql://localhost:5432/somedb spring.datasource.username=dbuser spring.datasource.password=dbpassword # Hikari will use the above plus the following to setup connection pooling spring.datasource.hikari.minimumIdle=5 spring.datasource.hikari.maximumPoolSize=20 spring.datasource.hikari.idleTimeout=30000 spring.datasource.hikari.poolName=SpringBootJPAHikariCP spring.datasource.hikari.maxLifetime=2000000 spring.datasource.hikari.connectionTimeout=30000 # Without below HikariCP uses deprecated com.zaxxer.hikari.hibernate.HikariConnectionProvider # Surprisingly enough below ConnectionProvider is in hibernate-hikaricp dependency and not hibernate-core # So you need to pull that dependency but, make sure to exclude it's transitive dependencies or you will end up # with different versions of hibernate-core spring.jpa.hibernate.connection.provider_class=org.hibernate.hikaricp.internal.HikariCPConnectionProvider # JPA specific configs spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.use_sql=true spring.jpa.properties.hibernate.id.new_generator_mappings=false spring.jpa.properties.hibernate.default_schema=dbschema spring.jpa.properties.hibernate.search.autoregister_listeners=false spring.jpa.properties.hibernate.bytecode.use_reflection_optimizer=false # Enable logging to verify that HikariCP is used, the second entry is specific to HikariCP logging.level.org.hibernate.SQL=DEBUG logging.level.com.zaxxer.hikari.HikariConfig=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE 

Come mostrato sopra, le configurazioni sono suddivise in categorie basate sui seguenti schemi di denominazione

  • spring.datasource.x (Spring auto-configure sceglierà questi, quindi HikariCP)
  • spring.datasource.hikari.x (HikariCP li seleziona per configurare il pool, annota i nomi dei campi camelCase)
  • spring.jpa.hibernate.connection.provider_class ( Indica a Spring di utilizzare il nuovo HibernateConnectionProvider)
  • spring.jpa.properties.hibernate.x (Utilizzato da Spring per configurare automaticamente JPA, annotare i nomi dei campi con caratteri di sottolineatura)

È difficile trovare un tutorial o un post o una risorsa che mostri come viene utilizzato il file delle proprietà sopra e come devono essere denominate le proprietà. Beh, il gioco è fatto.

Lanciare la suddetta application.properties con build.gradle (o almeno simile) in una versione del progetto JPA di Spring Boot (1.5.8) dovrebbe funzionare come un incantesimo e connettersi al database preconfigurato (nel mio caso è PostgreSQL che entrambi HikariCP & Spring escono da spring.datasource.url su quale driver di database usare).

Non ho visto la necessità di creare un bean DataSource e questo è dovuto al fatto che Spring Boot è in grado di fare tutto per me semplicemente esaminando application.properties e questo è pulito.

L’ articolo nel wiki github di HikariCP mostra come configurare Spring Boot con JPA ma manca di spiegazione e dettagli.

Il suddetto file è anche disponibile come un elenco pubblico https://gist.github.com/rhamedy/b3cb936061cc03acdfe21358b86a5bc6

Non hai bisogno di codice ridondante per mettere i valori delle proprietà alle variabili. È ansible impostare direttamente le proprietà con un file di proprietà.

Metti il ​​file hikari.properties nel classpath.

 driverClassName=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://localhost:3306/myDb connectionTestQuery=SELECT 1 maximumPoolSize=20 username=... password=... 

E creare un bean di origine dati come questo.

 @Bean(destroyMethod = "close") public DataSource dataSource() throws SQLException { HikariConfig config = new HikariConfig("/hikari.properties"); HikariDataSource dataSource = new HikariDataSource(config); return dataSource; } 

Questo funziona per la mia applicazione di avvio nel caso in cui aiuta. Questa class ti dice quali proprietà cerca l’object config:

https://github.com/brettwooldridge/HikariCP/blob/2.3.x/hikaricp-common/src/main/java/com/zaxxer/hikari/AbstractHikariConfig.java

Penso che più origini dati potrebbero supportare aggiungendo datasource_whatever alle chiavi di proprietà nel file di configurazione sorgente. Saluti!

 @Configuration class DataSourceConfig { @Value('${spring.datasource.username}') private String user; @Value('${spring.datasource.password}') private String password; @Value('${spring.datasource.url}') private String dataSourceUrl; @Value('${spring.datasource.dataSourceClassName}') private String dataSourceClassName; @Value('${spring.datasource.connectionTimeout}') private int connectionTimeout; @Value('${spring.datasource.maxLifetime}') private int maxLifetime; @Bean public DataSource primaryDataSource() { Properties dsProps = [url: dataSourceUrl, user: user, password: password] Properties configProps = [ connectionTestQuery: 'select 1 from dual', connectionTimeout: connectionTimeout, dataSourceClassName: dataSourceClassName, dataSourceProperties: dsProps, maxLifetime: maxLifetime ] // A default max pool size of 10 seems reasonable for now, so no need to configure for now. HikariConfig hc = new HikariConfig(configProps) HikariDataSource ds = new HikariDataSource(hc) ds } } 

È ansible utilizzare l’approccio dataSourceClassName, ecco un esempio con MySQL. (Testato con spring boot 1.3 e 1.4)

Per prima cosa è necessario escludere tomcat-jdbc dal classpath in quanto verrà scelto a favore di hikaricp.

pom.xml

   org.springframework.boot spring-boot-starter-jdbc   org.apache.tomcat tomcat-jdbc    

application.properties

 spring.datasource.dataSourceClassName=com.mysql.jdbc.jdbc2.optional.MysqlDataSource spring.datasource.dataSourceProperties.serverName=localhost spring.datasource.dataSourceProperties.portNumber=3311 spring.datasource.dataSourceProperties.databaseName=mydb spring.datasource.username=root spring.datasource.password=root 

Quindi aggiungi

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

Ho creato un progetto di test qui: https://github.com/ydemartino/spring-boot-hikaricp

non è ansible utilizzare l’approccio dataSourceClassName nelle configurazioni application.properties come affermato da @Andy Wilkinson. se vuoi avere dataSourceClassName comunque puoi usare Java Config come:

 @Configuration @ComponentScan class DataSourceConfig { @Value("${spring.datasource.username}") private String user; @Value("${spring.datasource.password}") private String password; @Value("${spring.datasource.url}") private String dataSourceUrl; @Value("${spring.datasource.dataSourceClassName}") private String dataSourceClassName; @Value("${spring.datasource.poolName}") private String poolName; @Value("${spring.datasource.connectionTimeout}") private int connectionTimeout; @Value("${spring.datasource.maxLifetime}") private int maxLifetime; @Value("${spring.datasource.maximumPoolSize}") private int maximumPoolSize; @Value("${spring.datasource.minimumIdle}") private int minimumIdle; @Value("${spring.datasource.idleTimeout}") private int idleTimeout; @Bean public DataSource primaryDataSource() { Properties dsProps = new Properties(); dsProps.put("url", dataSourceUrl); dsProps.put("user", user); dsProps.put("password", password); dsProps.put("prepStmtCacheSize",250); dsProps.put("prepStmtCacheSqlLimit",2048); dsProps.put("cachePrepStmts",Boolean.TRUE); dsProps.put("useServerPrepStmts",Boolean.TRUE); Properties configProps = new Properties(); configProps.put("dataSourceClassName", dataSourceClassName); configProps.put("poolName",poolName); configProps.put("maximumPoolSize",maximumPoolSize); configProps.put("minimumIdle",minimumIdle); configProps.put("minimumIdle",minimumIdle); configProps.put("connectionTimeout", connectionTimeout); configProps.put("idleTimeout", idleTimeout); configProps.put("dataSourceProperties", dsProps); HikariConfig hc = new HikariConfig(configProps); HikariDataSource ds = new HikariDataSource(hc); return ds; } } 

motivo per cui non è ansible utilizzare dataSourceClassName perché genererà ed eccezione

 Caused by: java.lang.IllegalStateException: both driverClassName and dataSourceClassName are specified, one or the other should be used. 

il che significa che l’avvio primaverile deriva dalla proprietà spring.datasource.url il Driver e, nello stesso tempo, l’impostazione di dataSourceClassName crea questa eccezione. Per renderlo corretto, le tue proprietà application.properties dovrebbero assomigliare a questo per l’origine dati HikariCP:

 # hikariCP spring.jpa.databasePlatform=org.hibernate.dialect.MySQLDialect spring.datasource.url=jdbc:mysql://localhost:3306/exampledb spring.datasource.username=root spring.datasource.password= spring.datasource.poolName=SpringBootHikariCP spring.datasource.maximumPoolSize=5 spring.datasource.minimumIdle=3 spring.datasource.maxLifetime=2000000 spring.datasource.connectionTimeout=30000 spring.datasource.idleTimeout=30000 spring.datasource.pool-prepared-statements=true spring.datasource.max-open-prepared-statements=250 

Nota: verificare se sono presenti tomcat-jdbc.jar o commons-dbcp.jar nel classpath aggiunto il più delle volte dalla dipendenza transitiva. Se questi sono presenti in classpath, Spring Boot configurerà l’origine dati utilizzando il pool di connessioni predefinito che è tomcat. HikariCP verrà utilizzato solo per creare l’origine dati se non ci sono altri provider in classpath. c’è una sequenza di riserva da tomcat -> a HikariCP -> a Commons DBCP.

Ecco le buone notizie. HikariCP è il pool di connessione predefinito ora con Spring Boot 2.0.0.

Note di rilascio di Spring Boot 2.0.0

La tecnologia di pooling del database predefinita in Spring Boot 2.0 è stata trasferita da Tomcat Pool a HikariCP. Abbiamo scoperto che Hakari offre prestazioni superiori e molti dei nostri utenti preferiscono Tomcat Pool.

Quindi risulta che quasi tutte le impostazioni predefinite per HikariCP funzionano per me tranne il numero di connessioni DB. Ho impostato la proprietà nella mia application.properties:

 spring.datasource.maximumPoolSize=20 

E Andy Wilkinson è corretto per quanto posso dire che non è ansible utilizzare l’approccio di configurazione dataSourceClassName per HikariCP con Spring Boot.

Con le versioni successive del boot di spring, il passaggio a Hikari può essere eseguito interamente in configurazione. Sto usando 1.5.6.RELEASE e questo approccio funziona.

build.gradle:

 compile "com.zaxxer:HikariCP:2.7.3" 

applicazione YAML

 spring: datasource: type: com.zaxxer.hikari.HikariDataSource hikari: idleTimeout: 60000 minimumIdle: 2 maximumPoolSize: 20 connectionTimeout: 30000 poolName: MyPoolName connectionTestQuery: SELECT 1 

Cambia connectionTestQuery per adattarlo al tuo DB sottostante. Questo è tutto, nessun codice richiesto.

Secondo la documentazione è cambiato,

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html

Esempio :

 spring: datasource: url: 'jdbc:mysql://localhost/db?useSSL=false' username: root password: pass driver: com.mysql.jdbc.Driver hikari: minIdle: 10 idle-timeout: 10000 maximumPoolSize: 30 

Queste sono le seguenti modifiche alla configurazione che possiamo fare su hikari, per favore aggiungi / aggiorna secondo le tue necessità.

 autoCommit connectionTimeout idleTimeout maxLifetime connectionTestQuery connectionInitSql validationTimeout maximumPoolSize poolName allowPoolSuspension readOnly transactionIsolation leakDetectionThreshold 

Il mio set-up:
Spring Boot v1.5.10
Hikari v.3.2.x (per valutazione)

Per capire veramente la configurazione di Hikari Data Source, consiglio di disabilitare l’Auto-Configurazione di Spring Boot per l’origine dati.

Aggiungi di seguito a application.properties:-

spring.autoconfigure.exclude = org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

Ciò disabiliterà la capacità di Spring Boot di configurare il DataSource da solo.

Ora è la possibilità per te di definire la tua configurazione personalizzata per creare il bean HikariDataSource e popolarlo con le proprietà desiderate.

NOTA :::
la class pubblica HikariDataSource estende HikariConfig

Devi

  1. popola l’object HikariConfig usando le proprietà desiderate di Hikari
  2. inizializza l’object HikariDataSource con l’object HikariConfig passato come argomento al costruttore.

Credo nella definizione della mia class di configurazione personalizzata (@Configuration) per creare l’origine dati da solo e popolarla con le proprietà dell’origine dati definite in un file separato (rispetto al tradizionale: application.properties)

In questo modo posso definire la mia sessionFactory Bean usando Hibernate raccomandato: class “LocalSessionFactoryBean” e popolarlo con la tua Hikari Data Source> e altre proprietà basate su Hiberante-JPA.

Riepilogo delle proprietà Hikari DataSource basate su Spring Boot: –

spring.datasource.hikari.allow-pool-sospensione = true
spring.datasource.hikari.auto-commit = false
spring.datasource.hikari.catalog =
spring.datasource.hikari.connection-init-sql =
spring.datasource.hikari.connection-test-query =
spring.datasource.hikari.connection-timeout = 100
spring.datasource.hikari.data-source-class-name =
spring.datasource.hikari.data-source-jndi =
spring.datasource.hikari.driver-class-name =
spring.datasource.hikari.idle-timeout = 50
spring.datasource.hikari.initialization-fail-fast = true
spring.datasource.hikari.isolate-interne-query = true
spring.datasource.hikari.jdbc-url =
spring.datasource.hikari.leak rilevamento soglia =
spring.datasource.hikari.login-timeout = 60
spring.datasource.hikari.max-vita =
spring.datasource.hikari.maximum-piscina-size = 500
spring.datasource.hikari.minimum-idle = 30
spring.datasource.hikari.password =
spring.datasource.hikari.pool-name =
spring.datasource.hikari.read-only = true
spring.datasource.hikari.register-MBeans = true
spring.datasource.hikari.transaction isolamento =
spring.datasource.hikari.username =
spring.datasource.hikari.validation-timeout =