您的位置:首页 >资讯列表 > 正文
发布时间:2020-04-10 16:34
支持HTTP多路复用的代理服务器的设计与实现

  万维网的发展,使得上网冲浪非常流行,但是随着访问互联网用户的日益增多,Web服务器的负荷也日益增大,如何能够提升Web服务器的处理能力也就成为因特网内容提供商比较关心的问题。


  网站的运营者通常使用以下三种不同的策略去加速他们的网站或者增强处理能力:增加硬件,做负载均衡或者调整服务器运行参数。第一种方法并不是最好的,因为购置硬件的花费比较大,而后两种方法是在现有资源的基础上提高性能。本文所阐述的方法和后两种方法的思想相似,它通过一个与Web服务器建立若干个保持不断的连接的HTTP代理来节省与服务器建立连接的时间和降低服务器的负荷,提升服务器的处理能力。


  2 TCP协议和HTTP协议的局限性


  首先,让我们来看看TCP/IP协议和HTTP协议的不足。在建立一个TCP连接前,请求建立连接方和被请求方之间要进行三次握手,成功后才开始传输数据。这样,在传输数据前至少要花费一个RTT(往返时间)的时间来建立连接。TCP采用三次握手是为了建立一条可靠的连接,这个额外开销在最初使用TCP/IP的网络———ARPANET上并不明显,因为


  ARPANET主要用于传输大数据量的文件。


  但是在今天的Internet上,有大量的小数据包在传输,而且一个网页就可能包含很多广告条、文本和图片,它们会建立起很多个TCP连接,继而产生很多三次握手的额外开销,另外,大量TCP连接也加重了Web服务器的负荷,这体现在:


  (1)在服务器端,建立连接需要一定量的处理开销。这通常包括分配新的端口号、资源和相应的数据结构。关闭连接也需要一些处理时间,虽然可能没有建立连接那么多;


  (2)当网站需要某种形式的身份认证或者私人数据需要加密时,每个HTTP请求都要重新认证将是很花时间的;


  (3)虽然TCP连接可能只是存活几秒钟的时间,但是TCP本身要求关闭连接的主机还要保存每个连接的一些信息4分钟左右(虽然一些系统在具体实现上会使用更短的时间)。一台很忙


  收稿日期:2002-11-09;修订日期:2003-01-23


  的服务器的保存连接信息的结构表可能会被这种“TIME-WAIT”状态下的连接所占满,因此没有空间用于建立新的连接,或者花费更多的管理这个结构表的代价[1]。


  这都是由一个HTTP请求使用一个TCP连接所造成的。


  另外,当前的HTTP协议在实际应用中也有一个问题,那就是大多数的这些TCP连接都只是传输几千字节的数据。其中很多是嵌入在网页中的GIF和JPEG图片。然而,很不幸的是,TCP连接在开始的几个往返过程中是不会完全使用可用的网络带宽的。这是因为现代的TCP使用一个叫做“慢启动”的技术去避免网络拥塞。慢启动的方法需要TCP发送方逐步打开它的“拥塞窗口”,一次往返后就按收到的包数目增大一倍。直到有效窗口的大小至少是往返时间与网络带宽的乘积(带宽-延迟积)时,TCP才会达到最大的吞吐量。这意味着慢启动限制了TCP的吞吐量,它有利于避免拥塞但增长了短连接的完成时间。


  由于这些HTTP的短连接引起了性能问题,因此在新的HTTP1.1协议[2]中已经可以使用一个单一的,一直保持不断的TCP连接去处理多个HTTP的请求。这个连接对所有嵌在页面里的图片都保持在打开状态,并且会跨越多个HTTP的接收。这就避免了几乎所有的由每次连接所造成的额外开销,而且也应该有助于避免TCP慢启动所造成的延迟。但是如果Web服务器直接支持客户端的连接保持,那么它的负担也是沉重的,体现在:


  (1)一个TCP连接保持不断,它可能有数据在传送,是活跃的,也可能是空闲的。但对操作系统来说,它都要对这些空闲或活跃的连接进行轮询(select或者poll操作);


  (2)操作系统要对每个连接上的HTTP请求的处理进行调度,进程调度的开销很大;


  (3)用户是从保持连接这里得到了好处,但是服务器就超负荷工作,不但降低了响应时间,甚至会最终垮掉。


  因此,很多网站的Web服务器都运行在HTTP1.0或者关闭了保持连接功能的HTTP1.1模式下。


  3支持HTTP多路复用的代理服务器方案


  本文提出的方法,它既有HTTP1.1保持连接的优点,又能


  作者简介:黄锦昌(1977-),男,广东广州人,硕士研究生,主要研究方向:网络安全与保密;李仲麟(1946-),男,广东肇庆人,教授,主要研究方向:网络安全与保密.


  6月黄锦昌等:支持HTTP多路复用的代理服务器的设计与实现245


  降低Web服务器的负荷,它通过在Web服务器之前放置一个代理服务器,并且使它与服务器建立好若干个保持不断的TCP连接,从而节省了建立每个HTTP请求的TCP连接的3次握手的开销。当它接收到客户端的请求时,它选择一个建立好的连接把请求发送给Web服务器,也可能把若干个请求一起发送出去,它使得Web服务器能够专心于处理HTTP请求和返回网页,而不必再浪费时间去处理打开和关闭TCP连接。这种通过一个TCP连接发送多个HTTP请求和接收多个回复的方法,也可以称为HTTP多路复用。


  3.1代理服务器的工作过程


  与基本的代理服务器的工作过程类似:在某个端口上监听客户端请求,接收到请求后,就与客户端请求的服务器建立一个TCP连接,把客户端请求通过该连接转发给服务器。当服务器返回应答数据时,就把这些数据通过与客户端的连接传回客户端。


  3.2实现HTTP多路复用并保持连接


  HTTP协议本身是支持保持连接的,我们只需要在客户端的HTTP请求头中加上一个字段Connection:Keep-Alive,再把修改后的请求头发送给服务器,如果服务器支持保持连接功能的话,在响应头中就会有Connection:Keep-Alive字段,告诉代理服务器该连接将会被保持,直到发送的请求数到达某一个服务器设定的最大值或连接端主动关闭为止;如果服务器没有打开保持连接功能,则响应头中就会有Connection:Close字段,这时就不能使用HTTP多路复用,只能按每个请求一个连接的方式进行。


  我们将为每一台服务器预先建立几个(可配置)保持不断的TCP连接,通过在初始化的时候发送带有Connection:Keep-Alive的HEAD请求头来实现。随后,所有发送给这些服务器的HTTP请求都通过这些预先建立好的通道来发送,从而达到多路复用的目的。


  3.3管道并发多个HTTP请求


  HTTP协议支持在保持连接的通道上并发发送多个请求,即无需发送一个请求后,等待接收完服务器返回该请求的响应数据,再发送第二个请求。这样不但可以使TCP连接的使用更高效,而且能够让服务器满负荷运转,消除了不必要的等待时间,提高了整体的响应时间。


  但是,返回的多个响应头和响应体就要进行划分,把对应


  的部分返回给相应的客户端。通过HTTP响应头中的Content-Length字段就可以把返回的混合数据进行划分,因为返回的响应的顺序跟请求的发送顺序是一致的。


  4支持HTTP多路复用代理服务器的实现


  4.1主要数据结构


  (1)request数据结构,保存每个HTTP请求的有关信息。


  (2)channel数据结构,保存每个通道的有关信息,每个通道对应于一个与Web服务器的TCP连接。


  (3)请求队列waiting-queue,暂存来自客户端的HTTP请求,等待放入某台服务器的某个通道中。


  4.2主要功能模块


  (1)初始化模块:为每台服务器建立好若干个保持连接的通道。


  (2)主控模块:对接收客户端请求的套接口、各个通道的套接口用系统调用select()进行读写选择。


  a)接收客户端请求的套接口可读:accept一个客户连接,读取客户请求信息,建立一个request结构保存请求信息,并


  把它放到waiting-queue队列中。


  b)某个通道可写:如果此通道还允许继续发送请求,则从waiting-queue中取一个request放进该通道的队列(在channel结构中定义)中,并且把该request信息发送出去。


  c)某个通道可读:读入信息。根据响应头中的Content-


  Length字段区分各个响应,依次把这些响应的数据写回到相应的客户端,然后关闭客户端连接,从队列中删除该请求。


  (3)分发响应数据模块:负责划分从服务器返回的多个响应头和响应体。具体算法如下:


  while(通道还有数据可读)


  {


  读入数据到缓存区;if已经读完一个响应头的数据then


  取出其中的Content-Length字段的值赋给变量content-length;读入随后的content-length大小的数据,它们都属于该响应的响应体


  else


  继续读入数据,直到读完一个响应头为止


  }


  5测试结果


  我们对实现的HTTP多路复用代理服务器进行了测试,看是否能带来实际的效果。


  测试环境:客户端软件使用OpenSTA,它可以同时向指定的服务器发送几百个HTTP请求,然后记录每个请求的响应时间和响应结果,我们用它来模拟多个客户端同时向Web服务器发送HTTP请求的情况。Web服务器使用RedHat Linux


  7.2操作系统和Apache服务器。代理服务器也是使用RedHat


  Linux 7.2操作系统,在其上运行有我们的HTTP多路复用代理服务器程序(与Web服务器建立5个通道),客户端、代理服务器和Web服务器通过10兆以太网连接。


  测试方法:在客户端的OpenSTA软件中分别指定请求Web服务器上的一个20K,50K和200K字节的网页,指定同时发送400个对该网页的HTTP请求,然后分别记录在通过代理服务器访问和不通过代理服务器访问两种情况下完成这400个请求所需要的时间。


  以下是上述三种情况下的测试数据:


  图1访问20K字节的网页


  246计算机应用2003年


  图2访问50K字节的网页


  图3访问200K字节的网页


  结果分析:从上面三组测试数据可以看出:在使用代理服务器的情况下,完成所有请求的时间大大小于直接访问Web服务器的情况下所需要的时间。特别在访问较小的网页(20K和50K字节的网页)时,响应时间大大缩短,这是因为在不通过代理访问的情况下,Web服务器把大量时间都花费在建立连接和创建进程上,而实际用于传输数据的时间较少,所以直接处理400个20K大小的网页和400个50K大小的网页所需要的时间很接近,都是120秒左右;而在通过我们的代理的情况下,使用建立好的几个通道来发送请求和接收响应,Web服务器不需要花额外的时间建立连接和创建进程,因而完成所有请求的时间被大大缩短了。从图3中,我们也看出,在处理较大的页面时,虽然Web服务器用于传输数据的时间有所增加,但使用代理与不使用代理的效果还是很明显的(节省了50%的时间)。


  另外,我们还研究了与Web服务器保持连接的通道数的多少、并发请求同一网页等因素是否会对测试结果有影响,我们发现它们对测试结果的影响不大。我们分别设置代理服务器与Web服务器的保持连接的通道数为1个,5个和10个,三种情况下完成400个对同一50k网页的并发请求的时间都在27秒左右;而并发访问同一个网页与并发访问不同的网页(相同字节数)所需要的完成时间也很接近,相差不超过2秒。因此,我们在测试过程中可以忽略这些因素的影响。


  总之,在Web服务器处理大量并发的请求的情况下,我们的HTTP多路复用的代理服务器确实能有效地降低Web服务器的负荷,缩短平均响应时间。


  6结论


  使用保持不断的连接去处理多个HTTP请求的方法减少了以多进程方式处理HTTP请求的服务器的进程数目,节省了建立连接和创建进程的时间,实际的测试也表明它能够有效地缩短HTTP请求的平均响应时间。在实际应用中,我们还要进一步处理Web服务器主动关闭通道的情况(例如在HTTP1.0下访问CGI产生的网页),以及通道意外关闭时请求重发的问题。


上一篇 具备高速缓存的HTTP代理防火墙的设计与实现 下一篇 Linux内核态高效HTTP代理的设计与实现