从大学开始接触java web的开发时就开始使用tomcat部署web项目,对它的理解仅仅停留在"这是个开源免费的servlet容器"的阶段,后来也接触了一些tomcat的体系,原理等方面的知识,也是半知半解,最近又开始看这方面的东西,截止到写这篇博文,我也不没有彻底理解它,但一些比较基础的东西总算有些眉目了,读源码不易,且行且珍惜,这里写篇笔记整理下.html
先盗张图:java
能够看到,Tomcat有一个最顶层的容器,也就是server容器,它最大,在server容器中,能够有多个service,由service来提供服务,因此service不能没有,至少得有一个.web
在service中,主要包含两个组件,Connector和Container.Container上图中没有标出,其实就是包含了Engine的部分.apache
Tomcat能够提供多种协议的请求,http协议就是其中一种,这里以http请求为例,一个http请求发到服务器时,由Connector来接收并进行转换,Connector就是用来处理链接相关工做的组件,好比能够进行Socket与request,response之间的转换,container是一个包含了servlet等众多资源的库,它接受Connector传过来的request请求,解析出请求的资源,返回给Container,因此Connector和Container一个主外一个主内,两人共同创建起美满的家庭.浏览器
固然上述比喻是不严谨的,由于一个Service中只有一个Container,但却能够有多个Connector,下面一段代码来自Tomcat目录下conf下的server.xml:tomcat
<Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> </Service>
能够看到,默认的Tomcat服务配置文件有两个Connector,一个负责监听8080端口,一个负责监听8009端口,前者咱们很熟悉了,它用来监听来自于浏览器的http请求,而后会new出一个线程来把请求传给Engine,然后者则是用来监听其余类型的servlet/jsp请求,叫AJP协议(我也没据说过).服务器
继续盗图,Container的体系结构:网络
Container是tomcat中容器的接口,咱们最熟悉的Servlet就封装在Container的子接口Wrapper中.看一下Server.xml中的配置:mvc
<Service name="Catalina"> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service>
Container有四个子容器,根据图示以及xml配置就能够看出来他们是逐层包含的关系.app
每一个service中只有一个Engine,Engine中能够由多个Host,每一个Host能够有多个Context,每一个Context中能够有多个Wrapper,而每个Wrapper里面就封装着一个Servlet.
下面分别简单总结几个容器:
Engine:顾名思义,引擎,它用来管理多个站点,也就是Host.
Host:表示一个站点,也能够叫作虚拟主机,在上面xml配置中,能够看到Tomcat默认配置了一个名为localhost的虚拟主机,咱们部署,运行项目时,就默认进入这个站点,Tomcat回去webapps目录下去定位请求的web项目资源.
Context:意思是上下文,它表示一个应用程序,也就是咱们开发的一个web项目,一个web项目就能够理解为一个Context.
Wrapper:每一个Wrapper封装一个servlet.
默认配置下的webapps下的每一目录都是一个应用,其中有一个ROOT目录表明主应用,整个webapps表示一个站点(Host),当咱们检测tomcat是否启动成功时通常都会打开http://localhost:8080/,这时候若是出现tomcat的官方站点就表示启动成功,其实这时候访问的就是ROOT应用下的资源,主应用就是直接使用域名访问就能够,假设webapps下还有一个helloword目录,若是你想访问helloword目录下的资源,就须要输入http://localhost:8080/helloword/.
<Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm"> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/> </Realm> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> </Engine> </Service> </Server>
在server.xml 中首先配置了一个server,在8005端口监听关闭命令"shutdown".
Server里定义了一个名为Catania的Service,Service里定义了两个Connector,一个是HTTP协议,一个是AJP协议,此外还定义了一个名为Catalina的Engine,Engine里定义了一个名为localhost的Host.
Host中name属性表示域名,因此这个默认Host能够用localhost来访问,appBase属性指定了站点的位置,这里就是webapps目录,这里还有不少属性,详细介绍,能够参考这篇博文:http://www.blogjava.net/baoyaer/articles/107278.html
没盗到图,本身画一张:
Connector是用来接收请求并把请求封装成Request和Response来进行具体的业务处理的,底层使用的Socket链接.
Connector实现了TCP/IP协议和HTTP协议,他会把Request和Response按照HTTP协议来进行封装,封装完以后交给Container来进行处理,待Container处理完以后,再返回回来,Connector使用Socket将返回结果返回给浏览器,完成整个处理请求.
下面简单介绍Connector中的几个重要组件
ProtocolHandler:处理不一样链接类型的请求,好比普通Socket请求和NioSocket请求.
Endpoint:处理底层Socket的网络链接.实现的是TCP/IP协议.
Processor:将Endpoint接收到的Socket请求封装成Request,实现的HTTP协议.
Adapter: 将Request请求适配给Container来处理.
整个Tomcat服务器其实就是java编写的一个应用,我尝试着读了一些源码,但资历尚浅,读的很艰难,一些代码上的实现方式和原理也不懂,只能大概理解一些类的功能,因此这里只是简单总结一些比较肤浅的知识,之后,有决心和毅力再去研读.共勉.