最近碰到一个client端连接异常问题,然后定位分析并查阅各种资料文章,对TCP连接队列有个深入的理解
查资料过程中发现没有文章把这两个队列以及怎么观察他们的指标说清楚,希望通过这篇文章能把他们说清楚一点
最近碰到一个client端连接异常问题,然后定位分析并查阅各种资料文章,对TCP连接队列有个深入的理解
查资料过程中发现没有文章把这两个队列以及怎么观察他们的指标说清楚,希望通过这篇文章能把他们说清楚一点
TCP默认做了一些带宽利用率、性能方面的优化,实际应用中这些优化可能会导致莫名其妙的问题
Nagle算法用于减少网络中小的packet的数量,从而降低网络拥塞程度。
举个例子,telnet连接后,用户在控制台每次按键都会发送一个packet,这个packet通常包含41个字节,然而只有一个字节是payload,其余40个字节都是header,如果每次按键都发送一个packet,那会造成巨大的开销。
为减少这种开销,Nagle算法指出,当TCP发送一个小于MSS的segment时,它必须等到接收到对方的ACK后,才能继续继续发送另一个小的segment。那么在等待过程中(一个RTT时间),TCP就能尽量多地将要发送的数据收集在一起,从而减少要发送的segment数量。
默认情况下,TCP开启Nagle算法,Nagle会引入负面影响,它会增加TCP发送数据的延迟。在一些要求低延迟的应用程序中(比如即时通讯),需要禁用Nagle算法,可以通过设置TCP_NODELAY
标识禁用Nagle算法
|
|
TCP的Delay ACK与Nagle算法有异曲同工之妙,当TCP接收到数据时,并不会立即发送ACK给对方,相反,它会做如下选择:
通过设置TCP_QUICKACK
标识调整为快速确认模式
TCP采用两种方式发送ACK: 快速确认和延迟确认
在快速确认模式下,本端接收到数据包后,会立即发送ACK给对端
在延迟确认模式下,本端接收到数据后,不会立即发送ACK给对端,而是等待一段时间,如果在此期间
本端有数据包要发送给对端,就在发送数据包时捎带上此ACK,如此一来节省了一个报文
本端没有数据包要发送给对端。延迟确认定时器会超时,然后发送纯ACK给对端
Linux提供了TCP_CORK选项,如果某个TCP socket上开启了这个选项,那么就相当于在这个socket出口堵上了塞子,往这个socket写入的数据都会聚集起来。虽然堵上了塞子,但是segment总得发送,不然数据会塞满整个TCP发送缓冲区,以下几种情况都会导致塞子打开:
满足以上任何一个条件,TCP就会将数据发送出去。对于Server来说,发送HTTP响应既要发送尽量少的segment,同时又要保证低延迟,那么需要在写完数据后显式取消设置TCP_CORK选项,让数据立即发送出去。
比如nginx中在sendfile模式下,可以设置打开TCP_CORK选项tcp_nopush on
(TCP_NOPUSH
与TCP_CORK
两个选项实现功能类似,只不过NOPUSH是BSD下的实现,而CORK是Linux下的实现)
1.如果client启用Nagle,并且server端启用了delay ack会有什么后果
假如client要发送一个长度为1600字节的请求,握手的MSS为1460,这个请求会拆为2个包,一个1460,一个140。第一个包发送至server后,server由于delay ack会延迟ack,同时由于server没有接受全请求,也无法回复http请求,而client的第二个包由于是小包,受nagle算法影响,会一直等待上一个包的ack,直至server的dalay ack超时(40ms),此时client收到第一个包的ack,接下来发送第二个包
看过太多tcp相关文章,但是看完总是不过瘾,似懂非懂,反复考虑过后,我觉得是那些文章太过理论,看起来没有体感,所以吸收不了。 希望这篇文章能做到言简意赅,帮助大家透过案例来理解原理。
我们的应用即使经过了测试部门的测试,也仍然很难全面覆盖用户的使用场景,为了保证万无一失,我们在进行发布的时候一般都会采用灰度发布,也就是会对新应用进行分批发布,逐步扩大新应用在整个及集群中的比例直到最后全部完成。灰度发布是说针对新应用在用户体验方面完全无感知。
docker的网络模式大致可以分成五种类型,在安装完docker之后,宿主机上会创建三个网络,分别是bridge网络,host网络,none网络,可以使用docker network ls命令查看。