详解主流Java应用服务器的工作原理及组件设计(有彩蛋)

2018 年 3 月 6 日 DBAplus社群 刘光瑞


本文根据DBAplus社群第138期线上分享整理而成,文末还有好书送哦~


讲师介绍

刘光瑞

《Tomcat架构解析》作者


  • 现任窝客研发总监,负责窝客产品研发管理及总体架构设计。

  • 拥有十几年企业级大型业务系统研发架构经验,成功带领团队设计并研发基于Tomcat的组件化微服务架构。

  • 热衷于系统架构、Java技术栈及应用服务器中间件的学习及研究。


今天所讲内容的大纲如下:

  1. Java应用服务器分类

  2. Servlet容器工作原理

  3. Tomcat组件及请求处理



一、Java应用服务器分类


大概从2000年以后,Java应用服务器的使用主要经历了3个阶段:J2EE应用服务器、Servlet容器及Web服务器、响应式微服务。


1、J2EE应用服务器


首先,是J2EE应用服务器。这部分在以Spring为主的without EJB的应用框架出现之前,基本上是企业应用开发的标配。这类应用服务器严格实现了J2EE规范,通过了SUN的相关认证,还支持标准的基于J2EE的应用开发,包括EJB、JMS、JTA、Servlet、JSF等等。



这类应用服务器有很强的配置和优化能力,非常适合集中式的大型企业级应用开发。这一类的产品情况如下:



像WebSphere这一类商用产品,是大型的银行、电信应用的主流服务器,甚至配合IBM的JVM实现,有着非常好的性能优势。


免费的诸如JBOSS,使用也非常广泛,作为商用企业级应用服务器的减配版。


企业级应用服务器的特点就是过重。大概2010年之后(具体时间不确定),有几个转向了OSGi这种模块化架构,期望提供一种更加灵活的架构。像JBoss这一类产品在互联网规模化、轻量化的大背景下,似乎使用的相对越来越少。但是在集中式的企业级应用场景,它们应该还是主流,轻量级服务器是很难取代的。


2、Servlet容器及Web服务器


这一类在后面才提到,并不是说它们的历史较短,像Tomcat的历史可以说是最长的几款服务器实现。而是说它们被大规模用于生产环境的尝试,相对较晚。


这是与互联网应用大规模分布式架构分不开的。在轻量级的架构中,绝大多数应用实际上主要使用了服务器的Servlet容器部分,其它部分很少使用,而是使用更完善的第三方框架去替代。这时候,J2EE服务器显得过重,所以开始更倾向于只使用Servlet容器提供HTTP服务。



这一类服务器见图片,主要是Tomcat、Resin、Jetty、Undertow。



Tomcat大家想必都很熟悉了,基本Java Web应用开发入门就使用。它主要的使用场景还是独立启动部署Web应用,嵌入式的场景与Jetty相比,要相对差一些;Undertow出现相对晚一些,它是JBoss实现的新的Servlet容器,以前JBoss直接使用Tomcat作为Servlet容器。


如果大家基于Spring Boot开发应用,想必都知道,现在Spring Boot对这三款容器都支持,现在用的比较多的是Tomcat和Jetty,Undertow使用的相对较少。


后两者是很少作为独立启动的服务器来使用的,尤其是Undertow,应该不支持这种场景。


3、响应式微服务


这一类严格说并不是Web服务器。有时候(如微服务架构),我们更倾向于直接提供HTTP服务,这个时候并不需要支持Web,不需要Servlet规范。



这一类就是为这种场景设计的,目前有两类方案可以来满足这种场景,一种是Vert.x,这个国内目前使用应该不是很多。主要是它不支持Servlet规范,这估计是一方面的原因。


还有一种是Play Framework内置的基于事件的HTTP服务,和Vert.x类似,它们都是为高并发的互联网服务开发实现的。今天对于这种方案我们不做展开,还是以主流的Servlet方案为主。



二、Servlet容器工作原理


应用服务器基于Servlet提供基础的HTTP服务,包括Web服务、SOA,即便是JSP页面,最终也是通过Servlet实现的。因此Servlet容器可以说是Web服务的核心。



1、容器的核心部分


对于一款Servlet容器,主要分为两部分:链接器和容器。前者是服务器对I/O的封装,后者是对Servlet规范的实现。



大家可以简要看一下这一篇的内容:一款服务器通过链接器读取网络请求,将其转换为符合Servlet规范的Request对象,同时负责将Servlet容器的响应输出到客户端。


它对Servlet容器屏蔽了协议及I/O方式等的区别。无论是HTTP还是AJP、还是HTTPS,在容器中获取到的都是一个标准的Request对象。



而容器呢,主要负责三个方面的工作:

  • 按照Servlet规范(Web.xml/注解等等),识别部署的Web应用,将其解析为内部的请求处理组件;

  • 接收链接器的请求调用(一般不需要容器负责请求映射,映射部分是链接器完成的);

  • 按照Servlet规范进行请求处理,这部分主要是Filter等的处理。



2、工作原理


大家可以看一下这个示意图:



对于链接器,无论采用哪一种I/O,都是采用一种线程池的方式来处理的。


主要有两个线程池,一个用于接收请求,一个用于处理请求。接收请求的线程负责读取请求头,完成请求映射,并将请求提交到映射到的请求处理组件(一个指定的Servlet)。


这儿大家注意一点,容器映射完成的结果是一个Servlet,而不是一个Web应用,至少Tomcat是这样处理的,Jetty更轻量。


虽然Servlet的具体实现不同,但是完成的工作基本类似,而且模式也类似(除去我们说的第三类)。


接下来我们具体看一下Tomcat是如何实现Servlet容器的:相对于Jetty轻量的处理架构,Tomcat更像“服务器”一些,它考虑了一些服务器的特性,如虚拟主机。



三、Tomcat组件及请求过程


1、容器主要组件


Tomcat的主要组件可以看一下下面这张图:它底层通过Java命名服务统一对各种组件进行管理,体现了服务器软件的“管理”特性;然后是链接器实现Coyote和Jasper JSP引擎。



Tomcat与Jetty相比,它更是一款完整的Servlet容器方案。而Jetty是以模块化的形式提供了Servlet容器以及各种HTTP工具集。像JSP引擎,Jetty直接使用的Tomcat中的Jasper(还有另一种可选方案)。


最上面的Catalina是Tomcat容器的实现。大家如果看Tomcat的异常堆栈,就会发现包名基本都是以这个作为开头。


Tomcat链接器,我们可以简单的按两层进行划分:应用层和传输层。



应用层里,最新版本的Tomcat支持HTTP、AJP以及HTTP2,传输层支持NIO、NIO2以及APR,最新版本已经不支持BIO。



链接器还有一个很重要的组件就是线程池,想必做过基本的Tomcat优化的人都调整过Tomcat并发链接数。线程池的分类我们刚才也说过了,分为接收线程池和请求处理线程池。


2、Tomcat Servlet容器组件


Servlet容器的组件见图:简单来说,Tomcat通过一种分层的架构使得Servlet容器有很好的灵活性,而且通过生命周期管理接口,为这些各层的对象提供统一的生命周期管理。



分层如下:Engine-Host-Context-Wrapper。引擎是顶级,我们可以认为就是容器本身。Host是虚拟主机的概念,这样可以在Tomcat配置多个虚拟主机。Context就是我们的Web应用,Wrapper是Web应用中的Servlet,所以还是刚才说的,Tomcat中的请求映射是体现到Servlet上。


基于分层的组件,Tomcat还提供了完善的生命周期事件处理机制,Web应用的自动扫描启动、热部署、卸载等都是通过事件实现的。如果阅读Tomcat代码,需要重点关注下面的生命周期监听。



HostConfig主要用于扫描Web应用,自动根据Web应用目录创建Context。ContextConfig重点处理Servlet规范,生成Servlet、Filter等各种规范组件。最后,Tomcat自身也实现了一种链式的请求处理机制,这一点和规范中的Filter类似,这就是Valve。


在Tomcat中,Filter中可以做的事情,Valve可以做;Valve可以做的事情,Filter却不一定可以做,需要深入和服务器交互的工作,一般都是用Valve实现。


3、请求处理过程


这是一张Tomcat请求处理过程的时序图,大家看一下就会发现。Tomcat在这种分层的容器设计方案下,请求处理是很简单的,重点在前期的请求接收及I/O处理(Processor的各种实现)、Mapper的映射以及Wrapper中的规范处理。



4、Tomcat的优化


最后一点内容,我们再概要介绍一下Tomcat的优化。今天介绍的相对比较基础,大家感兴趣的还是需要去看相关的专门的书籍。


Tomcat优化主要但不限于以下四个方面:线程池、协议、JVM以及I/O,之所以说不限于,是因为应用服务器的优化,不仅要去优化其自身,诸如操作系统等也是要统一考虑的。



线程池就是我们刚才说的两类。接收线程池一般都是CPU内核数即可。当然如果服务器核数非常多,可以适当调小。这个线程池处理速度比请求处理线程池要快的多,因此要考虑这两者的匹配,原因PPT中都介绍了。



做请求处理线程池这个设置时,最好做一些基准测试,并没有什么精确的经验值。


协议层面。这个最常见的就是开启HTTP GZip压缩。如果配置了前置的Web服务器,那么静态文件可以考虑直接放到Web服务器上,然后可以修改HTTP链接器的I/O方式。新版本的Tomcat默认是NIO,可以改为APR,后者可以充分发挥本地调用的优势,与直接使用Apache基本是类似的。



当然对于前置了Web服务器的,可以采用AJP协议与Web服务器链接。Apache应该没问题,Nginx好像没有官方的AJP实现。第三方的就需要考虑健壮性和支持程度了。



然后是JVM,这部分估计最常见的就是调整JVM的堆内存。对于垃圾回收算法,也需要根据具体的应用场景进行调整。是吞吐量优先还是响应时间优先,需要使用多少线程去处理,这些都需要在具体的硬件配置下进行具体的测试才行。



今天的内容到此就结束了,主要内容还是非常概要,每一部分大家如果想深入了解,都需要去阅读相关书籍。协议、规范、JVM,这些都是必不可少的。

彩蛋来了

在本文微信订阅号(dbaplus)评论区留下足以引起共鸣的真知灼见,小编将在本文发布后的隔天中午12点选出留言内容最精彩的3位读者送出以下好书一本~

新规说明:同一个月份里,已获赠者将不可重复拿书。

特别鸣谢图灵社区为活动供图书赞助。


近期热文

提前排雷!分布式缓存的25个优秀实践与线上案例

借鉴Codis实现的两种不停机分库分表迁移方案

从Elasticsearch集群及数据层架构,看分布式系统设计

DBA+工具:SQL自审自上线,摆脱人肉审核就在当下 

关联与下钻:快速定位MySQL性能瓶颈的制胜手段


最新活动

2018 Gdevops全球敏捷运维峰会(成都站)

↓↓↓点这里了解更多报名详情

登录查看更多
0

相关内容

JavaEE 是 Java 平台企业版(Java Platform Enterprise Edition), 是 由Sun 公司(Sun公司现被Oracle公司收购)推出的广泛运用于服务器端编程的平台。
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
专知会员服务
30+阅读 · 2020年5月20日
《深度学习》圣经花书的数学推导、原理与Python代码实现
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
【阿里技术干货】知识结构化在阿里小蜜中的应用
专知会员服务
96+阅读 · 2019年12月14日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
40张PPT,帮你轻松入门Spark大数据!BAT架构师制作!
七月在线实验室
19+阅读 · 2019年5月27日
工行基于MySQL构建分布式架构的转型之路
炼数成金订阅号
15+阅读 · 2019年5月16日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
从webview到flutter:详解iOS中的Web开发
前端之巅
5+阅读 · 2019年3月24日
一张图理清电商后台产品模块,90%的电商类产品后台都适用
人人都是产品经理
8+阅读 · 2018年12月9日
iOS高级调试&逆向技术
CocoaChina
3+阅读 · 2017年7月30日
Arxiv
10+阅读 · 2020年4月5日
Arxiv
29+阅读 · 2020年3月16日
Arxiv
110+阅读 · 2020年2月5日
Area Attention
Arxiv
5+阅读 · 2019年5月23日
Arxiv
7+阅读 · 2018年3月21日
Arxiv
3+阅读 · 2017年11月21日
VIP会员
相关VIP内容
【2020新书】使用高级C# 提升你的编程技能,412页pdf
专知会员服务
57+阅读 · 2020年6月26日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
234+阅读 · 2020年5月21日
专知会员服务
30+阅读 · 2020年5月20日
《深度学习》圣经花书的数学推导、原理与Python代码实现
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
【阿里技术干货】知识结构化在阿里小蜜中的应用
专知会员服务
96+阅读 · 2019年12月14日
【干货】大数据入门指南:Hadoop、Hive、Spark、 Storm等
专知会员服务
95+阅读 · 2019年12月4日
相关资讯
携程用ClickHouse轻松玩转每天十亿级数据更新
DBAplus社群
11+阅读 · 2019年8月6日
40张PPT,帮你轻松入门Spark大数据!BAT架构师制作!
七月在线实验室
19+阅读 · 2019年5月27日
工行基于MySQL构建分布式架构的转型之路
炼数成金订阅号
15+阅读 · 2019年5月16日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
从webview到flutter:详解iOS中的Web开发
前端之巅
5+阅读 · 2019年3月24日
一张图理清电商后台产品模块,90%的电商类产品后台都适用
人人都是产品经理
8+阅读 · 2018年12月9日
iOS高级调试&逆向技术
CocoaChina
3+阅读 · 2017年7月30日
相关论文
Arxiv
10+阅读 · 2020年4月5日
Arxiv
29+阅读 · 2020年3月16日
Arxiv
110+阅读 · 2020年2月5日
Area Attention
Arxiv
5+阅读 · 2019年5月23日
Arxiv
7+阅读 · 2018年3月21日
Arxiv
3+阅读 · 2017年11月21日
Top
微信扫码咨询专知VIP会员