研发网络应用程序的核心是写出能够运行在不同的端系统和通过网络彼此通信的程序。
重要的是,你不需要写在网络核心设备如路由器或链路层交换机上运行的软件。网**络核心设备并不在应用层上起作用,而仅较低层起作用,特别是在网络层及下面层次起作用。**这种基本设计,即将应用软件限制在端系统(如图所示)的方法,促进了大量的网络应用程序的迅速研发和部署。
应用程序的体系结构明显不同于网络的体系结构。从应用程序研发者的角度看,网络体系结构是固定的,并为应用程序提供了特定的服务集合。在另一方面,应用程序体系结构 (application architecture) 由应用程序研发者设计, 规定了如何在各种端系统上组织该应用程序。
现代网络应用程序中所使用的两种主流体系结构之一 客户-服务器体系结构或对等(P2P)体系结构。
客户-服务器体系结构
P2P体系结构
**对位于数据中心的专用服务器有最小的 (或者没有)依赖。**应用程序在间断连接的主机对之间使用直接通信,这些主机对
被称为对等方。这些对等方并不为服务提供商所有,因为这种对等方通信不必通过专门的服务器,该体系结构被称为对等方到对等方的。
目前流行的、流量密集型应用都是P2P体系结构的。这些应用包括文件共享(例如BitTorrent) x对等方协助下载加速器(例如迅
雷)、因特网电话和视频会议(例如Skype)。
P2P体系结构的最引人入胜的特性之一是它们的自扩展性 (self-scalability)。每个对等方都由于请求文件产生工作负载,但每个对等方通过向其他对等方分发文件也为系统增加服务能力。
P2P体系结构也是有成本效率的, 因为它们通常不需要庞大的服务器基础设施和服务器带宽。
面临的问题:
操作系统中,进行通信的实际上是进程(process)而不是程序。
当多个进程运行在相同的端系统上时,它们使用进程间通信机制相互通信。进程间通信的规则由端系统上的操作系统确定。
在两个不同端系统上的进程,通过跨越计算机网络交换报文(message)而相互通信。 发送进程生成并向网络中发送报文;接收进程接收这些报文并可能通过回送报文进行响应。
客户和服务器进程
进程与计算机网络之间的接口
进程寻址
一个运输层协议能够为调用它的应用程序提供什么样的服务呢?我们大体能够从四个方面对应用程序服务要求进行分类:可靠数据传输、吞吐量、定时和安全性。
因特网(更一般的是TCP/IP网络)为应用程序提供两个运输层协议,即UDP和TCP。当你(作为一个软件开发者)为因特网创建一个新的
应用时,首先要做出的决定是,选择UDP还是选择TCP。每个协议为调用它们的应用程序提供了不同的服务集合。
TCP服务
UDP服务
因特网运输协议所不提供的服务
应用层协议(application-layer protocol )定义了运行在不同端系统上的应用程序进程如何相互传递报文。
20世纪90年代初期,一个主要的新型应用即万维网(WorldWideWeb)登上了舞台也许对大多数用户来说,最具有吸引力的就是Web的按需操作。当用户需要时,就 能得到所想要的内容。这不同于无线电广播和电视,它们迫使用户只能收听、收看内容提供者提供的节目。
Web的应用层协议是超文本传输协议(HyperText Transfer Protocol, HTTP),它是Web的核心。HTTP由两个程序实现:一个客户程序和一个服务器程序。客户程序和服务器程序运行在不同的端系统中,通过交换HTTP报文进行会话。HTTP定义了这些报文的结构以及客户和服务器进行报文交换的方式。
Web页面(Webpage)也叫文档是由对象组成的。一个对象(object)只是一个文件,它们通过一个URL地址进行寻址。客户和服务器交互的核心思想是客户通过HTTP请求对服务器发出对Web页面的请求报文,服务器收到该报文后将返回包含该对象的HTTP响应报文。URL地址由两部分组成:存放对象的服务器主机名和对象的路径名。
HTTP定义了Web客户向Web服务器请求Web页面的方式,以及服务器向客户传送Web页面的方式。
HTTP使用TCP作为它的支撑运输协议(而不是在UDP上运行)。HTTP客户首先发起一个与服务器的TCP连接,需要注意的是,服务器根据请求作出响应,但是不存储任何关于该客户的状态信息。也正因为这样,HTTP被称为无状态协议。同时,Web使用了客户端-服务器的应用体系结构。其中web服务器总是开着的。
客户发出一系列请求并且服务器对每个请求进行响应。依据应用程序以及该应用程序的使用方式,这一系列请求可以以规则的间隔周期性地或者间断性地一个接一个发出。当这种客 户-服务器的交互是经TCP进行的,应用程序的研制者就需要做一个重要决定,即每个请求/响应对是经一个单独的TCP连接发送,还是所有的请求及其响应经相同的TCP连接发送呢?采用前一种方法,该应用程序被称为使用非持续连接(non-persistent connection);采用后一种方法,该应用程序被称为使用持续连接(persistent connection)。
采用非持续连接的HTTP
采用持续连接的HTTP
HTTP请求报文
HTTP请求报文的第一行叫作请求行(request line),其后继的行叫作首部行(header line)。
请求行有3个字段方法字段、URL字段和HTTP版本字段。
方法字段可以取几种:GET、POST、HEAD、PUT和DELETE。
首部行:
通用格式:
HTTP响应报文
一般报文:
它有三个部分 一个初始状态行(status line) , 6个首部行(headerline),然后是实体体(entity body)。实体体部分是报文的主要部分,即它包含了所请求的对象本身(表示为data data data data data -)。
状态行有3个字段协议版本字段、状态码和相应状态信息。
这里的Date是从文件系统中检索到该对象,插入到响应报文,并发送该响应报文的时间。
通用格式:
状态码相关信息:
前面提到,HTTP是无状态协议,但是Web站点为了识别用户身份或者限制用户访问的时间或者将用户访问的内容同用户身份相关联,Web站点可以使用Cookie技术;
cookie技术有4个组件:
当客户第一次访问一个Web服务器,请求报文到达服务器时,该Web站点将产生一个唯一识别码,并以此作为索引在它的后端数据库中产生一个表项。接下来Web服务器用一个包含Set-cookie:首部的HTTP响应报文对客户的浏览器进行响应,其中Set-cookie:首部含有该识别码。如:
当客户的浏览器收到了该HTTP响应报文时,它会看到该Set-cookie:首部。该浏览器在它管理的特定cookie文件中添加一行,该行包含服务器的主机名和在Set-cookie:首部中的识别码。当客户继续浏览网站时,每请求一个Web页面,其浏览器就会查询该cookie文件并抽取她对这个网站的识别码,并放到HTTP请求报文中包括识别码的cookie首部行中。
cookie可以用于标识一个用户。用户首次访问一个站点时,可能需要提供一个用户标识(可能是名字)。在后继会话中,浏览器向服务器传递一个cookie首部,从而向该服务器标识了用户。因此cookie可以在无状态的HTTP之上建立一个用户会话层。
Web缓存器(Web cache)也叫代理服务器( proxy server),它是能够代表初始Web服务器来满足HTTP请求的网络实体。Web缓存器有自己的磁盘存储空间,并在存储空间中保存最近请求过的对象的副本。
可以配置用户的浏览器,使得用户的所有HTTP请求首先指向Web缓存器。
当代理服务器收到一个HTTP请求后,它将检查本地是否缓存过该对象,如果缓存过该对象,将检查是否过期,如果没有过期,则直接将该对象返回给浏览器;如果本地不存在或者存在已过期,则代理服务器将根据请求报文里的Host首部行以及请求行里的URL字段向初始服务器发出请求,然后将响应对象返回给浏览器并缓存在本地。
Web缓存器既是服务器又是客户。
通常,代理服务器与客户端的通信速度要快于初始服务器与客户端的连接速度。Web代理服务器可以大起大减少对客户请求的响应时间。而且,缓存器能从整体上大大降低因特网上的web流量,从而有助于提高所有应用程序的性能。
通过使用内容分发网络(Content Distribution Network),Web缓存器正在因特网中发挥越来越重要的作用。
保存在服务器中的对象自该副本缓存在客户上以后可能已经被修改了。HTTP协议有一种机制,允许缓存器证实它的对象是最新的。这种机制就是条件GET (conditional GET)方法。
缓存器在将对象转发到请求的浏览器的同时,也在本地缓存了该对象。重要的是, 缓存器在存储该对象时也存储了最后修改日期。在过了一段时间后,如果有用户再来访问该对象,由于对象可能更新了,该缓存器通过发送一个条件GET执行最新检查。
值得注意的是If Modified-Since:首部行的值正好等于缓存前服务器发送的响应报文中的Last-Modified:首部行的值。该条件GET报文告诉服务器,仅当自指定日期之后该对象被修改过,才发送该对象。否则服务器将返回一个包含空实体体的报文。
状态行中为304 Not Modified,它告诉缓存器可以使用该对象,能向请求的浏览器转发它(该代理缓存器)缓存的该对象副本。
电子邮件是一种异步通信媒介,即当人们方便时就可以收发邮件,不必与他人的计划进行协调。
有3个主要组成部分用户代理( user agent)、邮件服务器(mail server)和简单邮件传输协议(Simple Mail Transfer Protocol, SMTP)。
邮件服务器形成了电子邮件体系结构的核心。每个接收方在其中的某个邮件服务器上有一个邮箱(mailbox)。
过程:从发送方的用户代理开始,传输到发送方的邮件服务器,再传输到接收方的邮件服务器,然后在这里被分发到接收方的邮箱中。当Bob要在他的邮箱中读取该报文时,包含他邮箱的邮件服务器(使用用户名和口令)来鉴别Bob。Alice的邮箱也必须能处理Bob的邮件服务器的故障。如果Alice的服务器不能将邮件交付给Bob的服务器,Alice的邮件服务器在一个报文队列(message queue )中保持该报文并在以后尝试再次发送。
报文由两部分组成:一个包含环境信息的首部和一个包含邮件内容的报文体。首部和报文体之间使用空行分开;首部行的格式为关键字:及其值;每个首部必须包含一个From和To首部行。首部也可以包含其它信息,比如Subject等。这与2.4.1中接触的SMTP命令不同,那节中的命令是握手协议的一部分;本节中研究的内容是邮件报文自身的一部分。
因特网上的主机和人类一样,可以使用多种方式进行标识。主机的一种标识方法是用 它的主机名 (hostname ),如 www. facebook, com、www. google, com等,这些名字便于记忆也乐于被人们接受。然而,主机名几乎没有提供 (即使有也很少)关于主机在因特网中位置的信息。主机也可以使用所谓IP地址(IP address)进行标识。 IP地址具有层次结构,是因为当我们从左至右扫描它时,我们会得到越来越具体的关于主机位于因特网何处的信息(即在众多网络的哪个网络里)。
识别主机有两种方式,通过主机名或者IP地址。我们需要一种能进行主机名到IP地址转换的目录服务。这就是域名系统
(Domain Name System, DNS)的主要任务。
DNS是:
DNS通常是由其他应用层协议所使用的,包括HTTP、SMTP和FTP,将用户提供的主机名解析为IP地址。
除了进行主机名到IP地址的转换外,DNS还提供了一些重要的服务:
DNS的一种简单设计是在因特网上只使用一个DNS服务器,该服务器包含所有的映 射。在这种集中式设计中,客户直接将所有查询直接发往单一的DNS服务器,同时该DNS服务器直接对所有的查询客户做出响应。这种集中式设计的问题包括:
分布式、层次数据库
为了处理扩展性问题,DNS使用了大量的DNS服务器,它们以层次方式组织,并且分布在全世界范围内。没有一台DNS服务器拥有因特网上所有主机的映射。这些映射分布在所有的DNS服务器上。
有3种类型的DNS服务器根DNS服务器、顶级域(Top Level Domain, TLD) DNS服务器和权威DNS服务器。
根DNS服务器:有400多个根名字服务器遍及全世界。根名字服务器提供TLD服务器的IP地址。
顶级域(DNS)服务器:对于每个顶级域(如com、org、net、edu和gov)和所有家的顶级域(如uk、fr、ca和jp),都有TLD服务器(或服务器集群)。
权威DNS服务器:在因特网上具有公共可访问主机(如Web服务器和邮件服务器)的每个组织机构必须提供公共可访问的DNS记录,这些记录将这些主机的名字映射为IP地址。
本地DNS服务器:本地DNS服务器并不属于该服务器的层次结构。每 个ISP (如一个居民区的1SP或一个机构的ISP)都有一台本地DNS服务器(也叫默认名字服务器)主机的本地DNS服务器通常“邻近”本主机。当主机发岀DNS请求时,该请求被发往本地DNS服务器,它起着代理的作用,并将该请求转发 到DNS服务器层次结构中。
DNS查询有两种,一种是递归查询一种是迭代查询;实践中,查询通常满足这样的模式:从请求主机到本地DNS服务器的查询是递归的,其余查询是迭代的。所谓迭代就是,如果请求的接收者不知道所请求的内容,那么接收者将扮演请求者,发出有关请求,直到获得所需要的内容,然后将内容返回给最初的请求者。也就是说,在递归查询中,一定要给请求者想要的答案;迭代查询则是指,如果接收者没有请求者所需要的准确内容,接收者将告诉请求者,如何去获得,但是自己并不去发出请求。
DNS缓存
为了改善时延性能并减少在因特网上到处传输的DNS报文数量,DNS广泛使用了缓存技术。在一个请求链中,当某DNS
服务器接收一个DNS回答(例如,包含某 主机名到IP地址的映射)时,它能将映射缓存在本地存储器中。
由于主机和主机名与IP地址间的映射并不是永久的,DNS服务器在一段时间后(通常设置为两天)将丢弃缓存的信息。事实上,因为缓存,除了少数DNS查询以 外,根服务器被绕过了。
共同实现DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record,RR), RR提供了主机名到IP地址的映射。每个DNS回答报文包含了一条或多条资源记录。
资源记录是一个包含了下列字段的4元组:
DNS报文
在DNS数据库中插入记录
采用了客户-服务器体系结构,极大地依赖于总是打开的基础设施服务器。使用P2P体系结构,对总是打开的基础设施服务器有最小的(或者没有)依赖。成对间歇连接 的主机(称为对等方)彼此直接通信。这些对等方并不为服务提供商所拥有,而是受用户控制的桌面计算机和膝上计算机。
有两种典型因特网应用十分适合P2P体系结构,一种是文件分发(BitTorrent),另一种是大型对等方社区中的数据库;我们将探讨分布式散列表的概念。P2P体系结构有着良好的自扩展性。这种扩展性的直接成因是:对等方除了比特的消费者之外还是他们的重新分发者。
BitTorrent
BitToiTent是一种用于文件分发的流行P2P协议。参与一个特定文件分发的所有对等方的集合被称为一个洪流(torrent)。在一个洪流中的对等方彼此下载等长度的文件块(chunk),典型的块长度为256KB。当一个对等方首 次加入一个洪流时,它没有块。随着时间的流逝,它累积了越来越多的块。当它下载块 时,也为其他对等方上载了多个块。一旦某对等方获得了整个文件,它也许(自私地)离开洪流,或(大公无私地)留在该洪流中并继续向其他对等方上载块。同时,任何对等方可能在任何时候仅具有块的子集就离开该洪流,并在以后重新加入该洪流中。
每个洪流具有一个基础设施节点,称为追踪器(tracker)。当一个对等方加入某洪流时,它向追踪器注册自己,并周期性地通知追踪器它仍在该洪流中。以这种方 式,追踪器跟踪参与在洪流中的对等方。一个给定的洪流可能在任何时刻具有数以百计或数以千计的对等方。
如图2 23所示,当一个新的对等方Alice加入该洪流时,追踪器随机地从参与对等方的集合中选择对等方的一个子集,并将这等方的IP地址发送给Aliceo Alice持有对等方的这张列表,试图与该列表上的所有对等方创建并行的TCP连接。我们称所有这样与Alice成功地创建一个TCP连接的对等方为“邻近对等方”。随着时间的流逝,这些对等方中的某些可能离开,其他对等方可能试图与Alice创建TCP连接。因此一个对等方的邻近对等方将随时间而波动。
Alice使用一种称为最稀缺优先(rarest Erst)的技术。这种技术的思路是,针对她没有的块在她的邻居中决定最稀缺的块(最稀缺的块就是那些在她的邻居中副本数量最少的块),并首先请求那些最稀缺的块。这样,最稀缺块得到更为迅速的重新分发,其目标是(大致地)均衡每个块在洪流中的副本数量。
BitTorrent使用一种算法,Alice优先从像她传时速度最快的邻居(4个,每10s修改一次)那里获取文件块。每过30s,Alice也要随机选择另外一个对等方Bob,向他发送块。若Alice是Bob最快的前四快,Bob也是Alice的前4快,则Bob和Alice互相发送据。 每过30s换一个新的对象,互相交换数据(一报还一报),为了使对等方能够找到彼此协调的速率上传。
在HTTP流中,视频只是存储在HTTP服务器中作为一个普通的文件,每个文件有一 个特定的URL。当用户要看该视频时,客户与服务器创建一个TCP连接并发送对该URL的HTTP GET请求。服务器则以底层网络协议和流量条件允许的尽可能快的速率,在一个HTTP响应报文中发送该视频文件。
流式视频应用程序周期性地从客户应用程序缓存中抓取帧,对这些帧解压缩并且在用户屏幕上展现。流式视频应用接收到视频就进行播放,同时缓存该视频后面部分的帧。
它具有严重缺陷,即所有客户接收到相同编码的视频,尽管对不同的客户或者对于相同客户的不同时间而言,客户可用的带宽大小有很大不同。 这导致了一种新型基于HTTP的流的研发,它常常被称为经HTTP的动态适应性流(Dynamic AdaptiveStreaming over HTTP, DASH) 。o在DASH中,视频编码为几个不同的版本,其中每个版本具有不同的比特率,对应于不同的质量水平。’客户动态地请求来自不同版本且长度为几秒的视频段数据块。
DASH允许客户使用不同的以太网接入速率流式播放具有不同编码速率的视频。
使用DASH后,每个视频版本存储在HTTP服务器中,每个版本都有一个不同的URL。HTTP服务器也有一个告示文件(manifest file),为每个版本提供了一个URL及其比特率。客户首先请求该告示文件并且得知各种各样的版本。然后客户通过在HTTP GET请求报文中对每块指定一个URL和一个字节范围,一次选择一块。客户也测量接收带宽并运行一个速率决定算法来选择下次请求的块。DASH允许
客户自由地在不同的质量等级之间切换。