我们有一个春季启动应用程序。
当我们执行“mvn spring-boot:run”时,应用程序使用HikariCP。 当我们在tomcat上部署war文件时,CP会有所不同,几小时后连接就会崩溃。
在部署war文件时如何强制Hikari?
这是我们的application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/xxx?
autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&connectionCollation=utf8_general_ci&characterSetResults=utf8&autoDeserialize=true&useConfigs=maxPerformance
spring.datasource.username=root
spring.datasource.password=___
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.open-in-view=true
spring.jpa.show-sql=false
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.DefaultNamingStrategy
spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
spring.jpa.properties.hibernate.hikari.dataSource.cachePrepStmts=true
spring.jpa.properties.hibernate.hikari.dataSource.prepStmtCacheSize=250
spring.jpa.properties.hibernate.hikari.dataSource.prepStmtCacheSqlLimit=2048
spring.jpa.properties.hibernate.hikari.dataSource.useServerPrepStmts=true
spring.jpa.properties.hibernate.generate_statistics=false
spring.jpa.properties.hibernate.cache.use_structured_entries=true
spring.jpa.properties.hibernate.archive.autodetection=class
spring.jpa.properties.hibernate.show_sql=false
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_update=true
spring.jpa.properties.hibernate.connection.characterEncoding=utf-8
spring.jpa.properties.hibernate.connection.CharSet=utf-8
spring.jpa.properties.hibernate.connection.useUnicode=true
spring.jpa.properties.hibernate.connection.autocommit=true
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=com.hazelcast.hibernate.HazelcastLocalCacheRegionFactory
spring.jpa.properties.hibernate.cache.region_prefix=
spring.jpa.properties.hibernate.cache.use_query_cache=true
spring.jpa.properties.hibernate.cache.use_minimal_puts=true
# JTA
spring.jta.enabled=true
这是Application类:
package site.app;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.web.config.EnableSpringDataWebSupport;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Properties;
/**
* to make this deployable as war, this is necessary:
* http://docs.spring.io/spring-boot/docs/current/reference/html/howto-traditional-deployment.html
*/
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = "site")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "site.repository" } )
@EntityScan(basePackages="site.model")
@EnableJpaAuditing
@EnableSpringDataWebSupport
@SpringBootApplication//mist: so that it can be run as war file
public class Application extends SpringBootServletInitializer {
/** mist: so that it can be run as war file */
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// System.out.println("Let's inspect the beans provided by Spring Boot:");
//
// String[] beanNames = ctx.getBeanDefinitionNames();
// Arrays.sort(beanNames);
// for (String beanName : beanNames) {
// System.out.println(beanName);
// }
// UserRepository repository = context.getBean(UserRepository.class);
// //example data
// User user = new User();
// user.setEmail("nov34@test.com");
// user.setFirstName("test");
// user.setLastName("test");
//
// repository.save(user);
// Iterable<User> allUsers = repository.findAll();
// for(User theUser : allUsers){
// System.out.println(theUser.getEmail());
// }
//
// SponsorRepository sponsorRepository = context.getBean(SponsorRepository.class);
//
// Sponsor sponsor = new Sponsor();
// sponsor.setEmail("test@test.com");
// sponsor.setSponsorPackage(SponsorPackage.DIAMOND);
//
// sponsorRepository.save(sponsor);
// Page page = new Page();
// page.setName("home");
// PageRepository pageRepository = context.getBean(PageRepository.class);
// pageRepository.save(page);
// Link link = new Link();
// link.setName("Registration");
// link.setUrl("/");
// LinkRepository linkRepository = context.getBean(LinkRepository.class);
// linkRepository.save(link);
// context.close();
}
// private DataSource dataSource() {
// final HikariDataSource ds = new HikariDataSource();
// ds.setMaximumPoolSize(100);
// ds.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource");
// ds.addDataSourceProperty("url", url);
// ds.addDataSourceProperty("user", username);
// ds.addDataSourceProperty("password", password);
// ds.addDataSourceProperty("cachePrepStmts", true);
// ds.addDataSourceProperty("prepStmtCacheSize", 250);
// ds.addDataSourceProperty("prepStmtCacheSqlLimit", 2048);
// ds.addDataSourceProperty("useServerPrepStmts", true);
// return ds;
// }
// @Value("${spring.datasource.username}")
// private String user;
//
// @Value("${spring.datasource.password}")
// private String password;
//
// @Value("${spring.datasource.url}")
// private String dataSourceUrl;
//
// @Value("${spring.datasource.driverClassName}")
// private String driverClassName;
//
//// @Value("${spring.datasource.connectionTestQuery}")
//// private String connectionTestQuery;
//
// @Bean
// public DataSource primaryDataSource() {
// Properties dsProps = new Properties();
// dsProps.setProperty("url", dataSourceUrl);
// dsProps.setProperty("user", user);
// dsProps.setProperty("password", password);
//
// Properties configProps = new Properties();
//// configProps.setProperty("connectionTestQuery", connectionTestQuery);
// configProps.setProperty("driverClassName", driverClassName);
// configProps.setProperty("jdbcUrl", dataSourceUrl);
//
// HikariConfig hc = new HikariConfig(configProps);
// hc.setDataSourceProperties(dsProps);
//// hc.setMetricRegistry(metricRegistry);
// return new HikariDataSource(hc);
// }
}
这是pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.bgjug</groupId>
<artifactId>site</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name> web site</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
<!--mist: exists in tomcat-->
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--TODO mist: hikariCP stays here. I couldn't make it use it (I'm missing something). Now it uses either tomcat's pool or commons' pool-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<scope>compile</scope>
</dependency>
<!-- I need this to make entities auditable -->
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time-jsptags</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.jadira.usertype</groupId>
<artifactId>usertype.core</artifactId>
<version>${jadira.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<!--mist: exists in tomcat-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<!-- spring security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<!-- email -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-hibernate4</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<!-- testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.186</version>
</dependency>
</dependencies>
<!--mist: a profile that has the spring-boot:run plugin and a couple of dependencies, so that-->
<!--spring-boot:run will work with an embedded tomcat. This profile is activated by default so that-->
<!--no extra conf is needed. when we deploy on the server, we deactivate the profile, because we don't-->
<!--want these dependencies in the war.-->
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<id>run.as.spring-boot.run</id>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
<properties>
<start-class>site.app.Application</start-class>
<spring.version>4.1.5.RELEASE</spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-data-jpa.version>1.5.0.M1</spring-data-jpa.version>
<hibernate-entitymanager.version>4.3.0.Final</hibernate-entitymanager.version>
<jadira.version>3.1.0.CR10</jadira.version>
<hazelcast.version>3.4</hazelcast.version>
<rest-assured.version>2.4.0</rest-assured.version>
<h2-database.version>1.3.156</h2-database.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
答案 0 :(得分:2)
所以我在评论中被告知,它不会隐式地工作,因为Tomcat的数据库池以某种方式优先,这对我来说很奇怪。
可以像这样明确地配置它:
@Configuration
@ConfigurationProperties//: so that the conf properties are supplied here
@SpringBootApplication//: so that it can be run as war file
...
public class Application extends SpringBootServletInitializer {
@Value("${spring.datasource.username}")
private String user;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.url}")
private String dataSourceUrl;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Bean
public DataSource primaryDataSource() {
Properties dsProps = new Properties();
dsProps.setProperty("url", dataSourceUrl);
dsProps.setProperty("user", user);
dsProps.setProperty("password", password);
Properties configProps = new Properties();
configProps.setProperty("driverClassName", driverClassName);
configProps.setProperty("jdbcUrl", dataSourceUrl);
HikariConfig hc = new HikariConfig(configProps);
hc.setDataSourceProperties(dsProps);
return new HikariDataSource(hc);
}
}
答案 1 :(得分:1)
我也遇到了这个问题,最后这只是一个小问题。它肯定优先,只有在你确保tomcat-jdbc.jar或commons-dbcp.jar永远不会出现在你的类路径中时。你可以通过排除这些依赖项来确保这一点,如果它们是可传递下载的(这就是我所做的,只需找出pom中的哪些依赖项在你的类路径中过渡下载这些依赖项)。当你完成这个时,你的application.properties应该是这样的:
# 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=2500
它将隐式配置HikariCP数据源。但更重要的是,它将使用Driver而不是推荐的dataSourceClassName。在这种情况下,你必须在application.properties中使用spring.datasource.dataSourceClassName = com.mysql.jdbc.jdbc2.optional.MysqlDataSource后使用Java Config:
@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;
}
}
在application.properties中定义dataSourceClassName以进行隐式自动配置并抛出异常:
Caused by: java.lang.IllegalStateException: both driverClassName and dataSourceClassName are specified, one or the other should be used.
当春季启动从url属性推断Driver时,您无法同时设置Driver(推断)和dataSourceClassName以进行隐式自动配置。