ChannelOption.TCP_NODELAY, true-浅谈tcp_nodelay的作用
2019独角兽企业重金招聘Python工程师标准>>>
在TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能的利用网络带宽,TCP总是希望尽可能的发送足够大的数据。这里就涉及到一个名为Nagle的算法,该算法的目的就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。
TCP_NODELAY就是用于启用或关于Nagle算法。如果要求高实时性,有数据发送时就马上发送,就将该选项设置为true关闭Nagle算法;如果要减少发送次数减少网络交互,就设置为false等累积一定大小后再发送。默认为false。
浅谈tcp_nodelay的作用
今天在用nginx作web缓存的时候,发现在http里加入这样个参数,能有效的提高数据的实时响应性,那就是tcp_nodelay.下面我们来说说tcp_nodelay的原理:
TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,这里我们主要讲TCP_NODELAY.Nagle化在这里的含义是采用Nagle算法把较小的包组装为更大的帧。JohnNagle是Nagle算法的发明人,后者就是用他的名字来命名的,他在1984年首次用这种方法来尝试解决福特汽车公司的网络拥塞问题(欲了解详情请参看IETF RFC 896)。他解决的问题就是所谓的silly window syndrome,中文称“愚蠢窗口症候群”,具体含义是,因为普遍终端应用程序每产生一次击键操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据载荷以及40个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞,。Nagle化后来成了一种标准并且立即在因特网上得以实现。它现在已经成为缺省配置了,但在我们看来,有些场合下把这一选项关掉也是合乎需要的。
现在让我们假设某个应用程序发出了一个请求,希望发送小块数据,比如sns游戏中的点击确定按钮。我们可以选择立即发送数据或者等待产生更多的数据然后再一次发送两种策略。如果我们马上发送数据,那么交互性的以及客户/服务器型的应用程序将极大地受益。例如,当我们正在发送一个较短的请求并且等候较大的响应时,相关过载与传输的数据总量相比就会比较低,而且,如果请求立即发出那么响应时间也会快一些。以上操作可以通过设置套接字的TCP_NODELAY选项来完成,这样就禁用了Nagle算法,在nginx中设置tcp_nodelay on,注意放在http标签里。
另外一种情况则需要我们等到数据量达到最大时才通过网络一次发送全部数据,这种数据传输方式有益于大量数据的通信性能,典型的应用就是文件服务器。应用Nagle算法在这种情况下就会产生问题。但是,如果你正在发送大量数据,你可以设置TCP_CORK选项禁用Nagle化,其方式正好同TCP_NODELAY相反(TCP_CORK 和 TCP_NODELAY 是互相排斥的)。下面就让我们仔细分析下其工作原理。
假设应用程序使用sendfile()函数来转移大量数据(nginx里可以设置sendfile on)。应用协议通常要求发送某些信息来预先解释数据,这些信息其实就是报头内容。典型情况下报头很小,而且套接字上设置了TCP_NODELAY。有报头的包将被立即传输,在某些情况下(取决于内部的包计数器),因为这个包成功地被对方收到后需要请求对方确认。这样,大量数据的传输就会被推迟而且产生了不必要的网络流量交换。
但是,如果我们在套接字上设置了TCP_CORK(可以比喻为在管道上插入“塞子”)选项,具有报头的包就会填补大量的数据,所有的数据都根据大小自动地通过包传输出去。当数据传输完成时,最好取消TCP_CORK选项设置给连接“拔去塞子”以便任一部分的帧都能发送出去。这同“塞住”网络连接同等重要。
总而言之,如果你肯定能一起发送多个数据集合(例如HTTP响应的头和正文),那么我们建议你设置TCP_CORK选项,这样在这些数据之间不存在延迟。能极大地有益于WWW、FTP以及文件服务器的性能,同时也简化了你的工作.
最近用了用libsoup库,用它来写个HttpServ玩。结果发现性能不行,竟然比nginx/apache慢了20倍。拿wireshark一看,发现每个TCP回复都要耗时几百毫秒。这就一下子让我想到了Nagle算法(一般的Nagle算法都是延时200ms)。于是下载libsoup的库,看代码,果然没有setsockopt。于是设置了TCP_NODELAY,结果速度一下子就上去了,与nginx相差无几(WEB主要是耗IO,在高并发的时候才能显示出代码优化的好处)。
而这个Nagle算法,在Windows上的效果尤其明显。以前使用GIO中的GSocket,也是如此。
对于初学socket编程的人来说,可能会忘记这里还有个“陷阱”。Nagle算法适用于小包、高延迟的场合,而对于要求交互速度的b/s或c/s就不合适了。socket在创建的时候,默认都是使用Nagle算法的,这会导致交互速度严重下降,所以需要setsockopt函数来设置TCP_NODELAY为1.
不过取消了Nagle算法,就会导致TCP碎片增多,效率可能会降低。所以,这也是要有所取舍的。
转载于:https://my.oschina.net/u/2381372/blog/802802
ChannelOption.TCP_NODELAY, true-浅谈tcp_nodelay的作用相关推荐
- sql之浅谈视图的作用
[数据库]☆★sql之浅谈视图的作用 在一个项目的实际开发过程中牵涉到复杂业务的时候,我们不可避免的需要使用中间表来进行数据连接,有的同学就说了,我可以采用Hibernate进行主外键进行关联啊?多对 ...
- 汽车钥匙芯片工作原理 浅谈汽车钥匙芯片作用及分类
工程师谭军 发表于 2018-10-08 10:01:00 http://m.elecfans.com/article/791926.html 本文主要是关于汽车钥匙芯片的相关介绍,并着重对汽车钥匙芯 ...
- 浅谈angular的作用
一.简单认识angular 1 AngularJS是什么? AngularJs(简称ng)是一个用于设计动态web应用的结构框架.首先,它是一个框架,不是类库,是像EXT一样提供一整套方案用于设计we ...
- 从石头剪刀布浅谈算法的作用
刚开始学习C语言的时候,常常听到前辈说,C语言的核心就是算法.但是对于小白来说,常常一脸懵逼,搞不懂啥叫算法?算法有什么用?我的if-else语句照样可以走天下.但是作为小白来说虽然不懂但是也不敢问, ...
- twrp双清勾选哪两个_浅谈TWRP的作用
小白向教程,大佬请后退 不少小白也曾想过刷机,但却不能理解twrp作用与使用方法,下面就带领小白们来了解twrp 一.twrp是什么? TWRP是国外android爱好者开发的一款工具,全名是:Tea ...
- 技术总监和CTO的区别 浅谈CTO的作用----软件公司如何开源节流(一)
我一直在思考软件公司如何开源节流. 当然,老板也在思考开源节流. 当然,老板思考的开源节流在公司运营层面上,而我作为CTO,我考虑的则是在产品运营角度上来思考这个问题.否则,一个软件公司,它的生存与发 ...
- 浅谈枚举的作用和用法
1.枚举(Enum)类型特点: 能够列出所有可能的取值,并给它们取一个名字.(一种新的数据类型) 2.枚举(Enum)语法格式: enum typeName{ valueName1, valueNam ...
- 浅谈CTF中各种花式绕过的小trick
文章目录 浅谈CTF中各种花式绕过的小trick 前言 md5加密bypass 弱比较绕过 方法一:0e绕过 方法二:数组绕过 强比较绕过 方法:数组绕过 md5碰撞绕过 方法:使用Fastcoll生 ...
- 计算机方面的文献在哪里找,最新浅谈计算机参考文献 浅谈计算机专著类参考文献哪里找...
[100个]关于最新浅谈计算机参考文献汇总,作为大学生的毕业生应该明白了浅谈计算机专著类参考文献哪里找,收集好参考文献后的浅谈计算机论文写作起来会更轻松! 一.浅谈计算机论文参考文献范文 [1]浅谈计 ...
最新文章
- Javascript中typeof instanceof constructor的区别
- 如何绘制计算机软件程序流程图?
- Intellij代码界面导入maven工程,且该maven工程不具备intellij配置文件
- java list 去重复元素_java List去掉重复元素的几种方式
- CentOS7-Docker 配置国内镜像源
- html ul高度自适应,如何让div中的ul元素自适应
- win2003 搭建文件服务器,用win2003+server搭建安全文件服务器.doc
- css大会站点顶部的一个特效
- 魅族 android版本升级,魅族系统更新APP
- linux 图形设计软件,Ubuntu下使用Blender 3D图形专业设计工具
- linux能yum装mcafee吗,Redhat(64位)安装Mcafee步骤
- mysql 三角函数_三角函数公式
- apifox通过若依平台登录传参获取token
- Linux PCI和PCIe总线
- 二进制转化成ascll_怎样将二进制转ascii码
- background 与 background-image
- NOIP2009提高组复赛原题题解——Proking
- 004.了解Excel宏
- 工作日,我们又团建了!
- Vue Uncaught SyntaxError: Unexpected token ‘<‘ 路由问题