2015-04-15 2 views
2

У нас есть приложение для загрузки весны.HikariCP начинается, когда «mvn spring-boot: run», но не с развертываемым файлом войны

Когда мы делаем «mvn spring-boot: run», приложение использует HikariCP. Когда мы разворачиваем военный файл на tomcat, CP отличается, и он падает с закрытием соединения через несколько часов.

Как я могу заставить Хикари при развертывании военного файла?

Это наша 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("[email protected]"); 
//  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("[email protected]"); 
//  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> 
+1

Вы очень стараетесь не использовать весеннюю загрузку ... Если вы всегда хотите явно использовать HikariCP настройте источник данных и удалите свойства «spring.datasource», «hibernate.connection» и «hibernate.hikari» (последние 2 бесполезны, так как источник данных вводится и не управляется спящим, а весной). –

+0

Что вы подразумеваете под словом "стараюсь очень не использовать весенний ботинок"? Я действительно хочу сделать использование hikariCP неявным, я не хочу привязываться к нему явно. – mist

+2

Имплоскость не будет работать, поскольку при развертывании в tomcat либо tomcat-jdbc, либо commons-dbcp (в зависимости от версии tomcat) имеет приоритет над Hikari. Поэтому, если вы хотите, чтобы вы всегда использовали Hikari, вам нужно будет его явно настроить. –

ответ

2

Так что я сказал в комментариях, что он не будет работать неявно, потому что у db-пула 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); 
    } 
} 
+2

Я предлагаю открыть проблему отслеживания в проекте весенней загрузки. Я склонен согласиться с вами, что в идеале приоритет должен иметь конфигурация, указанная в Spring-загрузке. Но опять же, может быть, это просит весеннюю загрузку слишком глубоко узнать о компонентах, которые она развертывает. В любом случае, открытие проблемы должно получить более четкий ответ от ребятишек, будь то возможно или разумно. – brettw

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, который рекомендуется. В этом случае вы должны пойти с Java Config после spring.datasource.dataSourceClassName = com.mysql.jdbc.jdbc2.optional.MysqlDataSource в application.properties:

@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; 
    } 
    } 

определение dataSourceClassName в application.properties для неявной автонастройки с броском исключением:

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

в весенней загрузке драйвер из выводит URL-адрес собственности, и вы не можете установить драйвер (выведенные) и dataSourceClassName в то же время для неявного автоматического конфигурирования. Вы можете найти загружаемый пример загрузки hikariCP CRUD и учебник, объясняющий неявное, а также конфигурацию эксклюзии здесь, в этой ссылке: http://frameworkonly.com/spring-boot-crud-tutorial-thymeleaf-spring-data-jpa-hikaricp/

 Смежные вопросы

  • Нет связанных вопросов^_^