早期Web容器早期的 Web 应用主要用于浏览新闻等静态页面,HTTP 服务器(比如 Apache、Nginx)向浏览器返回静态 HTML,浏览器负责解析 HTML,将结果呈现给用户。
Servlet规范
随着互联网发展,往往更多的是需要动态的交互。所以 Sun 公司推出了 Servlet 技术:servlet 规范!目前最新是 Servlet 4.0 ,它支持 HTTP2.0!
符合 Servlet 规范的 Web 流程:由 Servlet 容器来创建和管理 Servlet,客户端的请求 会被封装成 ServletRequest 和 ServletResponse,其本质上就是对通信协议的封装。
Tomcat简介
Tomcat 就是一个 Servlet 容器,实现了对 Servlet 和 JavaServer Page(JSP)的支持。同时,它还具有 HTTP 服务器的功能。所以,「Tomcat = HTTP服务器 + Servlet容器」,一般我们给这种组件称为:「轻量级web容器」!
Tomcat架构
Tomcat-Server
- 「Server」:一个 Server 就是一个 Tomcat 实例,下载 Tomcat 压缩包,执行 /bin/startup.sh,就可以启动一个 Tomcat 实例。
- 「Service」:一个对外服务的整体,它包括多个 Connector 和一个 Engine。同时,一个 Server 可以配置多个 Service。实际上 Service 只是将组件组合到一起,本身并没有实现什么功能。
Tomcat-连接器
连接器,启动 ServerSocket,负责监听 Socket 请求,将数据转换成 Tomcat Request,交给 Engine 处理。一个 Service 可以有多个 Connector,表示它可以监听多个端口。
Tomcat-容器
即 Servlet 容器,它是 Tomcat 容器的最顶层组件,它会管理多个虚拟主机 Host,一个 Service 只能有一个 Engine,但是一个 Engine 可以配置多个 Host。Tomcat 的 Servlet 容器是具有明显的分层架构的。
- 「Host」:虚拟主机,默认为 localhost,也就是 127.0.0.1。也可以配置不同的 IP 地址,访问不同的 IP 地址就可以访问到不同的虚拟主机。一个 Host 可以部署多个 Context。
- 「Context」:应用程序,一般会把我们实现的 Servlet 应用打包成 war,放到 Tomcat 的 webapps 目录下,Tomcat 会将其解压并部署映射成一个 Context 组件,表示一个应用上下文。一个 Context 可以管理多个 Wrapper,毕竟一个 web 应用肯定有多个 Servlet。
- 「Wrapper」:这个组件 Tomcat 配置文件并没有,因为它是在 web.xml 配置,它就是 Servlet。确切地说,是 Tomcat 用 Wrapper 包裹了我们自己实现的 Servlet。一个请求最终就会到 Wrapper 来执行。
Tomcat生命周期管理
「Tomcat 设计众多组件来保证高内聚低耦合,保证可扩展性」。但是,组件数量多也会带来其它问题,比如组件的管理,在启动、关闭和销毁需要涉及多个组件的操作。Tomcat 设计了 LifeCycle 接口,它定义生命周期钩子函数:init()、start()、stop() 和 destroy(),组件都实现这个接口,定义自己的处理逻辑。并且,上层组件在触发自己生命周期钩子函数的同时,会触发它管理的下层组件的钩子函数。其实国外设计框架很喜欢设计这个 LifeCycle 接口,新版 Apache Dubbo 也加入了这一特性。
Tomcat 在实现组件生命周期管理,充分利用了「组合模式、观察者模式和模板模式」。
- 「组合模式」:Tomcat 通过组合模式,用上层组件来管理它下一级组件,每个组件都是这样的管理方式。这样暴露给用户的是,只需要对一个组件进行访问,则可以达到一个完整系统调用的一致性效果。以 Tomcat 最顶级的组件 Server 来看,它的 init() 方法:
- 「观察者模式」:Tomcat 考虑自身的可扩展性,避免版本升级就得修改生命周期钩子函数,它引入了监听器 LifecycleListener 和 LifecycleState。它设计了一套贯穿组件生命周期全过程的状态集合,例如:当组件刚创建则处于 NEW 状态,调用了 init() 方法处于 INITIALIZED 状态...在调用生命周期方法的前后,会改变组件的状态,而状态的改变会被封装成为一个个事件 LifecycleEvent,由监听器来处理这些事件。
- 「模板模式」:主要体现了代码实现上,实际上状态的转变、事件的创建以及监听器的回调,这些操作其实没有必要在每个组件中自己实现,这会造成重复代码。Tomcat 在实现这个功能的时候,把这些通用逻辑抽象了出来,定义为一个 LifecycleBase 抽象类,它会定义骨架方法,比如 init() 方法。
Tomcat连接器
Tomcat 连接器,用来监听 Socket 连接,将 TCP 底层的字节流数据,转换为 Request 和 Response;连接器主要有3个组件:「EndPoint、Processor、Adapter」。
- 「Endpoint」 负责提供字节流给 Processor。
- 「Processor」 负责提供 Tomcat Request 对象给 Adapter。
- 「Adapter」 负责转换 ServletRequest 对象给容器。
其中,Tomcat 将 EndPoint 和 Processor 组合到一起,组成了 ProtocolHandler,这其实就是一种组合设计模式的使用。
Tomcat连接器-NioEndpoint
「Tomcat 使用 NioEndPoint 基于 java 的 nio 包实现了 I/O 多路复用模型」,主要包含了 LimitLatch、Acceptor、Poller、SocketProcessor 和 Executor 共 5 个组件。它的工作过程如下:
- 「LimitLatch」:负责控制最大连接数,NIO 模式下默认是 10000,达到这个阈值后,连接请求被拒绝。它是基于 AQS 实现,原理就跟 Lock 一样。
- 「Acceptor」:独立线程,不断调用 ServerSocketChannel 的 accept() 方法来接收新连接,一旦有新的连接请求到来,返回 SocketChannel 对象,然后将其封装在一个 PollerEvent 对象中,并将 PollerEvent 对象压入 Poller 的 Queue 里(「典型的生产者 - 消费者模式」)。
- 「Poller」:独立运行在一个线程里,底层就是一个 Selector,每个 Poller 线程可能同时被多个 Acceptor 线程调用来注册 PollerEvent。Poller 不断的通过内部的 Selector 对象向内核查询 Channel 的状态,一旦可读就生成任务类 SocketProcessor 交给 Executor 去处理。
- 「SocketProcessor」:实现了 Runable 接口,主要是调用 Http11Processor 来处理请求。Tomcat 会将 Socket 包装成一个 SocketWrapper,Http11Processor 会调用 SocketWrapper 来读写数据。
- 「Executor」:自定义的线程池,负责运行 SocketProcessor ,会调用 Http11Processor 来读取和解析请求数据。Http11Processor 是应用层协议的封装,它会调用容器获得响应,再把响应通过 Channel 写出。
Tomcat连接器-Nio2Endpoint
Tomcat 还支持了异步 I/O,基于 Java AIO 实现 - Nio2Endpoint 的组件跟 NioEndpoint 类似,但是 Nio2Endpoint 中没有 Poller 组件,也就是没有 Selector。这是因为在异步 I/O 模式下,Selector 的工作交给内核来做了。
- 「LimitLatch」:跟 NioEndPoint 一样,连接控制器,它负责控制最大连接数。
- 「Nio2Acceptor」:扩展了 Acceptor,自己就是处理连接的回调类,用异步 I/O 的方式来接收新连接后,得到一个 AsynchronousSocketChannel,它会将其封装成一个 Nio2SocketWrapper,并创建一个SocketProcessor 任务类交给线程池处理。
- 「Nio2SocketWrapper」:实际读取 Channel 内的数据,并提供接口给 Http11Processor 读写。但是由于异步 I/O 的性质,Http11Processor 读取 Nio2SocketWrapper 时很有可能内核还没有将数据准备好,为了解决这个问题,Http11Processor 采用了2次 read 调用:通过注册回调类 readCompletionHandler。
最后
其实 Tomcat 的实现细节很多,没办法一一重现,大部分情况下需要自己去对着源码跑一遍,像很多实际运用:
- ContainerBackgroundProcessor,实现热更新机制:热加载和热部署。
- 对象池技术,典型的以空间换时间的思路,通过 SynchronizedStack 减少 SocketWrapper 和SocketProcessor 的创建和销毁。
- Servlet 3.0 中引入的异步 Servlet,Tomcat 对其做了支持,它的思想是:让业务线程和 Tomcat I/O 线程分离开,将复杂耗时的业务计算移到业务线程池中进行,释放 Tomcat的I/O 线程,以便可以及时响应其它请求。
- 会话管理...
- 集群管理...
网站名称:深入分析Tomcat原理
文章地址:http://www.shufengxianlan.com/qtweb/news12/446662.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
广告
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源:
创新互联