Tomcat
2020-12-20 21:29:26 65 举报
AI智能生成
tomcat架构
作者其他创作
大纲/内容
架构
架构图
功能模块
按功能可拆分为解析http请求、管理Servlet,所以主要可分为两个组件:连接器和Servlet容器
发展方向
该架构为硬件资源稀缺的环境下产生的,即一个应用服务器部署多个应用,现在多为微服务架构,tomcat发展方向可以简化架构
连接器Connector
ProtocolHandler
Endpoint
Acceptor
从线程池中拿到线程后等待连接到来
建立连接后,将请求任务丢到线程池中等待SocketProcessor处理
SocketProcessor
如果不特殊配置,该线程池使用与Acceptor不同的池
LimitLatch
限制最大连接数
io
bio
同步阻塞 io
请求量较小时可考虑使用
tomcat8.5已经去掉该io
nio
使用jvm堆
由jvm管理,不容易出现内存泄露
io多路复用
处理流程图
nio2
异步io
windows内核提供了较成熟方案
Linux暂未有商业可用的异步io
如果在linux上使用该模式,是jvm在应用层模拟的
apr
比nio快在哪里
系统调用
c语言实现,与内核交互效率更高
更加开放的优化配置
tcp_defer_accept
延迟建立tcp连接直到真正的数据到来
有些操作系统不支持该配置
Jvm堆 vs 本地内存
apr使用本地内存,nio使用jvm堆
本地内存比jvm堆少拷贝一次
缺点:本地内存比jvm堆更难管理,出现内存泄露不容易定位
扩展:sendfile(零拷贝)
静态资源可考虑使用sendfile提升效率
不使用sendfile
使用sendfile
Processor
解析应用层
http
由Processor组件解析
解析为Request对象时只解析了请求头
真正解析请求体是在Servlet调用获取请求体内容的时候,如果一直不调用则一直不解析
ajp
与Apache服务器交互的协议
Adaper
processor解析后生成Request对象,而Servlet容器需要ServletRequest对象
所以需要Adapter对Request、ServletRequest和Response、ServletResponse之间进行互转
Servlet容器
有多层容器,由外到内为Engine、Host、Context、Wrapper
各容器父类ContainerBase内有pipeline
pipeline为valve链
在pipeline末端都有响应的BasicValve
在BasicValve中会调用子容器Pipeline的FirstValve
各容器抽象出接口Container
主要功能为管理子容器
扩展方式
Valve
各个Container都有Pipeline,可以添加Valve扩展
listener
各个Container状态改变时都有事件产生
线程池
重写jvm线程池的execute方法
捕获RejectedException异常后执行队列的force方法,再尝试入队一次,入队失败再抛出RejectedException
记录当前线程池任务数
扩展LinkedBlockingQueue
重写offer方法
判断线程数是否达到最大线程,是则直接尝试塞入
判断任务数是否小于当前线程数,是则直接尝试塞入
判断任务数是否大于当前线程数,是则返回false
与jvm不同:当线程数没有达到最大线程数并且没有空闲线程的时候,优先创建线程
类加载器
Jvm类加载器
双亲委派机制
BootstrapClassLoader
rt.jar
ExtClassLoader
ext目录
ApplicationClassLoader
classpath目录
tomcat类加载器
打破双亲委派
重写loadclass方法
判断是否在当前classloader缓存中已加载过
判断是否在parent缓存中已加载过
尝试使用ExtClassLoader加载
防止覆盖Jvm原生类
尝试自己加载,即调用findclass方法
交给parent加载
若加载失败,抛出异常
Servlet规范建议优先加载web应用目录下的类
隔离性
多个web应用会有多个自己的WebAppClassLoader
web应用共享的类可以使用SharedClassLoader加载
tomcat自己目录下的类使用CatalinaClassLoader加载,与web应用隔离
web应用与tomcat共享的类可以使用CommonClassLoader加载
一键启动
各组件都有生命周期,所以抽象出接口LifeCycle
主要功能为生命周期方法,start、init、stop、destroy
父组件负责启动子组件,只需启动Server组件,即可启动整个tomcat
类图
定时任务
StandardEngine会在init的时候使用schedule启动一个定时任务
该定时任务会调用当前容器以及子容器的backgroundprocess方法,所以各个容器可以依托该定时任务做一些操作
在执行定时任务的时候,会产生周期性的事件,说明容器还活着,可以干点什么事情
热加载
默认关闭,需要手动开启,配置loadable=true
StandardContext容器重写了backgroundProcess方法
扫描webapp目录下各个类文件是否有变更,如果有变更,调用context的reload方法
停止和销毁context容器及其子容器(即Servlet)
停止和销毁context下的filter和listener
停止和销毁context下的pipeline和valve
停止和销毁context的classloader及其加载的类
重新启动和初始化context,以及创建前四步销毁的组件
该reload并没有调用manager相关方法,即session没有被销毁
热部署
StandardHost容器注册定时任务事件监听器实现
粗粒度扫描,只扫描文件夹或者war包是否新增删除
如果扫描到文件夹被移除,则会把context销毁掉
如果扫描到有新增的文件夹,则创建context
Sesssion
浏览器通过在cookie中带着JSESSIONID或者重写URL实现会话
分布式session
tomcat提供了主从方案和复制session方案
主从方案依赖于负载均衡,并且需要节点较多
复制方案在小集群可行,大集群会导致网络拥堵
tomcat提供了可配置的redis共享session
Spring大都使用Spring Redis Session方案
Session清理
由StandardContext调用StandardManager的backgroundProcess方法实现
默认每六次process清理一次session,即60s
0 条评论
下一页