🏆【SpringBoot 技术专题】「Tomcat 技术专区」用正确的姿势如何用外置 tomcat 配置及运行(Tomcat 优化分析)
前提概要
在特别特殊的时候,我们可能需要外置 tomcat 去运行程序,例如 alitomcat 等特殊场景,方便我们去定时化开发项目或者其他特殊场景。
外置 tomcat 执行
pom.xml 文件首先更改打包方式 war,再排除 springboot 内置的 web 项目下 tomcat 依赖
Maven 配置调整
移除 tomcat 依赖或者将 tomcat 依赖 scope 改为 provide,移除 tomcat 依赖
再引入 tomcat 依赖:
将打包方式修改为 war
调整 springboot 的启动类
继承 org.springframework.boot.web.servlet.support.SpringBootServletInitializer,实现 configure 方法:为什么继承该类,SpringBootServletInitializer 源码注释:
Note that a WebApplicationInitializer is only needed if you are building a war file and deploying it. If you prefer to run an embedded web server then you won't need this at all.
注意,如果您正在构建 WAR 文件并部署它,则需要 WebApplicationInitializer。如果你喜欢运行一个嵌入式 Web 服务器,那么你根本不需要这个。
DemoApplication,让其实现 SpringBootServletInitializer,然后重写 configure()方法:
方式一,启动类继承 SpringBootServletInitializer 实现 configure:
方式二,新增加一个类继承 SpringBootServletInitializer 实现 configure:
注意事项
使用外部 Tomcat 部署访问的时候,application.properties(或者 application.yml)中配置的将失效,请使用 tomcat 的端口,tomcat,webapps 下项目名进行访问。
为了防止应用上下文所导致的项目访问资源加载不到的问题,建议 pom.xml 文件中<build></build>标签下添加<finalName></finalName>标签:
IDEA 下,运行 mvn clean,--> mvn package ,等到项目打包成功,在该项目文件位置找到 target 下的 demo.war,拷贝到 tomcat/webapps 目录下,
使用 windows 命令行,启动 tomcat 服务器,项目启动成功会出现, spring 的标志。
访问路径:localhost:8080/${打包文件名}/请求 url
如何在访问时去掉 war 包名?
原理:Tomcat 的默认根目录是 ROOT,实际上 ROOT 这个项目在实际生产环境是没有用的,所以我们可以用我们的项目覆盖 ROOT 项目
操作过程
删除 ROOT 下所有文件及文件夹.
把我们项目的 war 包解压后,项目目录下的所有文件和子目录都拷贝到 ROOT 目录下即可或者有更狠的一招:直接删掉 ROOT 目录,然后把我们的项目打包名称改成 ROOT.war,放到 webapps 下就行.
原理:Tomcat 本身可以配置虚拟目录。方法就是在 Server.xml 中<Engine><Host>节点下加入 Context 信息。
如我们可以配置<Context path="/abc" docBase="D:\app\abc" ... />,那我们可以通过地址 http://localhost:8080/abc 来访问我们放在 D:\app\下面的 abc 项目。我们可以把这个 path="/abc"修改为 path=""。意思就是把 abc 映射到根目录,访问路径就会变成 http://localhost:8080/。
按照配置虚拟目录的方式,在<Engine><Host>下添加一个 Context 节点,具体配置如下:
Spring Boot 也提供了对 JMX 监控的支持。JMX 监控对外暴露的信息相同,不过是使用 MBeans 容器将应用数据封装管理。
Springboot 的 jmx 是默认开启的,如果 tomcat 部署两个原 springboot 打成的 war 包。
需要将每一个项目的 jmx 关闭 Application.properties 配置中 添加 spring.jmx.enabled=false;
在各自项目中都添加:spring.jmx.default-domain=project1 以及 spring.jmx.default-domain=project2 保证 domain 是不一样的。
tomcat 相关配置修改
修改默认的 http 访问端口:8080 为 8181,在 tomcat8.5/conf/server.xml 文件里修改:示例
修改默认的 session 有效期
在 tomcat/conf/web.xml 文件里修改,范围是具体项目:示例
在 tomcat/conf/server.xml
在 java 后台代码里配置,具体页面的 session 有效时间
生效优先级: 3 > 2 > 1,
(彩蛋) tomcat 调优
tomcat 修改最大线程,在 tomcat/conf/server.xml 文件里修改:示例
maxThreads=“X” 表示最多同时处理 X 个连接
minSpareThreads=“X” 初始化 X 个连接
maxSpareThreads=“X” 表示如果最多可以有 X 个线程,一旦超过 X 个,则会关闭不在需要的线程
acceptCount=“X” 当同时连接的人数达到 maxThreads 时,还可以排队,队列大小为 X.超过 X 就不处理
tomcat 内存优化
Windows 下的 catalina.bat
Linux 下的 catalina.sh 如:
JAVA_OPTS=’-Xms256m -Xmx512m’-Xms JVM 初始化堆的大小-Xmx JVM 堆的最大值 实际参数大小根据服务器配置或者项目具体设置.
Tomcat IO 优化
同步阻塞 IO(JAVA BIO) 同步并阻塞,服务器实现模式为一个连接一个线程(one connection one thread 想想都觉得恐怖,线程可是非常宝贵的资源),当然可以通过线程池机制改善.
BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,但程序直观简单易理解.
JAVA NIO:又分为同步非阻塞 IO,异步阻塞 IO 与 BIO 最大的区别 one request one thread.可以复用同一个线程处理多个 connection(多路复用)
NIO 方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4 开始支持.
异步非阻塞 IO(Java NIO2 又叫 AIO) 主要与 NIO 的区别主要是操作系统的底层区别.可以做个比喻:比作快递,NIO 就是网购后要自己到官网查下快递是否已经到了(可能是多次),然后自己去取快递;AIO 就是快递员送货上门了(不用关注快递进度)。
AIO 方式使用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用 OS 参与并发操作,编程比较复杂,JDK7 开始支持.
在 server.xml 中
实现对 Tomcat 的 IO 切换
APR 是从操作系统级别来解决异步的 IO 问题,大幅度的提高性能. (http://apr.apache.org/).
APR(Apache Portable Runtime)是一个高可移植库,它是 Apache HTTP Server 2.x 的核心.能更好地和其它本地 web 技术集成,总体上让 Java 更有效率作为一个高性能 web 服务器平台而不是简单作为后台容器.
在产品环境中,特别是直接使用 Tomcat 做 WEB 服务器的时候,应该使用 Tomcat,Native 来提高其性能.如果不配 APR,基本上 300 个线程狠快就会用满,以后的请求就只好等待.但是配上 APR 之后,并发的线程数量明显下降,从原来的 300 可能会马上下降到只有几十,新的请求会毫无阻塞的进来.
在局域网环境测,就算是 400 个并发,也是一瞬间就处理/传输完毕,但是在真实的 Internet 环境下,页面处理时间只占 0.1%都不到,绝大部分时间都用来页面传输.如果不用 APR,一个线程同一时间只能处理一个用户,势必会造成阻塞。所以生产环境下用 apr 是非常必要的.
版权声明: 本文为 InfoQ 作者【李浩宇/Alex】的原创文章。
原文链接:【http://xie.infoq.cn/article/d5fecd4e1d7bf3532ebcc6589】。文章转载请联系作者。
评论