`
- 浏览:
12874 次
- 性别:
- 来自:
北京
-
当我还在 Recurse Center 的时候,我用 Python 写过 TCP 协议栈(还写过一篇文章:如果你用 Python 写 TCP 协议栈会遇到什么?)。这是一次有趣的学习经历,但是也仅此而已。
一年以后,工作中有人在 Slack 上提到:“嘿,我在向 NSQ 发布消息时,每次要耗费 40 毫秒”。我已经断断续续思考了一个星期,但是没有任何结果。
一点背景知识:NSQ 是一个消息队列,你通过本地的一个 HTTP 请求向其发布消息。发送本地的一个 HTTP 请求确实不应该花费 40 毫秒,有时候会更差。NSQ 守护进程的负载不高,也没有使用过多的内存,也看不到 GC 停顿。这究竟是为什么呢?神呐,救救我吧!
突然我记起我一周以前看过的一篇叫做“性能研究(In search of performance)”的文章——我们如何为每个 POST 请求节省 200ms。在这篇文章中,他们说到为什么每个 POST 请求会花费额外的 200 毫秒。就是这个原因。这是该文章中的关键段落:
延迟确认(ACK) 与 TCP_NODELAY
Ruby 的 Net::HTTP 会将 POST 请求切分为两个 TCP 包,一个消息头,一个消息体。相反,curl 会将这两者合并为一个包。更糟糕的是,Net::HTTP 在打开 TCP 套接字时不会设置 TCP_NODELAY,这将导致第二个包需要等到第一个包的接收确认通知之后才能发送。这是 Nagle 算法导致的。
转换到连接的另一端,HAProxy 需要决定如何确认这两个包。在 1.4.18 版本中(我们正在用的版本),它是通过 TCP 延迟确认通知来实现的。延迟确认对 Nagle 算法有非常糟糕的影响,会导致请求暂停直到服务器延迟确认超时。
现在我们解释这个段落说的内容。
TCP 是一个通过数据包传输数据的算法
他们的 HTTP 库将 POST 请求分割成两个小的数据包发送
接下来,TCP 采用类似如下的步骤进行交互:
application:Hi!这里有一个数据包。
HAProxy:(沉默),等待第二个包发送
HAProxy:对了,我需要返回一个确认,不过没关系,等会吧
application: (沉默)
application:好吧,我正在等待确认,可能现在网络延迟比较大
HAProxy:好吧,太烦人了,这是一个确认。
application:好极了,这是第二个数据包!!!
HAProxy:亲,我们已经搞定了。
这个过程是不是应用程序和 HAProxy 都在消极等待另一方发送信息?这就是那额外的 200ms。应用程序这么做的是因为 Nagle 算法,而 HAProxy 消息等待的原因是延迟确认。
据我所知,延迟确认是所有 Linux 系统的默认行为。所以这不是一个偶然或者异常情况,如果发送 TCP 数据包多一个 1 个,你就会遇到这种情况。
现在,我们成为专家了
读过这篇文章之后我很快就忘了。不过当我被额外的 40 毫秒难住的时候,我又记起来了。
所以我认为——这不可能是我的问题,可能吗?可能吗??然后我发了一封邮件给我团队说:“我想我快要疯了,但是这可能是 TCP 的问题”。
所以我提交了一次修订,将我的应该调整为 TCP_NODELAY,然后问题就“嘣”的一声解决了。
40 毫秒的延迟立马就消失了。所有的事情都解决了,我就是个天才。
我们是否应该完全停止使用延迟确认?
我刚好在 Hacker News 看到 John Nagle (Nagle 算法的创始人)对 @alicemazzy 提到这个问题的评论。
本质问题是延迟确认。200 毫秒的“延迟确认”是一个非常不好的主意,1985 年中,在伯利克(Berkeley)研究 BSD 的人实际上没有真正明白这个问题。延迟确认是应用层对 200 毫秒内是否响应的一场博弈,但是即便每次它都赌输了,TCP 仍在使用延迟确认。
他继续说到,确认本身是很小并且消耗很低的,延迟确认引起的问题可能比它解决的问题还要多。
不懂得 TCP 你就无法解决 TCP 问题
我曾经也认为,TCP 是一个相当底层的问题,我不需要明白。大多数时候你的确不需要明白。但是有的时候,当你在实践中遇到由于 TCP 算法引起的 bug 时,懂点 TCP 知识就变得非常重要了。(正如我们经常在博客中讨论的,许多事情都是这样,比如系统调用和操作系统:) )
延迟确认及 TCP_NODELAY 的交互非常不好——这对任何语言实现的 HTTP 请求都有影响。你不需要很深入的去了解,成为系统程序专家。但是了解一点 TCP 是如何运作的,对我的工作的确大有裨益。通过对 TCP 的学习,我才意识到这篇博客所描述的问题也许正好是我所熟悉的领域。我也一直在使用 strace,并且会一直使用下去。
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
延迟确认收入并延迟纳税的行为可能会被视为逃税或避税,面临税务稽查的风险。一旦被查实,企业可能需要一次性补缴税款,如文中提到的6000万销售额按17%的增值税率计算,还需支付滞纳金和罚款。此外,这种做法还导致...
其次,企业可能为了降低税负或转移利润而少计收入或延迟确认。这可能表现为收到货款后不确认收入,或将货款存入非本单位账户。以旧换新销售时,只确认新旧商品的差价为收入,或者在劳务结果可可靠估计时推迟确认收入...
盈余管理分为正向管理和反向管理,前者通常通过提前确认收入来增加盈余,后者则通过延迟确认收入来减少盈余。常见的盈余管理手段包括提前或延迟确认收入、选择性费用资本化、变更会计估计和处理异常损失等。 【债务...
而对于收益或好消息,企业应延迟确认。这种稳健的会计处理方式有助于提高财务报告的质量,增强投资者对企业的信心。 参考文献: 1、 甄红线,王三法,王晓洪.公司债特殊条款、债券评级与会计稳健性[J].会计研究,2019...
公司的收入指引之前为31-33亿欧元,但由于疫情和产品升级影响,收入延迟确认导致营收有所减少,符合调整后的24-25亿欧元区间。 2. 业务部门分析:从具体业务来看,ASML的系统业务中逻辑业务(Logic)持续增长,而...
2. 延迟确认收入:通过主营业务收入明细账,对比销售合同约定交付、房屋交付、入住和发票开具四个时间点,确保收入及时确认。 3. 预收款延迟入账:审查收款收据存根联和预收账款、其他应付款明细账,确认是否存在...
例如,在交互式输入中,当用户输入如"date\n"这样的命令时,数据会被立即发送,但TCP不会立即发送确认(ack),而是等待一定时延后,或者与需要发送的数据一起发送,这被称为延迟确认。这种机制减少了网络中微小分组...
3. **延迟确认**:为了提高效率,TCP可能不会立即对每个数据段发送ACK,而是累积多个数据段后再一起确认,这种机制称为延迟确认。 4. **累计确认**:累计确认允许接收方在一个ACK中确认多个连续的数据段,提高了...
延迟确认策略是接收方不立即发送ACK,而是等到有新的数据需要发送时一并确认;Nagle算法则鼓励发送大段数据,减少网络中小数据包的数量。 6. 拥塞控制:当网络出现拥塞时,TCP通过减缓数据发送速率来防止拥塞进一步...
【收入准则概述】 会计收入准则是一项重要的财务会计原则,它主要规范了企业在日常活动中如何确认、计量...同时,通过对收入的严格确认和计量,防止企业提前或延迟确认收入,操纵利润,保障财务信息的透明度和可比性。
2. **延迟确认**:合并多个ACK,减少确认的开销,提高网络效率。 3. **动态自适应调整**:根据网络状况动态调整TCP的拥塞窗口,例如使用TCP Vegas或TCP BBR等新型拥塞控制算法。 4. **减少RTT(往返时间)**:通过...
在使用`tcp_test`之前,确保你了解了基本的TCP概念,如滑动窗口机制、拥塞控制(慢启动、快速重传和快速恢复等)、TCP选项(如Nagle算法和延迟确认)。此外,为了进行测试,你需要一台运行服务器程序的设备和至少一...
- 了解这些差异有助于企业进行合理的税务筹划,如合理安排收入确认时间,避免提前或延迟确认导致的税收负担不均衡。 - 同时,企业需要确保在税务报表和会计报表之间的一致性,以满足审计要求和监管机构的审查。 ...
这种处理方式确保了收入确认的合理性,避免了提前或延迟确认收入导致的财务失真。 总的来说,营运收入的核算涉及物流企业的各项经营活动,包括收入的分类、确认原则和方法。准确理解和应用这些原则,不仅可以帮助...
- 通过对预售、收入确认的检查,核实销售收入的完整性,防止提前或延迟确认收入以逃避税收。 - 检查税前扣除项目,如成本、费用的合规性,防止虚增成本减少税负。 3. **房地产行业预售的检查**: - 预售款项的...
5. **赊销和分期收款审查**:审查企业在合同约定的收款日期确认收入的情况,防止提前或延迟确认。 6. **长期工程合同审查**:检查企业在按照完工进度确认收入时的计算方法是否合规,是否存在虚报收入的情况。 2. *...
此外,TCP还有许多其他特性,如延迟确认、时间戳选项等,它们都是为了提升传输效率和准确性。例如,延迟确认可以减少不必要的往返时间,提高网络性能;时间戳则可以帮助确定数据包的准确顺序,解决网络时延问题。 ...
实验中,学生需要通过实际操作和数据分析来理解这些概念,例如观察RTT(往返时间),计算丢包率,查看不同操作系统的初始cwnd(拥塞窗口大小)差异,以及是否使用Delay ACK(延迟确认)策略。这些实践将帮助学生从...