Spring Boot 揭秘与实战 - 内嵌的服务器 Tomcat剖析

 
 
 
文章目录
 
1. 内嵌的 Tomcat,一个Jar包运行
2. 如何定制内嵌 Tomcat
2.1. 设置内嵌Tomcat的端口
2.2. 设置内嵌Tomcat的最大线程数
2.3. 设置内嵌Tomcat的编码
2.4. 官方提供的常用配置参数
3. War 包部署的使用细节
4. 总结
5. 源代码
 
 
 
 
 
 
 
 
 
 
 
Spring Boot 默认使用的是 Tomcat 作为内嵌的服务器。所以,我们搭建一个 Web 工程将会变得非常的简单。
 
内嵌的 Tomcat,一个Jar包运行
 
还记得,《Spring Boot 揭秘与实战(一) 快速上手》讲到的例子么?我们来回顾下。
首先,修改 POM 文件,添加依赖。
 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
创建Java代码
 
@RestController
@EnableAutoConfiguration
public class RestfulApiWebDemo {
    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }
    public static void main(String[] args) throws Exception {
        SpringApplication.run(RestfulApiWebDemo.class, args);
    }
}
 
直接运行 Java 类,或者可以通过 “mvn spring-boot:run” 在命令行启动该应用。会启动一个内嵌的 Tomcat 服务器运行在 8080 端口。访问 “http://localhost:8080” 可以看到页面上显示“Hello World!”。
 
此外,在 POM 文件添加插件。
 
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
 
在添加了插件后,当运行 “mvn package” 进行打包时,会打包成一个可以直接运行的 JAR 文件,使用 “java -jar” 命令就可以直接运行。
 
通过 Spring Boot 内嵌的 Tomcat 服务器,我们通过一个 jar 包就可以运行一个 web 工程,这个也很符合微服务的场景,我们在正式环境只要部署一个 jar 即可,当然,我们还可以把这个 jar 部署在 docker 容器中运行,是不是非常方便呢?
 
如何定制内嵌 Tomcat
设置内嵌Tomcat的端口
 
Spring Boot 内嵌的 Tomcat 服务器默认运行在 8080 端口。如果,我们需要修改Tomcat的端口,我们可以在 src/main/resources/application.properties 中配置Tomcat信息。
 
server.port=8089
 
现在,你可以重新运行上面的例子,看下是不是 Tomcat 的端口变成 8089 了。
 
设置内嵌Tomcat的最大线程数
 
我们还可以修改内嵌的 Tomcat 服务器的最大线程数。
 
server.tomcat.max-threads=1000
设置内嵌Tomcat的编码
 
在一些场景下,我们可能需要改动 Tomcat 的编码,例如是 GBK 还是 UTF-8。
 
server.tomcat.uri-encoding = UTF-8
官方提供的常用配置参数
 
除了上面讲到的3个场景外,我们还可以自定义设置路径地址、 SSL等参数。
 
这里列举一些官方提供的常用配置参数,如果有特定需求,可以进行内嵌 Tomcat 的定制。
 
server.tomcat.accesslog.enabled=false # Enable access log.
server.tomcat.accesslog.pattern=common # Format pattern for access logs.
server.tomcat.accesslog.prefix=access_log # Log file name prefix.
server.tomcat.accesslog.rename-on-rotate=false # Defer inclusion of the date stamp in the file name until rotate time.
server.tomcat.accesslog.suffix=.log # Log file name suffix.
server.tomcat.background-processor-delay=30 # Delay in seconds between the invocation of backgroundProcess methods.
server.tomcat.basedir= # Tomcat base directory. If not specified a temporary directory will be used.
server.tomcat.internal-proxies=10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|\\
        192\\.168\\.\\d{1,3}\\.\\d{1,3}|\\
        169\\.254\\.\\d{1,3}\\.\\d{1,3}|\\
        127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|\\
        172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|\\
        172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|\\
        172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3} # regular expression matching trusted IP addresses.
server.tomcat.max-threads=0 # Maximum amount of worker threads.
server.tomcat.min-spare-threads=0 # Minimum amount of worker threads.
server.tomcat.port-header=X-Forwarded-Port # Name of the HTTP header used to override the original port value.
server.tomcat.protocol-header= # Header that holds the incoming protocol, usually named "X-Forwarded-Proto".
server.tomcat.protocol-header-https-value=https # Value of the protocol header that indicates that the incoming request uses SSL.
server.tomcat.redirect-context-root= # Whether requests to the context root should be redirected by appending a / to the path.
server.tomcat.remote-ip-header= # Name of the http header from which the remote ip is extracted. For instance `X-FORWARDED-FOR`
server.tomcat.uri-encoding=UTF-8 # Character encoding to use to decode the URI.
War 包部署的使用细节
 
如果,我们还是希望通过 war 包的方式,部署到外部的 Tomcat 服务器上, Spring Boot 也是支持的,不过需要一些额外的配置。
 
首先,要将最终的打包形式改为 war 包,所以需要将 packaging 的值修改为 war。
 
<packaging>war</packaging>
 
接着,对依赖进行适当的配置,值得注意的是,在这里需要移除对嵌入的 Tomcat 的依赖,这样打出的 WAR 包中,在 lib 目录下才不会包含 Tomcat 相关的JAR包。
 
<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> 
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
 
另外,为了保证编译正确,还需要添加对 servlet-api 的依赖,因此添加如下的配置。
 
<dependency>  
    <groupId>org.apache.tomcat</groupId>  
    <artifactId>tomcat-servlet-api</artifactId>  
    <version>7.0.42</version>  
    <scope>provided</scope>  
</dependency>
 
设置,打包后的项目访问名称,在<build>节点里添加<finalName>内容。
 
<build>
  <finalName>springboot-web-demo</finalName>
</bulid>
 
如果我们想要将在外部的 Tomcat 服务器部署的 WAR 包,就不能依赖于 RestfulApiWebDemo 的 main 函数,要以类似于 web.xml 文件配置的方式来启动 Spring 应用上下文,此时我们需要声明一个类,这个类的作用与在 web.xml 中配置负责初始化 Spring 应用上下文的监听器作用类似,只不过在这里不需要编写额外的 XML 文件了。
 
public class ServletInitializer extends SpringBootServletInitializer {   
    @Override  
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {  
        return application.sources(RestfulApiWebDemo.class);  
    }  
}
 
大功告成,此时,我们可以通过 Maven 的 “mvn clean package” 打包出一个 war 包,并部署到外部的 Tomcat 服务器运行。访问 “http://localhost:8080/springboot-web-demo/” 可以看到页面上显示“Hello World!”。
 
总结
 
Spring Boot 默认使用的是 Tomcat 作为内嵌的服务器。所以,我们搭建一个 Web 工程将会变得非常的简单,只需要一个 jar 包即可运行。此外,我们还可以对内嵌的 Tomcat 进行一些定制,例如端口、最大线程数、编码、 SSL 等。如果,我们还是希望通过 war 包的方式,部署到外部的 Tomcat 服务器上, Spring Boot 也是支持的,不过需要一些额外的配置,这个配置过程也只需要几个简单的步骤即可实现。
 
源代码
 
相关示例完整代码: springboot-action
 
 
 tomcat是目前较为常用的Web容器,那么怎么配置tomcat才能使得自己的服务效率更高,今天我主要解释一下tomcat的最大线程数(maxThreads)、最大等待数(acceptCount)和最大连接数(maxConnections)。
 
    maxThreads(最大线程数):每一次HTTP请求到达Web服务,tomcat都会创建一个线程来处理该请求,那么最大线程数决定了Web服务可以同时处理多少个请求,默认200.
 
    accepCount(最大等待数):当调用Web服务的HTTP请求数达到tomcat的最大线程数时,还有新的HTTP请求到来,这时tomcat会将该请求放在等待队列中,这个acceptCount就是指能够接受的最大等待数,默认100.如果等待队列也被放满了,这个时候再来新的请求就会被tomcat拒绝(connection refused)。
 
    maxConnections(最大连接数):这个参数是指在同一时间,tomcat能够接受的最大连接数。一般这个值要大于maxThreads+acceptCount。
 
 
 
增加线程是有成本的,JVM中默认情况下在创建新线程时会分配大小为1M的线程栈,所以更多的线程异味着更多的内存;
更多的线程会带来更多的线程上下文切换成本。

猜你喜欢

转载自blog.csdn.net/weixin_41722928/article/details/88737136