1、现象nginx
在一次访问请求nginx中,一般只须要几毫秒的RT,但当请求数据达到某一个数值时,rt明显提升,甚至超过了300毫秒。 算法
2、问题的缘由tcp
你们都知道,TCP为了提升带宽利用率和吞吐量,作了各类优化。好比delay ack和Nagle算法。就是这样的一些优化使用不慎,致使陷入性能问题。接下来就先分别说说delay ack和Nagle算法。性能
就以咱们的Nginx为例吧。nginx收到请求后,当即返回一个ack收到确认包。这个包没有只有消息头没有任何数据内容。这就致使一个明显的问题:带宽利用率比较低效。那有没有办法能够优化呢?有,就是delay ack。怎么作呢?就是Nginx收到数据不要着急发送ack包,而是等一段时间好比40毫秒,若是这40毫秒内有数据要发送给client。那么这个ack就能够打这趟顺风车了,从而节省资源。若是40毫秒内没数据发送给client呢,没办法,到了40毫秒也必须发送ack包。由于client觉得丢包重传的代价更大。优化
还有一种状况就是,nginx收到数据在延缓等待发送ack包时,又收到client的一个数据包。这时nginx会把两个ack包合并为一个ack包回复给client。spa
在发送数据包时,若是数据包小于MSS(最大分段大小),则会去判断是否有已发出去的包尚未ack,若是有则不着急发送,等等前面的包收到回复再发送。server
假如client发送一个http请求个server。这个请求时1600byte,MSS是1460byte。那么就会分红两个tcp包,第一个1460byte,剩下的140byte放在第二个包。第一个包发送到server时,因为server开启了delay ack,因此没有当即ack,又由于server没有收到完整的http请求包,因此也没有当即进行http response,这就致使ack会一直等到40毫秒的delay时间。其实若是client当即发送第二个包,server收到后当即作出http response也不会有问题。问题时client启动了Nagle算法,第一个包没有收到ack,第二个包就不会当即发送出去。两边相互等。这就是性能问题的核心缘由。资源