重温web服务器--细说Tomcat服务器

简介:   从大学开始接触java web的开发时就开始使用tomcat部署web项目,对它的理解仅仅停留在"这是个开源免费的servlet容器"的阶段,后来也接触了一些tomcat的体系,原理等方面的知识,也是半知半解,最近又开始看这方面的东西,截止到写这篇博文,我也不没有完全理解它,但一些比较基础的东西总算有些眉目了,读源码不易,且行且珍惜,这里写篇笔记整理下.

  从大学开始接触java web的开发时就开始使用tomcat部署web项目,对它的理解仅仅停留在"这是个开源免费的servlet容器"的阶段,后来也接触了一些tomcat的体系,原理等方面的知识,也是半知半解,最近又开始看这方面的东西,截止到写这篇博文,我也不没有完全理解它,但一些比较基础的东西总算有些眉目了,读源码不易,且行且珍惜,这里写篇笔记整理下.

Tomcat体系结构

  先盗张图:

    

  可以看到,Tomcat有一个最顶层的容器,也就是server容器,它最大,在server容器中,可以有多个service,由service来提供服务,所以service不能没有,至少得有一个.

  在service中,主要包含两个组件,Connector和Container.Container上图中没有标出,其实就是包含了Engine的部分.

  Tomcat可以提供多种协议的请求,http协议就是其中一种,这里以http请求为例,一个http请求发到服务器时,由Connector来接收并进行转换,Connector就是用来处理连接相关工作的组件,比如可以进行Socket与request,response之间的转换,container是一个包含了servlet等众多资源的库,它接受Connector传过来的request请求,解析出请求的资源,返回给Container,所以Connector和Container一个主外一个主内,两人共同建立起美满的家庭.

  当然上述比喻是不严谨的,因为一个Service中只有一个Container,但却可以有多个Connector,下面一段代码来自Tomcat目录下conf下的server.xml:

<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的体系结构:

    

  Container是tomcat中容器的接口,我们最熟悉的Servlet就封装在Container的子接口Wrapper中.看一下Server.xml中的配置:

<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 &quot;%r&quot; %s %b" />
      </Host>
    </Engine>
  </Service>

  Container有四个子容器,根据图示以及xml配置就可以看出来他们是逐层包含的关系.

  每个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/.

conf目录下的配置文件server.xml  

<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 &quot;%r&quot; %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

 Container体系结构

  没盗到图,自己画一张:

  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编写的一个应用,我尝试着读了一些源码,但资历尚浅,读的很艰难,一些代码上的实现方式和原理也不懂,只能大概理解一些类的功能,所以这里只是简单总结一些比较肤浅的知识,以后,有决心和毅力再去研读.共勉.

参考资料:

  <看透Spring mvc源码>第七章:Tomcat分析 

相关文章
|
1月前
|
存储 资源调度 应用服务中间件
浅谈本地开发好的 Web 应用部署到 ABAP 应用服务器上的几种方式
浅谈本地开发好的 Web 应用部署到 ABAP 应用服务器上的几种方式
27 0
|
1月前
|
网络协议 Shell 网络安全
实验目的1.编译安装httpd2.优化路径3.并将鲜花网站上传到web服务器为网页目录4.在客户机访问网站http://www.bdqn.com
实验目的1.编译安装httpd2.优化路径3.并将鲜花网站上传到web服务器为网页目录4.在客户机访问网站http://www.bdqn.com
164 0
|
1月前
|
前端开发 应用服务中间件 nginx
使用Docker快速搭建Web服务器Nginx
本文指导如何使用Docker快速搭建Nginx服务器。首先,通过`docker pull`命令获取Nginx镜像,然后以容器形式运行Nginx并映射端口。通过挂载目录实现本地文件与容器共享,便于自定义网页。使用`docker ps`检查运行状态,访问IP:8088确认部署成功。最后,介绍了停止、删除Nginx容器的命令,强调Docker简化了服务器部署和管理。
50 0
|
7天前
|
Java 应用服务中间件 Linux
在阿里云服务器上部署Tomcat详细图文详解
本文介绍了在阿里云服务器上安装和配置JDK和Tomcat的步骤。首先,需要注册阿里云账号并进行实名认证,然后购买并设置服务器。接着,通过File Zilla连接服务器,创建Java和Tomcat的安装目录,并将JDK和Tomcat的tar.gz文件上传到服务器,解压并重命名。之后,配置JDK的环境变量,将catalina.sh复制到/etc/init.d/目录下,并修改相关配置。最后,启动Tomcat并配置安全组规则,确保可以通过公网访问。
|
10天前
|
Web App开发 Java 应用服务中间件
【Java Web】在 IDEA 中部署 Tomcat
【Java Web】在 IDEA 中部署 Tomcat
|
13天前
|
Java 应用服务中间件 Linux
阿里云服务器部署多个tomcat
阿里云服务器部署多个tomcat
|
1月前
|
Windows
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
57 2
|
1月前
|
机器学习/深度学习 Python
Python基础:构建一个简单的Web服务器
Python基础:构建一个简单的Web服务器
57 1
|
1月前
|
应用服务中间件 Apache nginx
web后端-web服务器对比
web后端-web服务器对比
|
22天前
|
监控 JavaScript 前端开发
《理解 WebSocket:Java Web 开发的实时通信技术》
【4月更文挑战第4天】WebSocket是Java Web实时通信的关键技术,提供双向持久连接,实现低延迟、高效率的实时交互。适用于聊天应用、在线游戏、数据监控和即时通知。开发涉及服务器端实现、客户端连接及数据协议定义,注意安全、错误处理、性能和兼容性。随着实时应用需求增加,WebSocket在Java Web开发中的地位将更加重要。