1.springboot 的内置tomcat没有去掉,导致springboot 和tomcat 分别启动了1次
2.完全是tomcat 启动了两次
第一个问题:我们在springboot pom.xml中
<packaging>war</packaging>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去除内嵌tomcat -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
第二个问题:在tomcat 的server.xml中 把host的appBase 换为“”,然后启动就好了
或者你在tomcat内部新建一个webroot 文件夹 然后把appBase换成webroot 也可以
就是host 和context 分别启动了两次
当时看到这的时候以为肯定是这两个问题,一定能解决,结果我们改完之后,测试还是不好使
然后经过测试
发现是springboot 启动类 @SpringBootApplication的类 把extends 的去掉就好了
具体原因就不在这里说明了,但是基本上springboot 在tomcat 中发布两次的问题 就这三个原因了
原文链接:
idea中使用tomcat 方式启动spring boot项目
Spring boot 的main 入口启动方式相信都会用,直接运行main直接就启动了,但是往往这种方式并不是最佳的启动方式,比如运维的层面更希望调整tomcat的调优参数,而只使用嵌入启动方式很难做到这些。所以使用tomcat方式启动spring boot就比较重要。
1、去tomcat 官网下载 tomcat 8 tar.gz 文件,然后解压.
https://tomcat.apache.org/download-80.cgi
2、idea中,配置启动
3、gradle or maven 配置
<packaging>war</packaging>
or
apply plugin: "war"
4、增加tomcat启动调用spring boot初始化入口:
public class ServletInitializer extends SpringBootServletInitializer {
private Logger logger = LoggerFactory.getLogger(ServletInitializer.class);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
logger.info("starting spring boot initializer ......");
return application.sources(MainApplication.class);
}
}
or
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
5、start runing
搞定!
tomcat重启两次的原因是appBase和Context中docBase设置的值导致的,只需要把appBase置为空,docBase写项目的绝对路径就可以了,代码如下:
<Host name="localhost" appBase=""
unpackWARs="true" autoDeploy="true">
<Context path="/" docBase="F:/Tomcat8.5/webroot/taocloud" debug="0"/> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" /> </Host>
————————————————
Java代码
1. <Host name="localhost" appBase=""
2. "true" autoDeploy="true"
3. "false" xmlNamespaceAware="false">
4.
5. "/usr/local/apache-tomcat-6.0.29/webapps/semwinner" path="" reloadable="true"></Context>
6. "/usr/local/apache-tomcat-6.0.29/webapps/emarboxmanager" path="/admin" reloadable="true"></Context>
7.
8. </Host>
把appBase设置为空即可!
去除了appBase="webapps"中的webapps变成了appBase="",因为web应用程序都是放在webapps这个目录下的,如果 不把“webapps“去掉,这里会调用一次quartz的任务调度,在接下来的“<Context path”中又会调用一次quartz的任务调度,所以就重复了2次
https://www.iteye.com/blog/nkliuliu-816335
本人这个问题最后解决发现,的确是由 web应用程序默认都是放在webapps这个目录下的,如果不把“webapps“去掉,这里会调用一次quartz的任务调度,在接下来的“<Context path”中又会调用一次quartz的任务调度 这个原因导致。
而且本人刚开始执行3次,tomcat的webapp下面XXX.WAR包解压之后,war包没有删除,相当webapp目录下有 XXX 和XXX.war 所以XXX和XXX.war各执行一次,当删除XXX.war时,就只执行了2次,分别是 tomcat的server.xml中appBase和Context docBase,再删除
<Context docBase= 就只执行一次了。
以上本人验证成功!
如果webapp下面有多个不同的war包,那么把server.xml中appBase 的内容去掉,应该也是可以。这点没试过,待验证!
我开始以为眼花了,tomcat启动的时候,
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.2.RELEASE)
出现了两次,然后日志中有报错:
Unable to register MBean [HikariDataSource (HikariPool-2)] with key 'dataSource ...
最终确认springboot被加载了两次。
原因一:
war包发布,可能没有排除内置tomcat,先确认exclusions
原因二:
tomcat的server.xml配置有问题
如果<Context>节点里配置了应用全路径,那么<host>节点里的appBase要置空,否则就是这出问题,host和context分别加载一次。
待测: 如果有两个springboot应用放在tomcat下的情况,还未测试。