文档章节

ChannelOption.TCP_NODELAY, true->浅谈tcp_nodelay的作用

HelloRookie
 HelloRookie
发布于 2016/12/09 10:13
字数 1562
阅读 47
收藏 0
点赞 0
评论 0

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碎片增多,效率可能会降低。所以,这也是要有所取舍的。

本文转载自:http://stephen830.iteye.com/blog/2109006

共有 人打赏支持
HelloRookie
粉丝 4
博文 137
码字总数 24176
作品 0
广州
程序员
netty pts上不去

@石头哥哥 你好,想跟你请教个问题:netty4实现的http简单服务端,pts只达到2万,修改了一些参数也没有作用,不知道这个瓶颈点在那里,请帮忙看下,多谢。服务器4核,16G private EventLoop...

风影1
2015/02/09
369
2
netty5 长联接问题

我在使用netty5做通讯框架,长联接。连续发送多个请求,服务端每个请求后也执行 ctx.writeAndFlush(buildResponse(message, body));服务端居然将几个请求处理完了后。端户端才会有反应。哪位能...

毛毛侯
2015/04/28
813
4
2015年12月4日:让 Netty 使用 openssl

2015年12月4日,风轻云淡 参考这篇文档《Forked Tomcat Native》。 两点注意 netty-tcnative 的版本最高只能是 1.1.33.Fork6,否则会有 libnetty-tcnative.so 无法加载的问题。这个问题在 Ne...

编走编想
2015/12/04
253
0
netty服务端详解

本文仅适用与Netty4.0.32版本,其他版本是否适用表示并不清楚... Netty服务器启动流程: 1、创建线程池 创建处理连接的线程池:bossGroup 创建处理所有事件的线程池:workerGroup EventLoopGro...

weiliu007
2016/09/07
30
0
SOCKET选项--TCP_NODELAY

默认情况下,发送 数据采用Negale算法. Negale算法是指发送的数据不会立刻发出,而是放在缓冲区内,等缓冲区满了再发出.发送完一批数据后,会等待接收方对这批数据的回应,然后再发送下一批数据....

dyaodwjh
2013/12/01
0
0
nginx 的 tcp_nopush 和 tcp_nodelay

TCPNODELAY 和 TCPCORK, 这两个选项都对网络连接的行为具有重要的作用。许多UNIX系统都实现了TCPNODELAY选项,但是,TCPCORK则是Linux系统所独有的 而且相对较新;它首先在内核版本2.4上得以...

范堡
2009/09/21
13.6K
1
TCP_NODELAY 和 TCP_NOPUSH

TCPNODELAY 和 TCPNOPUSH 一、问题的来源 今天看到 huoding 大哥分享的 lamp 面试题,其中一点提到了: Nginx 有两个配置项: TCPNODELAY 和 TCPNOPUSH ,请说明它们的用途及注意事项。 初看...

xiaomaimai
2014/09/24
0
0
netty客户端读取文件内容内存溢出

基于netty 4.0.14final 最近做一个存储转发项目,使用netty框架,客户端发送报文到服务器端,服务器端将报文入库,在客户端模拟报文时,采用读取txt文件的方式,每读取一行就发送到服务器端,...

highstar0617
2016/01/27
706
2
TCP连接优化

当我们在浏览器上点开一个网页时,我们的客户端就会和服务器建立一个socket连接。Soket是什么,什么是Socket 五元组,常见的TCP优化参数的依据又是什么,这里我们将来分析一下。 Socket 五元...

酥心糖
2017/08/31
0
0
Nginx 教程(2):性能

tcpnodelay, tcpnopush 和 sendfile tcp_nodelay 在 TCP 发展早期,工程师需要面对流量冲突和堵塞的问题,其中涌现了大批的解决方案,其中之一是由 John Nagle 提出的算法。 Nagle 的算法旨在...

夜华-Q
01/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

十大Intellij IDEA快捷键

Intellij IDEA中有很多快捷键让人爱不释手,stackoverflow上也有一些有趣的讨论。每个人都有自己的最爱,想排出个理想的榜单还真是困难。以前也整理过Intellij的快捷键,这次就按照我日常开发...

HJCui
18分钟前
0
0
word 使用mathtype 编写 数学公式

下载安装,这个链接命名。。。。 http://www.mathtype.cn/xiazai.html 安装之后会多出一个选项 使用内联方式插入图表 编写公式的界面 设置支持latex 语法 输入公式回车就可以看到结果...

阿豪boy
36分钟前
0
0
Promise

定义 Promise是异步编程的一种解决方案,所谓Promise就是一个容器,里面保存着某个未来才会结束的事件(通常是一个一步操作)的结果。 特点: 2.1 对象的状态不受外界影响,三种状态pending...

litCabbage
47分钟前
0
0
设计模式:适配器模式

说明:在不改变旧接口代码的前提下,为该接口新增其他接口的功能 适配器模式可以分为:类适配器模式、对象适配器模式、接口适配器模式 前两种模式下,我会以播放器为例。老版的播放器(Playe...

人觉非常君
47分钟前
0
0
使用VsCode搭建Java开发环境,创建springboot应用

1、在 Visual Studio Code 中打开扩展视图(Ctrl+Shift+X),输入关键词java、spring分别下载Java开发插件包和springboot插件包 2、配置参数 点击设置按钮,进入设置选项,配置用户设置 在用户...

qsyan
51分钟前
20
0
调教属于你的“贾维斯”(给自己挖了一个很大的坑)

今天玩一下现在很火的人工智能。 废话不多说,先来看几张图: 看出什么蹊跷了吗? 再来看一个视频: https://www.zhihu.com/video/1002567561061511168 (演示网址和代码见文末) 人工智能离...

crossin
56分钟前
1
0
ES10-检索入门

1.创建索引,准备数据 定义索引结构 DELETE telegraphPUT telegraph{ "mappings": { "msg":{ "properties": { "title":{ "type": "text", ...

贾峰uk
今天
1
0
css 三角形

1.无边框三角形 条件:width,height设置为0,border-width设置一定的宽度,border-color保留一边有颜色其他三边设置透明 .triangle{ width:0px; height:0px; border-width:40...

爱喝水的小熊
今天
0
0
NPM依赖包版本号~和^和*的区别

~ 会匹配最近的小版本依赖包,比如~1.2.3会匹配所有1.2.x版本,但是不包括1.3.0 ^ 会匹配最新的大版本依赖包,比如^1.2.3会匹配所有1.x.x的包,包括1.3.0,但是不包括2.0.0 * 这意味着安装最...

fangPeng_
今天
0
0
第三章 spring-bean之SimpleAliasRegistry(2)

前言 AliasRegistry的实现类,嗯,嗯,嗯,一个很简单的实现。只有一个map。 源码解读 接口 AliasRegistry public interface AliasRegistry {void registerAlias(String name, String al...

鸟菜啊
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部