tomcat8原理分析
Java中应采用main函数运行。
1.Tomcat是Java开发的,启动的时候入口类为BootStrap main函数
2. 执行到我们的main函数中的init方法
2.1 使用Java的放射技术实例化我们的Catalina(实际上是个包装类,包装了所有的tomcat核心组件 (Connector, Service, Container, Wrapper))
3. 执行BootStrap函数中的load方法,再使用Java反射机制执行Catania的load方法
4. Catalina的load方法解析conf/server.xml配置文件,并且读取到代码中,初始化server
5. 调用fireLicleBase类的init初始化Server(StanderServer 初始化 Server)
--Service 运行存在多个,负责tomcat业务逻辑操作
---Server的Connector连接器主要负责监听客户端的请求,封装请求和响应。
----Containet(容器)
----- host
--------context
-----------Wrapper
采用了责任链的设计模式。
6. 在ContextConfig中的webConfig方法解析项目的web.xml。有web.xml的情况就是读,没有就回调(实现WebApplicationInitializer 接口的 无web.xml方式)
7.运行Tomcat项目,判断项目中是否有web.xml,检查web.xml 中 servlet配置,如果有的情况下,再开始初始化。
注意:
因为外部Tomcat服务器默认启动时候对Jsp支持友好,默认启动的时候就会加载Jsp组件
Tomcat conf/web.xml 定义了JspServlet实现对我们Jsp转换Servlet操作
优化方案:
Tomcat配置优化
减少一些没有必要启动的配置
A.如果在微服务情况下,删除我们视图层加载
- 假设我们现在是微服务架构情况下,我们编写的接口都是rest形式http+json 微服务架构中只有接口没有视图层(jsp)
- 因为外部tomcat服务器默认启动的时候对jsp支持非常友好,默认启动的时候就会加载我们的jsp组件
- Tomcat conf/web.xml 定义了JspServlet 实现对我们jsp转换servlet操作;
- 所以优化策略:将conf/web.xml文件下的JspServlet移除;
B. 外部的tomcat服务器 有这样welcome-file-list 非常浪费效率,直接移除;
C. mime-mapping告诉给浏览器响应类型,如果是微服务项目情况下,移除mime-mapping非json返回类型;
D.在微服务架构中,不会采用session的; 基本被token或者jwt、oatuh2.0
使用token替代我们的session
E. reloadable 为true 当部署的项目web/conf/class文件发生变化的情况直接实现热部署,在生产环境如果设置为true,黑客如果注入了class文件可能会不安全;所以在本地开发环境中可以设置为true,生产环境中必须设置为false;
F.减少日志请求记录 ,在tomcat中日志文件分为:catalina、localhost_access_log、
Catalina属于tomcat最核心的配置文件
localhost_access_log 记录每次请求
建议移除localhost_access_log日志配置文件 conf/server.xml 中的
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context docBase="D:\mayikt" path="/mayikt" reloadable="true"/>
Tomcat线程处理IO模型
Tomcat中分为以下四种IO模型:
- BIO 使用传统io模型处理我们请求 阻塞io;
- NIO 同步非阻塞式io 效率比BIO提高非常多倍 多路复合机制tomcat8
- AIo 异步非阻塞形式 tomcat8
- APR tomcat 以JNI形式调用http服务器的核心动态链接库来处理文件读取或网络传输操作,需要编译安装APR库
SpringBoot内嵌入tomcat是nio,外部tomcat默认的情况下使用apr需要将外部io模型改为nio模式
线程池优化
在我们的conf/server.xml
maxThreads="150" minSpareThreads="10"
maxThreads参数表示我们做多同时存在150个线程;
minSpareThreads 最小活跃的线程是为10个;
配置如何设置:实际项目来定
1.如果并发量比较大的情况下 最小活跃线程建议设置比较大,可以避免重复处理线程 可以增加吞吐量;如果最小活跃的线程如果比较大的情况下,非常占用cpu资源;
2. 如果是项目的并发量比较小的情况下,最小活跃线程可以设置小一点,可以节约cpu内存
实际案例:
20/s tomcat线程池 最大线程树为100 最小活跃线程树30s
Connector的优化:
1.8080 Http协议 处理我们的请求
2.8009 ajp协议 属于tomcat内部通讯端口号
建议移除ajp协议 8009端口监听 减少我们服务器内存消耗;
因为外部tomcat运行加载很多没有必要的配置