大家好,我是烤鸭:
关于springboot war包部署tomcat。
环境:
springboot 2.0.3.RELEASE
apache-tomcat-8.5.32
1. 修改pom
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
com.xxx.xxx
1.0.0-SNAPSHOT
xxx_xxxx_interface
war
xxx_xxxx_interface
xxx接口
1.8
1.8
UTF-8
UTF-8
zh_CN
org.springframework.boot
spring-boot-starter-web
dev
dev
true
test
test
pro
pro
xxxx_interface
src/main/resources
true
test/*
pro/*
dev/*
src/main/resources/${profiles.active}
org.springframework.boot
spring-boot-maven-plugin
1.8
@
false
true
false
lib/
xxx.xxx.xxxInterfaceMainApplication
${project.version}
网上很多人都说需要再加忽略内置tomcat,或者servlet.api的包,其实都不需要。
主要就是
org.springframework.boot
spring-boot-starter-parent
2.0.3.RELEASE
org.springframework.boot
spring-boot-starter-web
war
2. 修改启动方法
package com.xxx.xxxx.config;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import javax.annotation.PostConstruct;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@Configuration
@EnableAutoConfiguration
@ComponentScan(value = "com.xxx.xxxx", excludeFilters = { @Filter(Controller.class),
@Filter(type = FilterType.ASSIGNABLE_TYPE, value = { RootConfiguration.class }) })
@MapperScan({"com.xxx.xxxx.dao"})
public class RootConfiguration extends SpringBootServletInitializer {
@PostConstruct
public void postConstruct() {
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return configureApplication(builder);
}
public static void main(String[] args) {
configureApplication(new SpringApplicationBuilder()).run(args);
}
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
return builder.sources(RootConfiguration.class);
}
}
主要就是继承 SpringBootServletInitializer ,重写 configure 方法。
3. 问题及猜想
之前的项目就是这么配置的,用的springboot 1.5.6.RELEASE,是没有问题的。
改了新项目,升级了springboot,也加了很多东西,项目就起不来了。
本地run方法运行是没有问题的。
3.1 问题 :
启动卡死:
这是tomcat下log日志的最后几行,乍一看并没有什么问题。但是总觉得哪里不对。访问tomcat也访问不到。
[2018-07-04 06:48:10.199] [main] [DEBUG] o.h.validator.internal.xml.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
[2018-07-04 06:48:10.205] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator as ValidatorFactory-scoped message interpolator.
[2018-07-04 06:48:10.206] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.resolver.TraverseAllTraversableResolver as ValidatorFactory-scoped traversable resolver.
[2018-07-04 06:48:10.206] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.util.ExecutableParameterNameProvider as ValidatorFactory-scoped parameter name provider.
[2018-07-04 06:48:10.206] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.DefaultClockProvider as ValidatorFactory-scoped clock provider.
[2018-07-04 06:48:10.207] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
[2018-07-04 06:48:10.654] [main] [WARN ] org.thymeleaf.templatemode.TemplateMode - [THYMELEAF][main] Template Mode 'HTML5' is deprecated. Using Template Mode 'HTML' instead.
[2018-07-04 06:48:10.823] [main] [INFO ] org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler [http-nio-8161]
[2018-07-04 06:48:10.839] [main] [INFO ] org.apache.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
[2018-07-04 06:48:10.877] [main] [INFO ] com.xx.xx.xxxInterfaceMainApplication - Started xxxInterfaceMainApplication in 5.237 seconds (JVM running for 5.691)
或者卡在这:
[2018-07-04 06:48:10.056] [main] [DEBUG] o.h.validator.internal.engine.ConfigurationImpl - Setting custom MessageInterpolator of type org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator
[2018-07-04 06:48:10.057] [main] [DEBUG] o.h.validator.internal.engine.ConfigurationImpl - Setting custom ConstraintValidatorFactory of type org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory
[2018-07-04 06:48:10.057] [main] [DEBUG] o.h.validator.internal.engine.ConfigurationImpl - Setting custom ParameterNameProvider of type org.springframework.validation.beanvalidation.LocalValidatorFactoryBean$1
[2018-07-04 06:48:10.059] [main] [DEBUG] o.h.validator.internal.xml.ValidationXmlParser - Trying to load META-INF/validation.xml for XML based Validator configuration.
[2018-07-04 06:48:10.059] [main] [DEBUG] o.h.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via user class loader
[2018-07-04 06:48:10.059] [main] [DEBUG] o.h.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via TCCL
[2018-07-04 06:48:10.060] [main] [DEBUG] o.h.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via Hibernate Validator's class loader
[2018-07-04 06:48:10.060] [main] [DEBUG] o.h.validator.internal.xml.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
[2018-07-04 06:48:10.067] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator as ValidatorFactory-scoped message interpolator.
[2018-07-04 06:48:10.067] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.resolver.TraverseAllTraversableResolver as ValidatorFactory-scoped traversable resolver.
[2018-07-04 06:48:10.067] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.util.ExecutableParameterNameProvider as ValidatorFactory-scoped parameter name provider.
[2018-07-04 06:48:10.068] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.DefaultClockProvider as ValidatorFactory-scoped clock provider.
[2018-07-04 06:48:10.068] [main] [DEBUG] o.h.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
[2018-07-04 06:48:10.189] [main] [DEBUG] o.h.v.i.engine.resolver.TraversableResolvers - Cannot find javax.persistence.Persistence on classpath. Assuming non JPA 2 environment. All properties will per default be traversable.
或者卡在springboot读取banner之后。
这种问题真的是难找,也不报错。
3.2 猜想:
1 是不是springboot版本升级导致的问题,第一时间降版本,无效。
2 是不是引了多余的包,导致jar包冲突,解决了之后,无效。
3 tomcat本身问题,换tomcat版本,保证tomcat是没问题的,无效。
如果这些都做了,还是无效的话,考虑一下是不是代码的问题。
我尝试注释掉部分代码,再打包启动,如果成功了,就说明代码部分有问题。最后找到了代码中的问题。
问题代码:
/**
*
* 定时任务回调轮询
*/
@Component
public class TaskUpdateNotify implements CommandLineRunner {
public static Log logger = LogFactory.getLog(TaskUpdateNotify.class);
public static final long timeFlag = 1000;
@Autowired
private RedisClient redisClient;
@Autowired
private ThreadHandler threadHandler;
/**
* 25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h) 异步通知回调
*/
@Override
public void run(String... args) throws Exception {
while (true) {
// 先处理发二维码
threadHandler.doNotifyAgainHandler(); //
threadHandler.doPayNotifyAgainHandler(); //多线程方法
//线成休息 1 min
TimeUnit.MINUTES.sleep(1);
}
}
}
我怀疑原因是在实现 CommandLineRunner 接口,并在我在方法中 TimeUnit.MINUTES.sleep(1) 。
之后把这个方法改成了定时任务,又取消了线程sleep,就可以启动了。
最后贴一下:
启动成功的日志最后几行,应该是有tomcat容器启动的。
6-Jul-2018 06:14:03.022 信息 [localhost-startStop-1] org.springframework.boot.StartupInfoLogger.logStarted Started RootConfiguration in 6.223 seconds (JVM running for 12.622)
06-Jul-2018 06:14:03.063 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\preauth_interface.war] has finished in [10,773] ms
06-Jul-2018 06:14:03.064 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\docs]
06-Jul-2018 06:14:03.086 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\docs] has finished in [22] ms
06-Jul-2018 06:14:03.086 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\examples]
06-Jul-2018 06:14:03.357 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\examples] has finished in [271] ms
06-Jul-2018 06:14:03.357 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\host-manager]
06-Jul-2018 06:14:03.386 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\host-manager] has finished in [29] ms
06-Jul-2018 06:14:03.386 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\manager]
06-Jul-2018 06:14:03.409 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\manager] has finished in [23] ms
06-Jul-2018 06:14:03.410 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\ROOT]
06-Jul-2018 06:14:03.432 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [G:\develop\environment\apache-tomcat-8.5.32-1\webapps\ROOT] has finished in [22] ms
06-Jul-2018 06:14:03.441 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
06-Jul-2018 06:14:03.455 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
06-Jul-2018 06:14:03.462 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 11229 ms
4. 总结
如果有报错信息一切都好说,最怕的就是这样,找不到原因。只能一点点摸索,算是分享一下吧。每个人的原因不可能一样。这种问题只能慢慢找了。多尝试几次,如果还是找不到。
就用 jar包方式 运行 springboot 项目。如果有 静态页面,就前后端分离,简单的方式 Nginx。