我们有一个Spring Boot应用程序。
当我们执行“ mvn spring- boot:run”时,该应用程序使用HikariCP。当我们在tomcat上部署war文件时,CP不同,并且在几个小时后关闭连接后崩溃。
部署战文件时如何强制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>
因此,我在评论中被告知,它不会隐式工作,因为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); } }