web服务器

简单来说只要Web上的Server都叫Web Server,但是大家分工不同,解决的问题也不同,所以根据Web Server提供的功能,每个Web Server的名字也会不一样。

但是按功能来分web服务器主要分为http serverapplication server

1
2
3
4
5
6
|- Web Server
|- Http Server
|- Application Server
|- Servlet Container
|- CGI Server
|- ......

htt服务器

HTTP Server本质上也是一种应用程序——它通常运行在服务器之上,绑定服务器的IP地址并监听某一个tcp端口来接收并处理HTTP请求,这样客户端(一般来说是IE, Firefox,Chrome这样的浏览器)就能够通过HTTP协议来获取服务器上的网页资源。

一个HTTP Server关心的是HTTP协议层面的传输和访问控制,所以在Apache/Nginx上你可以看到代理、负载均衡等功能。

HTTP Server中经常使用的是Apache、Nginx两种,HTTP Server主要用来做静态内容服务、代理服务器、负载均衡等。直面外来请求转发给后面的应用服务(Tomcat,django什么的)。

1
2
3
|- Application Server
|- Tomcat
|- Jetty

Application Server

Application Server 是一个应用执行的服务器。它首先需要支持开发语言的 Runtime(对于 Tomcat 来说,就是 Java),保证应用能够在应用服务器上正常运行。其次,需要支持应用相关的规范,例如类库、安全方面的特性。与HTTP Server相比,Application Server能够动态的生成资源并返回到客户端。

1
2
3
|- Application Server
|- Tomcat
|- Jetty

在Apache Server开发时还未出现Servlet的概念,所以Apache不能内置支持Servlet。实际上,除了Apache,其他许多HTTP Server软件都不能直接支持Servlet。为了支持Servlet,通常要单独开发程序,这种程序一般称为服务器小程序容器(Servlet Container),有时也叫做服务器小程序引擎(Servlet Engine)。它是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于MIME的请求,格式化基于MIME的响应,它在Servlet的生命周期内包容和管理Servlet,是一个实时运行的外壳程序。运行时由Web服务器软件处理一般请求,并把Servlet调用传递给“容器”来处理。

比如,对于 Tomcat 来说,就是需要提供 JSP/Sevlet 运行需要的标准类库、Interface 等。为了方便,应用服务器往往也会集成 HTTP Server 的功能,但是不如专业的 HTTP Server 那么强大,所以Application Server往往是运行在 HTTP Server 的背后,执行应用,将动态的内容转化为静态的内容之后,通过 HTTP Server 分发到客户端。

Tomcat运行在JVM之上,它和HTTP服务器一样,绑定IP地址并监听TCP端口,同时还包含以下指责:

1
2
3
1. 管理Servlet程序的生命周期;
2. 将URL映射到指定的Servlet进行处理;
3. 与Servlet程序合作处理HTTP请求——根据HTTP请求生成HttpServletRequest/Response对象并传递给Servlet进行处理,将Servlet中的HttpServletResponse对象生成的内容返回给浏览器;

所以 Tomcat 属于是一个「Application Server」,但是更准确的来说,是一个「Servlet/JSP」应用的容器

tomcat的内部结构

从上图就可以看出tomcat的内部结构的核心主要分为两部分连接器(Connector)容器(Container)而他们的主要作用如下

  • Connector用于处理连接相关的事情,并提供Socket与Request和Response相关的转化;
  • Container用于封装和管理Servlet,以及具体处理Request请求;

一个Tomcat中只有一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但是可以有多个Connectors,这是因为一个服务可以有多个连接,如同时提供Http和Https链接,也可以提供向相同协议不同端口的连接,示意图如下
connectors

connector 架构分析

Connector用于接受请求并将请求封装成Request和Response,然后交给Container进行处理,Container处理完之后在交给Connector返回给客户端。
因此,我们可以把Connector分为四个方面进行理解:

  • Connector如何接受请求的?
  • 如何将请求封装成Request和Response的?
  • 封装完之后的Request和Response如何交给Container进行处理的?
  • Container处理完之后如何交给Connector并返回给客户端的?

下图是Connector的结构图
conn2

Connector就是使用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型,比如:Http11Protocol使用的是普通Socket来连接的,Http11NioProtocol使用的是NioSocket来连接的。

其中ProtocolHandler由包含了三个部件:Endpoint、Processor、Adapter。

  • Endpoint用来处理底层Socket的网络连接,Processor用于将Endpoint接收到的Socket封装成Request,Adapter用于将Request交给Container进行具体的处理。

此时前三个问题就可以解答了,但是第四个问题还要看container的架构

container 架构分析

首先先看container的架构图
container

从图中可以看到container有4个子容器Engine、Host、Context、Wrapper它们的作用分别是:

  • Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
  • Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
  • Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
  • Wrapper:每一Wrapper封装着一个Servlet;

假设adapter提交了一个访问请求地址为http://localhost:8080/examples/composite.jsp的请求到Container那么container会通过以下流程处理该请求:

  • Container容器交给其子容器——Engine容器,并等待Engine容器的处理结果
  • Engine容器匹配其所有的虚拟主机,这里匹配到Host
  • 请求被移交给hostname为localhost的Host容器,host匹配其所有子容器Context,这里找到contextPath为/examples的Context容器。如果匹配不到就把该请求交给路径名为”“的Context去处理
  • 请求再次被移交给Context容器,Context继续匹配其子容器Wrapper,由Wrapper容器加载composite.jsp对应的servlet,这里编译的servlet是basic_002dcomparisons_jsp.class文件
  • Context容器根据后缀匹配原则*.jsp找到composite.jsp编译的- java类的class文件
  • Connector构建一个org.apache.catalina.connector.Request以及org.apache.catalina.connector.Response对象,使用反射调用Servelt的service方法
  • Context容器把封装了响应消息的Response对象返回给Host容器
  • Host容器把Response返回给Engine容器
  • Engine容器返回给Connector
  • Connetor容器把Response返回给浏览器
  • 浏览器解析Response报文
  • 显示资源内容

通过这样的从上到下的查找锁定了该请求的servlet然后,再逐级递交response返还给connector返还给浏览器完成了一次请求的处理

总结

tomcat服务器实质是一个web容器,核心架构就是connector和container。当请求传递过来之后。connector会接受请求通过ndpoint、Processor、Adapter三个子部件转化二进制请求为可以使用的request对象并传递给container,container通过Pipeline-Valve管道逐级处理和锁定(engine到host到context到wrapper)处理请求的servlet将封装了响应信息的response对象逐级返还到connector。最后传递给浏览器进行解析。这样便完成了整个对服务端的请求。