削减网络流量当然是十分重要的优化行动之一,不过这种手法也只是是完成高功能网络数据传输范畴的一个方面。其他TCP选项也或许明显供给传输功能一起在某些条件下削减服务器的呼应时间推延。下面就让咱们来了解一些此类选项。
TCP_DEFER_ACCEPT
咱们首要考虑的第1个选项是TCP_DEFER_ACCEPT(这是Linux体系上的叫法,其他一些操作体系上也有相同的选项但运用不同的姓名)。为了了解TCP_DEFER_ACCEPT选项的详细思维,咱们有必要大致论述一下典型的HTTP客户/服务器交互进程。请回想下TCP是怎么与传输数据的方针树立衔接的。在网络上,在别离的单元之间传输的信息称为IP包(或IP 数据报)。一个包总有一个带着服务信息的包头,包头用于内部协议的处理,并且它也能够带着数据负载。服务信息的典型比如便是一套所谓的标志,它把包符号代表TCP/IP协议栈内的特别意义,例如收到包的成功承认等等。一般,在经过“符号”的包里带着负载是完全或许的,但有时,内部逻辑迫使TCP/IP协议栈宣布只要包头的IP包。这些包常常会引发厌烦的网络推延并且还增加了体系的负载,成果导致网络功能在全体上下降。
现在服务器创立了一个套接字一起等候衔接。TCP/IP式的衔接进程便是所谓“3次握手”。首要,客户程序发送一个设置SYN标志并且不带数据负载的TCP包(一个SYN包)。服务器则以宣布带SYN/ACK标志的数据包(一个SYN/ACK包)作为方才收到包的承认呼应。客户随后发送一个ACK包承认收到了第2个包然后完毕衔接进程。在收到客户发来的这个ACK包之后,服务器会唤醒一个接纳进程等候数据抵达。当3次握手完成后,客户程序即开端把“有用的”的数据发送给服务器。一般,一个HTTP恳求的量是很小的并且完全能够装到一个包里。可是,在以上的情况下,至少有4个包将用来进行双向传输,这样就增加了可观的推延时间。此外,你还得注意到,在“有用的”数据被发送之前,接纳方现已开端在等候信息了。
为了减轻这些问题所带来的影响,Linux(以及其他的一些操作体系)在其TCP完成中包含了TCP_DEFER_ACCEPT选项。它们设置在侦听套接字的服务器方,该选项指令内核不等候最终的ACK包并且在第1个真实有数据的包抵达才初始化侦听进程。在发送SYN/ACK包之后,服务器就会等候客户程序发送含数据的IP包。现在,只需求在网络上传送3个包了,并且还明显下降了衔接树立的推延,对HTTP通讯而言特别如此。这一选项在好些操作体系上都有相应的对等物。例如,在FreeBSD上,相同的行为能够用以下代码完成:
/* 为清楚起见,此处省略无关代码 */
struct accept_filter_arg af = { dataready, };
setsockopt(s, SOL_SOCKET, SO_ACCEPTFILTER, af, sizeof(af));
这个特征在FreeBSD上叫做“承受过滤器”,并且具有多种用法。不过,在简直一切的情况下其效果与TCP_DEFER_ACCEPT是相同的:服务器不等候最终的ACK包而只是等候带着数据负载的包。要了解该选项及其对高功能Web服务器的重要意义的更多信息请参阅Apache文档上的有关内容。
就HTTP客户/服务器交互而言,有或许需求改动客户程序的行为。客户程序为什么要发送这种“无用的”ACK包呢?这是由于,TCP协议栈无法知道ACK包的状况。假如选用FTP而非HTTP,那么客户程序直到接纳了FTP服务器提示的数据包之后才发送数据。在这种情况下,推延的ACK将导致客户/服务器交互呈现推延。为了承认ACK是否必要,客户程序有必要知道应用程序协议及其当时状况。这样,修正客户行为就成为必要了。
对Linux客户程序来说,咱们还能够选用另一个选项,它也被叫做TCP_DEFER_ACCEPT。咱们知道,套接字分红两种类型,侦听套接字和衔接套接字,所以它们也各自具有相应的TCP选项调集。因而,常常一起选用的这两类选项却具有相同的姓名也是完全或许的。在衔接套接字上设置该选项今后,客户在收到一个
SYN/ACK包之后就不再发送ACK包,而是等候用户程序的下一个发送数据恳求;因而,服务器发送的包也就相应削减了。
TCP_QUICKACK
阻挠因发送无用包而引发推延的另一个办法是运用TCP_QUICKACK选项。这一选项与 CP_DEFER_ACCEPT不同,它不但能用作办理衔接树立进程并且在正常数据传输进程期间也能够运用。别的,它能在客户/服务器衔接的任何一方设置。假如知道数据不久行将发送,那么推延ACK包的发送就会派上用场,并且最好在那个带着数据的数据包上设置ACK 标志以便把网络负载减到最小。当发送方必定数据将被当即发送(多个包)时,TCP_QUICKACK选项能够设置为0。对处于“衔接”状况下的套接字该选项的缺省值是1,初次运用今后内核将把该选项当即复位为1(这是个一次性的选项)。
在某些景象下,宣布ACK包则十分有用。ACK包将承认数据块的接纳,并且,当下一块被处理时不至于引进推延。这种数据传输形式对交互进程是恰当典型的,由于此类情况下用户的输入时间无法猜测。在Linux体系上这便是缺省的套接字行为。在上述情况下,客户程序在向服务器发送HTTP恳求,而预先就知
道恳求包很短所以在衔接树立之后就应该当即发送,这可谓HTTP的典型作业方式。已然没有必要发送一个朴实的ACK包,所以设置TCP_QUICKACK为0以进步功能是完全或许的。在服务器方,这两种选项都只能在侦听套接字上设置一次。一切的套接字,也便是被承受呼叫直接创立的套接字则会承继原有套接字的一切选项。
经过TCP_CORK、TCP_DEFER_ACCEPT和TCP_QUICKACK选项的组合,参加每一HTTP交互的数据包数量将被下降到最小的可承受水平(依据TCP协议的要求和安全方面的考虑)。成果不仅是取得更快的数据传输和恳求处理速度并且还使客户/服务器双向推延完成了最小化。
小结
网络程序的功能优化显然是一项杂乱的使命。优化技能包含:尽或许运用零复制、用TCP_CORK及其等价选项拼装恰当的数据包、把传输数据包的数量最小化以及推延优化等。为了提高网络、体系的功能和可伸缩性,有必要在程序代码中联合一致地选用以上各种可用办法。当然,清楚了解TCP/IP协议栈和操作体系的内部作业原理也是必要的
发布者:博子