我们知道,不同肤色的人外貌差别很大,而双胞胎的辨识很难。有意思的是 Web 服务器/Web 容器/Web 应用程序服务器/反向代理有点像四胞胎,在网络上经常一起出现。本文将对这四个概念进行区分。
Web 服务器概念与基本原理
Web 服务器的历史
1989 年,互联网之父 Berners-Lee 向其雇主 CERN 提出了一个新项目,目的是通过使用超文本系统来缓解科学家之间的信息交流。
该项目导致 Berners-Lee 在 1990 年编写了两个方案:
- 一个名为 World Wide Web 的浏览器。
- 世界上第一个网络服务器,后来被称为 CERN httpd,它运行在 NeXTSTEP 上在 1991 年至 1994 年期间,用于通过万维网冲浪和交换数据的早期技术的简单性和有效性有助于将其移植到许多不同的操作系统,并将其用于科学组织和大学,然后传播到行业。
1994 年,Berners-Lee 决定组建万维网联盟(W3C),通过标准化过程来管理涉及的许多技术(HTTP,HTML 等)的进一步发展。
就是这台服务器:
Web 服务器的主要功能是存储,处理和传递网页给客户。客户端和服务器之间的通信使用超文本传输协议(HTTP)进行。
交付的页面最常见的是 HTML 文档,除了文本内容之外,还可能包含图像,样式表和脚本。
一个用户代理,通常是 Web 浏览器或 Web 爬虫,通过发起一个 HTTP 请求以获取服务器资源,服务器根据请求返回该资源或由于某种原因响应错误消息。
该资源通常是服务器辅助存储上的真实文件,但这不一定是这种情况,取决于 Web 服务器的实现方式。
虽然主要功能是提供内容,但 HTTP 的完整实现还包括从客户端接收内容的方式。此功能用于提交 Web 表单,包括上传文件。
许多通用 Web 服务器还支持使用 Active Server Pages(ASP),PHP 或其他脚本语言的服务器端脚本。
这意味着 Web 服务器的行为可以在单独的文件中脚本化,而实际的服务器软件保持不变。
通常,此函数用于动态生成 HTML 文档(“即时”),而不是返回静态文档。前者主要用于从数据库检索或修改信息;后者通常快得多,并且更容易被缓存,但不能提供动态内容。
Web 服务器不仅用于为万维网服务。它们也可以被嵌入到诸如打印机,路由器,网络摄像机等设备中,并且仅服务于本地网络。
然后,Web 服务器可以用于监视或管理所讨论的设备的系统的一部分。
这通常意味着客户端计算机上不需要安装其他软件,因为只需要一个网络浏览器(现在大多数操作系统都包含在内)。
Web 服务器工作原理
HTTP 协议基于 TCP 协议上,是一个应用层协议,用于用户代理和 Web 服务器进行通信。
Web 服务器通常采用一问一答的方式进行工作:
- 在用户代理上用户发起资源请求,请求内容包括但不限于:指定资源的唯一标识 URI,指明动作类型(GET/POST/DELETE/PUT…)
- 用户代理解析用户输入 URI 并从中获取目标域名,交由 DNS 服务器解析。如果 URI 中指定某 IP 地址,就无需这步。
- 如果与服务器的会话还没建立,此时先建立 TCP 连接,并完成 HTTP 协商(确定双方均可接受的处理方式,包括协议版本,是否加密,内容格式等等)。
- 用户代理把请求内容封装成 HTTP 数据包向服务器发送。
- 服务器接收到资源请求并以之前协商好的方式解包并处理。
- 服务器请求的资源封装成 HTTP 数据包并返回给用户代理。
接下来重点说说服务器端的工作原理,如下图:
TCP 监听模块:服务器监听某个端口(一般默认是 8080 端口,用户可以设置其他端口),以建立和用户代理之间的连接。一旦建立连接,用户代理的后续 HTTP 请求将不用再进入监听模块。
预处理:此处主要做三件事,从 TCP 报文中获取 HTTP 请求报文,根据和用户代理的协商进行解密,解压,安全处理等等。根据服务器自身的配置进行安全处理,建立会话状态等等。
UR 路由:解析 URL 字符串和动作以确定用户代理请求的资源,根据匹配规则(通常根据正则表达式+后缀)路由到静态资源处理模块或动态资源处理模块。
静态资源处理模块:负责找到静态资源,比如 HTML/JavaScript/CSS 文件/图片/图像,确定内容是字符流或者字节流,并确定对应 MIME。
比如 HTML 生成 MIME 为 text/html 的字符流,mpeg 视频文件生成 MIME 为 video/mpeg 的字节流。
动态资源处理模块:运行业务逻辑处理,动态决定返回的资源内容和类型,内容和类型的处理原则同上。
后处理:根据和用户协商的协议进行加密,压缩,安全处理等等。
资源输出模块:把处理好的内容和类型封装成 HTTP 报文,往 TCP 连接另一头的用户代理发送 TCP 报文(内容是 HTTP 报文)。
主流 Web 服务器
包括 Apache、IIS 、Nginx 市场占有率如下图:
还有比较多使用 Tomcat,Jetty,WebSphere,WebLogic,Kerstrel 等等。
Web 应用程序容器概念与基本原理
Web 应用程序容器的由来
Web 服务器的出现标志着 WWW 时代的到来,世界变得更加平面化。当初尝到甜头的开创者们开始不满足于在互联网上获取静态资源,于是出现了 CGI 脚本来动态获取资源。
再后来网络发展方向也是朝着增强 Web 服务器动态获取资源的能力前进。以下是代表性的动态技术:
Web 应用程序容器的基本工作原理
一般情况下,Web 应用程序容器是以下构成体系:
注:浅蓝色的模块是实现业务程序的主要使用模块
相对于 Web 服务器,该容器新增或强化了以下模块:
- 分配线程池资源,容器为每个请求分配一个线程进行处理,通常采取线程池的方式高效率由 CPU 算资源。
- 封装 Request 上下文,一个请求对应一个 Request 上下文,它主要封装了用户请求的主要构成。
URL,HTTP 请求头,以及基于请求头构建的 Session,Cookie 等对象,方便编程使用。
- 封装 Response 上下文,一个请求对应一个 Response 上下文,主要用于向用户代理返回资源。可以在其中写入输出流,或者重定向,或者返回错误码等等。
- URL 路由,在容器里,运行开发人员设置不同的路由匹配规则,比如让 .HTM 返回 .HTML,也可以自定义 .xyz 返回 .HTML 资源。更加灵活的配置可以参考 Java MVC 或者 ASP.NET MVC 的配置方案。
- 动态资源处理模块,通常在这里具体的容器和开发语言都有自己的高效开发模型,比如 Java 的 Servlet,ASP.NET 的 Web Form,MVC。
- 回收资源,这里会回收刚才的线程资源,为了线程复用,除非服务器空闲一般会将线程返回线程池。
可以看出,Web 容器本身具备了做为一个 Web 服务器的功能,事实上通常实现 Web 容器功能的服务器就是一个 Web 服务器。比如 Tomcat,IIS,Jetty。
主流 Web 容器
包括 Tomcat,IIS,Jetty 。还有比较多使用 WebSphere,WebLogic 等等。
Web 应用程序服务器概念及基本原理
在 Web 服务器发展的同一个时期,应用服务器已经存在并发展很长一段时间了。
一些公司为 Unix 开发了 Tuxedo(面向事务的中间件)、TopEnd、Encina 等产品,这些产品都是从类似 IMS 和 CICS 的主机应用管理和监控环境衍生而来的。
大部分的这些产品都指定了“封闭的”产品专用通信协议来互连胖客户机(“fat” client)和服务器。
在 90 年代,这些传统的应用服务器产品开始嵌入 HTTP 通信功能,刚开始要利用网关来实现。不久后它们之间的界线开始变得模糊了。
同时,Web 服务器越来越成熟,可以处理更高的负载、更多的并发和拥有更好的特性;应用服务器开始添加越来越多的基于 HTTP 的通信功能。所有的这些导致了 Web 服务器与应用服务器的界限变得更窄了。
目前,“应用服务器”和“Web 服务器”之间的界限已经变得模糊不清了。但是人们还把这两个术语区分开来,作为强调使用。
当有人说到“Web 服务器”时,你通常要把它认为是以 HTTP 为核心、Web UI 为向导的应用。
当有人说到“应用服务器”时,你可能想到“高负载、企业级特性、事务和队列、多通道通信(HTTP 和更多的协议)”。但现在提供这些需求的基本上都是同一个产品。
下图描述一个典型的 Web 应用服务器的结构图:
从上图中可以看到 Web 应用服务器包括了 Web 容器,同时内置了支撑企业应用的事务,安全,集成,通信,高可用等等功能。
极大地减少了重复开发量,保障了业务系统快速开发和部署,而它本身也是一个 Web 服务器。
Web 应用服务器可以选择使用大厂的 WebLogic 和 WebSphere 这种重量级产品外。
也可以使用类似与 Tomcat、Jetty 这样的 Web Containner 再加上第三方的框架(Spring,Hibernate等)来构建自己的 Application Server;.NET Core 平台下可以选择 IIS,Apache,Nginx 与 ASP.NET Core 构建。
反向代理概念与基本原理
反向代理基本概念
反向代理是代理服务器的一种。它根据客户端的请求,从后端的服务器(如Web 服务器)上获取资源,然后再将这些资源返回给客户端。
与前向代理不同,前向代理作为一个媒介将互联网上获取的资源返回给相关联的客户端,而反向代理是在服务器端(如 Web 服务器)作为代理使用,而不是客户端。
客户端通过前向代理可以访问很多不同的资源,反向代理是很多客户端都通过它访问不同后端服务器上的资源,而不需要知道这些后端服务器的存在,以为所有资源都来自于这个反向代理服务器。
互联网中的请求发送给反向代理,反向代理把请求转发到内网中的服务器。
反向代理的主要作用为:
- 加密和SSL加速
- 负载均衡
- 缓存静态内容
- 压缩
- 减速上传
- 安全防火墙
- 外网发布
- 突破互联网封锁
- 解决跨域问题
反向代理基本工作原理
一个反向代理服务器的构成和处理过程如下图:
左边淡黄色功能模块对外网报文进行处理,右边灰色功能模块针对内网报文进行处理。
TCP 监听模块
监听 TCP 请求,这里的请求是指报文内容是某应用层协议(比如 HTTP,FTP,Email 等应用层协议)的请求。
至于这里是否会单独产生一个线程来开始处理,这个由服务器自己决定,目前最流行的是先入消息队列然后异步处理,这样能极大提高代理的吞吐量和稳定性。
匹配被代理服务器
代理服务器根据一个表(存放外网 URI 和内网服务器的对应关系,通常需人工进行设置),如果匹配到则继续处理,否则依据外网协议返回错误信息,比如 HTTP 协议这返回 404。
应用负载均衡策略
如果比较大型的互联网应用,为了整体系统稳定性,解决单点问题,需要根据自定义策略合理的转发报文给被代理服务器。简单的策略是哈希分发或者随机分发,一般可以由用户进行配置和选择。
预处理
这里依据协商好的外网应用协议进行解密,安全,会话,解压等处理。
新生成网络报文
这里依据协商好的内网应用协议生成网络报文,这里可能会进行加密,安全,会话,压缩等处理。
转发给被代理服务器
把新生成的网络报文发送给内网服务器(可能是否 Web 服务器,FTP 服务器,邮件服务器)。
接受网络报文
接受内网服务器反馈的网络报文。
预处理
这里依据协商好的外网应用协议进行加密,安全,会话,压缩等处理。
资源输出模块
这时生成满足外网应用协议要求的报文,并发送到外网连接的另一端(用户代理)。
常用的反向代理服务器
它们的名字您一定记得,分别是:Ngnix,IIS,Apache。
总结
从概念上讲:
- Web 服务器是提供 WWW 服务的程序。
- Web 容器是提供给开发者的框架。
- Web 应用程序服务器内容丰富得多,既可由各厂商通常遵循一定的工业标准并自定义扩展功能而成,也可以利用开源组件轻量级拼装打造。
- 反向代理服务器在企业级应用中表现突出,具有解决集中式安全,负载均衡等等优点。
如今这四个概念的边界越来模糊,看看这个表就知道了
关于 Kerstrel 是否是 Web 容器,有两种观点:
- 由于 Kerstrel 不提供编写应用的框架,所以它不是容器;ASP.NET Core 才是容器,因为它提供了开发应用的框架并提供 Web 应用(MVC,Web API)运行环境。
- Kerstrel 提供了运行环境。
非常欢迎大家提出自己的有力观点,帮助我们清晰化这个 ASP.NET Core 容器概念。