使用kill -9杀掉springboot应用后,立马java -jar重启,会报错,需要等待一段时间才能启动成功,
报错的原因是:/tmp/tomcat-docbase.4749794910434376321.9086] is not valid
以下是详细错误信息:
Caused by: org.apache.catalina.LifecycleException: Failed to start component [org.apache.catalina.webresources.StandardRoot@53001498] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:158) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:4831) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4963) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] ... 7 more Caused by: java.lang.IllegalArgumentException: The main resource set specified [/tmp/tomcat-docbase.4749794910434376321.9086] is not valid at org.apache.catalina.webresources.StandardRoot.createMainResourceSet(StandardRoot.java:725) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.webresources.StandardRoot.startInternal(StandardRoot.java:686) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.core.StandardContext.resourcesStart(StandardContext.java:4831) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4963) ~[tomcat-embed-core-8.5.4.jar!/:8.5.4] ... 7 more mealtime-report-[15:48:37:716] [ERROR] - org.apache.juli.logging.DirectJDKLog.log(DirectJDKLog.java:181) - A child container failed during start
[root@localhost tmp]# ls -dlt tomcat* drwxr-xr-x 3 root root 4096 May 15 14:19 tomcat.2482651926943103152.4444 drwxr-xr-x 2 root root 4096 May 15 14:19 tomcat-docbase.1606353072223048027.4444 drwxr-xr-x 3 root root 4096 May 15 14:19 tomcat.6427937730432992105.4004 drwxr-xr-x 2 root root 4096 May 15 14:19 tomcat-docbase.9014354490424152602.4004 drwxr-xr-x 3 root root 4096 May 14 18:21 tomcat.365692316696650885.2000 drwxr-xr-x 2 root root 4096 May 14 18:21 tomcat-docbase.8871210702020412482.2000 drwxr-xr-x 3 root root 4096 May 14 18:21 tomcat.9194454391130879725.2222 drwxr-xr-x 2 root root 4096 May 14 18:21 tomcat-docbase.6449009990528406178.2222 drwxr-xr-x 3 root root 4096 May 11 16:31 tomcat.7533402776366547594.3333 drwxr-xr-x 2 root root 4096 May 11 16:31 tomcat-docbase.8347169054078560101.3333 drwxr-xr-x 3 root root 4096 May 11 16:31 tomcat.5755321441664547955.3004 drwxr-xr-x 2 root root 4096 May 11 16:31 tomcat-docbase.4368794759444711233.3004 drwxr-xr-x 3 root root 4096 May 11 16:31 tomcat.7487101127514666304.4444 drwxr-xr-x 2 root root 4096 May 11 16:31 tomcat-docbase.3505389582011000978.4444 drwxr-xr-x 3 root root 4096 May 11 16:30 tomcat.6483749742824168608.4004 drwxr-xr-x 2 root root 4096 May 11 16:30 tomcat-docbase.2936863713994400124.4004 drwxr-xr-x 3 root root 4096 May 11 16:30 tomcat.8814016287852028090.2000 drwxr-xr-x 2 root root 4096 May 11 16:30 tomcat-docbase.5759661693624441557.2000 drwxr-xr-x 3 root root 4096 May 11 16:30 tomcat.3084296173620137759.2222 drwxr-xr-x 2 root root 4096 May 11 16:30 tomcat-docbase.2913734529869658765.2222 drwxr-xr-x 3 root root 4096 May 11 16:30 tomcat.1261539854295462589.3333 drwxr-xr-x 2 root root 4096 May 11 16:30 tomcat-docbase.4327066414867055940.3333 drwxr-xr-x 3 root root 4096 May 11 16:30 tomcat.1652439996406851728.3004 drwxr-xr-x 2 root root 4096 May 11 16:30 tomcat-docbase.5233226104416503892.3004 drwxr-xr-x 3 root root 4096 May 11 11:38 tomcat.8505864110333115533.3333 drwxr-xr-x 2 root root 4096 May 11 11:38 tomcat-docbase.5036544091928181133.3333 drwxr-xr-x 3 root root 4096 May 11 11:37 tomcat.494020510980868278.3004 drwxr-xr-x 2 root root 4096 May 11 11:37 tomcat-docbase.468265602651303178.3004 drwxr-xr-x 3 root root 4096 May 11 11:36 tomcat.8093369488059063930.3004 drwxr-xr-x 2 root root 4096 May 11 11:36 tomcat-docbase.7679645853200594654.3004 drwxr-xr-x 3 root root 4096 May 11 11:31 tomcat.5040740781547956399.4444 drwxr-xr-x 2 root root 4096 May 11 11:31 tomcat-docbase.8256790475295084303.4444 drwxr-xr-x 3 root root 4096 May 11 11:31 tomcat.7344112750169248130.4004 drwxr-xr-x 2 root root 4096 May 11 11:31 tomcat-docbase.2016044219412775812.4004 drwxr-xr-x 3 root root 4096 May 11 11:30 tomcat.3866209351076068036.4444
SpringBoot测试版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
SpringBoot默认使用的是Tomcat作为web server
springboot中默认可以通过配置如下参数设置内嵌容器Tomcat的端口,最大线程数等等
server.port=8081 server.tomcat.max-threads=1000
但是,无法设置最大连接数,而最大连接数直接影响到Tomcat的性能,如何调整这个最大连接数呢?
以下有三种方法
一:
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
import org.springframework.boot.context.embedded.ServletContextInitializer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.stereotype.Component;
@Component()
public class MyEmbeddedServletContainerFactory extends TomcatEmbeddedServletContainerFactory
{
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers)
{
//设置端口
this.setPort(8081);
return super.getEmbeddedServletContainer(initializers);
}
protected void customizeConnector(Connector connector)
{
super.customizeConnector(connector);
Http11NioProtocol protocol = (Http11NioProtocol)connector.getProtocolHandler();
//设置最大连接数
protocol.setMaxConnections(2000);
//设置最大线程数
protocol.setMaxThreads(2000);
protocol.setConnectionTimeout(30000);
}
}
二:
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebServerConfiguration
{
@Bean
public EmbeddedServletContainerFactory createEmbeddedServletContainerFactory()
{
TomcatEmbeddedServletContainerFactory tomcatFactory = new TomcatEmbeddedServletContainerFactory();
tomcatFactory.setPort(8081);
tomcatFactory.addConnectorCustomizers(new MyTomcatConnectorCustomizer());
return tomcatFactory;
}
}
class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer
{
public void customize(Connector connector)
{
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
//设置最大连接数
protocol.setMaxConnections(2000);
//设置最大线程数
protocol.setMaxThreads(2000);
protocol.setConnectionTimeout(30000);
}
}
三:
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class WebServerConfiguration
{
@Bean
public EmbeddedServletContainerCustomizer createEmbeddedServletContainerCustomizer()
{
return new MyEmbeddedServletContainerCustomizer();
}
}
class MyEmbeddedServletContainerCustomizer implements EmbeddedServletContainerCustomizer
{
public void customize(ConfigurableEmbeddedServletContainer container)
{
TomcatEmbeddedServletContainerFactory tomcatFactory = (TomcatEmbeddedServletContainerFactory)container;
tomcatFactory.setPort(8081);
//下面的操作可以参照上面的方法
}
}
最后,如果发现没有生效,就把application.properties配置里面关于Tomcat的一些配置(server.*)全部删掉,就OK了。
自定义tomcat
在实际的项目中简单的配置tomcat端口肯定无法满足大家的需求,因此需要自定义tomcat配置信息来灵活的控制tomcat。
以定义默认编码为例
package com.lkl.springboot.container.tomcat; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * tomcat 配置 * @author liaokailin * @version $Id: TomcatConfig.java, v 0.1 2015年10月4日 上午12:11:47 liaokailin Exp $ */ @Configuration public class TomcatConfig { @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); tomcat.setUriEncoding("UTF-8"); return tomcat; } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
构建EmbeddedServletContainerFactory的bean,获取到TomcatEmbeddedServletContainerFactory实例以后可以对tomcat进行设置,例如这里设置编码为UTF-8
SSL配置
生成证书
keytool -genkey -alias springboot -keyalg RSA -keystore /Users/liaokailin/software/ca1/keystore
设置密码123456

tomcat中验证证书是否正确
修改tomcat/conf/server.xml文件
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" keystoreFile="/Users/liaokailin/software/ca1/keystore" keystorePass="123456" clientAuth="false" sslProtocol="TLS"/>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
启动tomcat ,访问 http://localhost:8443

spring boot 内嵌tomcat ssl
配置资源文件
server.port=8443 server.ssl.enabled=true server.ssl.keyAlias=springboot server.ssl.keyPassword=123456 server.ssl.keyStore=/Users/liaokailin/software/ca1/keystore
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
server.ssl.enabled启动tomcat ssl配置server.ssl.keyAlias别名server.ssl.keyPassword密码server.ssl.keyStore位置
启动 spring boot

访问https://localhost:8443/springboot/helloworld

多端口监听配置
前面启动ssl后只能走https,不能通过http进行访问,如果要监听多端口,可采用编码形式实现。
1.注销前面ssl配置,设置配置 server.port=9090
2.修改TomcatConfig.Java
package com.lkl.springboot.container.tomcat; import java.io.File; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.Http11NioProtocol; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * tomcat 配置 * @author liaokailin * @version $Id: TomcatConfig.java, v 0.1 2015年10月4日 上午12:11:47 liaokailin Exp $ */ @Configuration public class TomcatConfig { @Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); tomcat.setUriEncoding("UTF-8"); tomcat.addAdditionalTomcatConnectors(createSslConnector()); return tomcat; } private Connector createSslConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler(); try { File truststore = new File("/Users/liaokailin/software/ca1/keystore"); connector.setScheme("https"); protocol.setSSLEnabled(true); connector.setSecure(true); connector.setPort(8443); protocol.setKeystoreFile(truststore.getAbsolutePath()); protocol.setKeystorePass("123456"); protocol.setKeyAlias("springboot"); return connector; } catch (Exception ex) { throw new IllegalStateException("cant access keystore: [" + "keystore" + "] ", ex); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
通过addAdditionalTomcatConnectors方法添加多个监听连接;此时可以通过http 9090端口,https 8443端口。

