清泛IT社区App Inventor 2 中文社区

搜索

扫码访问移动社区 移动社区,您的掌上技术专家

关注我,精彩不错过! 关注我,精彩不错过!

扫码安装最新版AI伴侣 最新版AI伴侣v2.72

Aia Store .aia 源码一站式解决方案 发布日志AI2连接测试ai2Starter模拟器

开通会员送SVIPApp Inventor 2 拓展有奖征文 VIP会员享专有教程,免费赠送基础版*技术支持服务! AI2入门必读中文文档中文教程IoT专题

查看: 864|回复: 0
打印 上一主题 下一主题

为什么你得学些 TCP 的知识?

  • TA的每日心情
    开心
    2024-02-17 18:16
  • 签到天数: 14 天

    [LV.3]偶尔看看II

    546

    主题

    715

    帖子

    1万

    积分

    管理员

    这里没有广告...

    Rank: 9Rank: 9Rank: 9

    积分
    10709
    QQ
    跳转到指定楼层
    楼主
    发表于 2016-04-20 12:12:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    这不是指要明白 TCP 的所有东西,也不是说要通读 《TCP/IP 详解》。不过懂一点 TCP 知识是很有必要的。理由如下:
    当我还在 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,并且会一直使用下去。

    本文由 伯乐在线 - 刘晓鹏 翻译,Namco 校稿。英文出处:Julia Evans

    清泛网 - 专注IT技能提升
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    © 2024 tsingfun.com, Inc.  沪ICP备2020034476号-1  沪公网安备31011702000040号

    GMT+8, 2024-11-22 00:26 , Processed in 0.024395 second(s), 39 queries .