第2章 应用层
应用层协议原理
编写网络应用程序的核心是,能够运行在不同端系统且通过网络通信。应用层抽象让我们只关心如何编写在端系统上运行的软件,而不需要关心如何操作网络核心设备。这一设计大大促进了网络应用程序的开发和部署。
网络应用程序体系结构
应用程序体系结构就是对端系统上如何组织程序的规则,现代网络常用的有两种:客户-服务器体系结构和对等(P2P)体系结构。
- 客户-服务器体系结构:服务器是一个总是打开的主机,它服务其它客户主机的请求。客户相互之间不直接进行通信。服务器具有固定的、周知的地址(IP地址)。在大型服务器应用中,一台单独的服务器可能无法处理所有客户的请求,所以会考虑使用数据中心来进行服务,这样的数据中心可能有上万台服务器用于相关应用服务。
- P2P 体系结构:这一服务甚至不需要要求中心专有服务器(或需要的资源很少),而应用程序在主机对之间直接通信,这些主机对被称为对等方。这一体系结构拥有很强的自扩展性,但同时由于高度的非集中式结构也面临安全性、性能和可靠性的挑战。
进程通信
在操作系统层面,进行通信的实际上是进程而不是程序。在不同端系统之间的进程通过交换报文来相互通信。
在一对进程之间的通信场景下,定义发起通信的进程为客户,而在会话开始前等待联系的进程为服务器。
进程通过套接字来向网络发送报文和从网络接收报文,套接字是一台主机内应用层与运输层之间的接口。运输层对应用程序的开发者几乎是不可见的,开发者仅能选择运输层协议和控制可能的几个参数。
为正确地定位要通信的进程地址,需要定义两种信息:主机的地址,目的主机中接收进程的标识符。在因特网中,主机由 IP 地址标识,进程由端口号标识。
可供应用程序使用的运输服务
因特网提供了多种运输层协议以供应用层开发人员选择,这些运输层协议提供的服务可以归为四类:可靠数据传输,吞吐量,定时,安全性。
- 可靠数据传输:分组在计算机网络中可能丢失,而某些协议提供了在不可靠运输上建立可靠传输的机制,即确保数据能正确且完整地从应用程序的一端传输到另一端。另一方面,也有一些应用程序能容忍少量的数据丢失(如多媒体应用),这样的应用就可以考虑使用不保证可靠数据传输的协议。
- 吞吐量:由于网络是共享的,网络吞吐量可能会随着时间发生波动,某些协议能保证应用程序吞吐量的下限,这对于带宽敏感性应用很有用。另一方面,弹性应用能够根据当前可用带宽调整使用的吞吐量。
- 定时:一些应用层协议能提供定时保证,即对数据交付的时间有严格的限制和保障,这有利于交互式应用程序。
- 安全性:为应用程序传输的数据提供安全保障,包括数据加密、数据完整性检查和端点鉴别。
因特网提供的运输服务
一般即指两类运输层协议:TCP和UDP。
TCP
TCP 是面向连接的服务:在正式开始数据交换前,TCP协议要求发送双方交换信息,进行握手,对使用的一些信息达成一致。然后才进行数据交换。当结束时,也需要拆除这一连接。
TCP 是全双工的:即连接双方的进程可以同时进行报文收发。
TCP 提供可靠的数据传送服务:即从协议上保证了数据从发送者发出后,能无差错且按适当顺序地交付给接收者。
TCP 拥有拥塞控制协议:有利于整个因特网,当中间的网络发生拥塞时,TCP拥塞控制机制会主动抑制发送进程;该机制还试图限制每一个TCP连接使用的资源,使网络带宽公平地在连接之间共享。
TCP 和 UDP均未提供加密机制,即发送进程发送的数据以明文形式在网络上发送。包含加密的 TCP 加强版被称为安全套接字层 SSL。 SSL 是对 TCP 的一种加强,其通常由应用层实现,SSL 的套接字 API 与 TCP 类似。
UDP
轻量级运输协议,仅提供最小服务。
没有握手过程,不可靠数据传输,没有拥塞控制协议。
应用层协议
定义运行在不同端系统上的应用程序如何传递保报文。包括:交换的报文类型(如响应报文、请求报文),报文的语法,字段的语义,发送时间以及响应规则。
一些应用层协议由 RFC 文档定义,属于公共域。也有一些公司开发使用了专属的协议。
Web 和 HTTP
HTTP 概况
HTTP 即超文本传输协议,是 Web 的核心。通常由一个客户程序和一个服务器程序组成。该协议定义的是 Web 客户端向 Web 服务器请求页面以及服务器回送页面的方式。
HTTP 使用 TCP 作为支撑运输协议。HTTP 通过套接字发送和接收报文。
HTTP 是无状态协议,即服务器并不存储关于客户的状态信息。
非持续连接和持续连接
在客户与服务端交互的过程中,根据每个请求/响应对是单独使用 TCP 发送还是经由相同的 TCP 连接通信,将两种方式分别称为非持续连接和持续连接。HTTP 能使用两种方式,默认情况下为持续连接。
在采用非持续连接的方法时,需要为每一个请求的对象建立并维护连接结构,且会由于多次握手造成时延。而采用持续连接时,多个对象可以通过一个单独的 TCP 连接进行传送,甚至可以将同一服务器上多个 Web 页面的请求通过单独 TCP 连接发送给用户。这些请求可以采用流水线的方式,不必等待回复就请求下一个对象。
HTTP 报文格式
HTTP 报文包括两种:请求报文和响应报文。
HTTP 报文由 ASCII 文本书写,每一行末尾由回车和换行符结束。
HTTP 请求报文第一行为请求行,后继行为首部行,在一个空的回车换行符后为实体体。请求行包括方法、URL和 HTTP 版本字段。实体体通常用于 PUT 方法提交表单,不过也有直接在 URL 中包括输入数据的方法来进行数据提交,此时使用的是 GET 方法。
HTTP 响应报文类似,由状态行、首部行和实体体组成。状态行包括协议版本、状态码和状态信息字段。实体体比较重要,一般包含响应的具体数据。
Cookie
HTTP 服务器本身无状态,为了识别用户,HTTP 使用 cookie 来允许站点对用户进行跟踪。
要使用 cookie,首先需要在 HTTP 报文首部行包含一个 cookie 首部行。当首次访问某个服务器时,服务器会为其分配以恶搞唯一识别码,并在数据库中记录,然后通过在返回报文中设置 set cookie 字段对客户浏览器响应,客户浏览器将其保存在本地,之后每次发出请求的时候都会在报文中包括该 cookie 在首部行中。
可以认为,cookie 在无状态的 HTTP 上建立了一个用户会话层。
Web 缓存
Web 缓存能大大减少客户请求的响应时间,并减少通信量。
通过内容分发网络 CDN,Web 缓存器还能发挥更大的作用。
条件 GET
用于解决缓存陈旧过时的问题。当在请求报文使用 GET 方法,且包含 If-Modified-Since 首部行时,Web 缓存器会向服务器询问是否有过修改,如果有则服务器返回更新后的文件,否则返回 304 Not Modified。
因特网中的电子邮件
因特网电子邮件:用户代理,邮件服务器,简单邮件传输协议 SMTP。
典型的邮件发送过程:从发送方的用户代理开始,到发送方的邮件服务器,再到接收方的邮件服务器,最后分发到接收方的邮箱中。
邮件服务器中一般还会包含报文队列,处理比如对方服务器故障的情况。如果发送失败,会在若干天内反复尝试直到成功,否则若几天后仍然不能成功,则会通知发送方发送失败。
SMTP
使用 TCP 可靠传输。
SMTP 一般不使用中间邮件服务器发送邮件,即不论是否发送成功,邮件都不会在某个中间的邮件服务器存留。
SMTP 通过类似对话的方式相互交互。通过 MAIL FROM 发起一个邮件传输,通过一个只包含句点的行结束邮件顺序,另外还有若干控制语句用于交流控制信息。
SMTP 使用持续连接,当发送方有多个邮件发往同一个邮件服务器时,可以用同一个 TCP 连接发送所有的报文,每一个报文用一个新的 MAIL FROM 发起。
DNS:因特网的目录服务
DNS 提供的服务
域名系统的主要任务:提供主机名到 IP 地址转换的目录服务。
包含两个部分:由分层的 DNS 服务器实现的分布式数据库,用于主机查询分布式数据库的应用层协议。
DNS 协议运行在 UDP 上。
DNS 还提供一些额外服务:主机别名服务,邮件服务器别名,负载分配。
DNS 工作机理概述
DNS 从用户使用的角度看,像是发送查询请求后返回结果的黑盒子,但实际上由于性能和安全等方面的考虑,DNS 服务采用的分布式的设计,这使得其中的很多细节变得非常复杂。DNS 是在因特网上实现分布式数据库的精彩范例。
DNS 使用了分布式、层次化的数据库,为了方便地处理扩展性地问题。没有一台 DNS 服务器拥有因特网上所有主机的映射。DNS 服务器根据其层次可以大致分为三类:根 DNS 服务器,顶级域 DNS 服务器和权威 DNS 服务器。另外还有本地 DNS 服务器,通常在地理位置上临近主机,比如就在同一个局域网中,或者仅相隔几个路由器。
DNS 查询有递归查询和迭代查询两种,其实质上是一个不断询问掌握更加精细信息的 DNS 服务器,最终得到准确回复的过程。由此,一个由客户发出的完整的 DNS 查询可能设计数次的 DNS 报文发送和接收。
DNS 缓存能显著减少时延,并减少向网络上传输的 DNS 报文数量。在请求链中,当某 DNS 收到一个回复时,会将回复中的映射缓存到本地存储器中,以便于之后若遇到相同的查询可以直接使用缓存。因为实际网络结构可能发生变化,所以缓存并不是永久的,由 DNS 服务器管理并在一定时间后丢弃(通常为两天)。
DNS 记录和报文
所有 DNS 服务器存储了资源记录 RR,该数据提供了主机名到 IP 地址的映射,通常是包含 (Name, Value, Type, TTL)这些字段的 4 元组。
TTL 是生存时间,决定资源记录被从缓存中删除的时间。
Type 标记该记录的类型,如为 A 则标识 Name 为主机名 Value 为 IP 地址,为 NS 则 Name 为域 Value 是知道如何获得该域中主机 IP 地址的权威 DNS 服务器的主机名(辅助沿着查询链对 DNS 的查询),为 CNAME 则 Value 是别名为 Name 的主机对应的规范主机名,为 MX 则 Value 是别名为 Name 的邮件服务器的主机名。
P2P 文件分发
在 P2P 中,对等方彼此直接通信,通常不需要或者最小依赖总是打开的基础设施服务器。
P2P 拥有很强的自扩展性。对等方不仅能接收比特数据,而且能重新分发数据使数据更快地扩散到群体中。
BitTorrent 使 P2P 协议中比较广泛使用的一种。这一协议将参与一个特定文件分发的所有对等方的集合称为洪流,将文件拆分成文件块用于传输和记录,每个洪流还有一个追踪器用于注册和跟踪拥有该洪流中的块的对等方。在任意时刻,每个对等方拥有该文件的若干块的子集,当需要下载的时候,某一对等方首先从追踪器获得一个洪流中的对等方的子集,然后询问这些对等方格子拥有的数据块,再采用一种称为最稀缺优先的算法先请求出现最少的块(这样能让最稀缺的块迅速重新分发,是的每个块在洪流中的副本数量尽可能地均衡)。同时,对等方根据对换算法选择向哪个邻居发起请求,具体来说,它选择能以最高速率提供数据的邻居请求数据,同时自身也要随机选择一个发送数据(这一算法能使得对等方以趋向于找到彼此协调的速率上载)。
视频流和内容分发网
因特网视频
视频通常的特点是数据量大,要求高比特率的传输。
通常,服务商会预置好视频的不同比特率的版本,由客户根据网络连接带宽决定连接的流式播放码率,且通常可以根据带宽变化自适应。
内容分发网
CDN 管理分布在多个地理位置上的服务器,并在其中存储数据资料的副本,试图将用户的请求定位到能提供最佳体验的 CDN 位置。
有两种 CDN 服务器安置的方法。其一是深入就近,部署大量 CDN 服务器以尽量贴近端用户,但这样高度分布式的设计对维护和管理集群提出了挑战;其二是在少量但是关键的位置建立 CDN 集群,然后邀请 ISP 接入连接,通常这些 CDN 会被放置在因特网交换点 IXP,但这样会导致较高的延迟和较低的吞吐量。
CDN 通常采用类似缓存的拉策略,即若用户请求资源且该资源不在 CDN 中缓存时,CDN 会向数据中心请求并在本地保存一个副本。同样也和缓存类似,有生存时间的设计。
大多数 CDN 使用 DNS 来截获和重定向请求,并使用一些策略将客户动态地定向到 CDN 的某个服务器集群或数据中心。