SpringBoot優化內嵌的Tomcat ---設置MaxConnections


使用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

https訪問

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

啟動spring boot

訪問https://localhost:8443/springboot/helloworld

訪問https

多端口監聽配置

前面啟動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端口。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM