BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

懂一点TCP是多么的必要

| 作者 金灵杰 关注 5 他的粉丝 发布于 2015年11月26日. 估计阅读时间: 4 分钟 | CNUTCon 了解国内外一线大厂50+智能运维最新实践案例。

大部分开发者可能不会直接使用TCP协议进行网络开发,但是在分布式系统中,无可避免的需要接触到应用层协议,或是排查网络导致的问题。因此,对于TCP协议,不是每个开发者都需要熟读《TCP/IP详解》[1][2][3],但还是建议能够了解一些TCP协议有关的知识。

有了一些基础知识,可以帮助我们更快的排查网络问题,例如,在《性能探索——我们如何将每个POST请求削减200ms》这篇博客中,作者介绍了他们对POST请求延迟问题的排查,为什么每个POST请求会多消耗200ms,这里摘录一些最终排查到的核心原因:

Ruby的Net::HTTP库,会将HTTP的POST请求拆分成两个TCP数据包:POST请求头一个数据包,请求体一个数据包。而curl命令却相反,它会尽可能的将请求头和请求体塞入一个数据包中。更糟糕的是,Net::HTTP在打开TCP套接字的时候,没有设置TCP_NODELAY选项,因此该套接字会等待第一个数据包的确认包(ack)之后,才会发送第二个数据包。该行为是Nagle算法的结果。

到连接的另一端,HAProxy需要选择如何应答这两个包。在版本1.4.15(我们曾经使用的版本)中,它选择使用TCP延迟应答。延迟应答和Nagle算法相互影响,引起了请求中断,直到服务端触发了延迟应答超时。

重要通知:接下来InfoQ将会选择性地将部分优秀内容首发在微信公众号中,欢迎关注InfoQ微信公众号第一时间阅读精品内容。

这时连接双方(Ruby Net::HTTP和HAProxy)的数据交互是这样的:

双方都在等待对方发送数据包,应用端等待HAProxy发送应答包(Nagle算法),HAProxy在等待应用端后续的数据包(延迟应答)。这就导致了中间的200ms延迟。

找到问题之后,解决就非常方便,在应用端设置TCP_NODELAY参数或者服务端取消延迟应答(TCP_QUICKACK参数)。另一个问题又来了,设置了这两个参数之后,对于应用和服务端有什么影响呢?

应用端套接字设置了TCP_NODELAY参数之后,TCP包将不会使用缓冲区而直接发送。如果应用端会发送大量小数据,可能会遇到缓冲区刷新的瓶颈,同时可能会有大量带宽浪费在了TCP头上。

服务端使用了TCP_QUICKACK,将不会合并发送应答包,同样会增加数据包数量。但是相对来说,应答包的损耗相对于延迟应答来说可能更小。

上面这个示例说明了,虽然大部分情况下,开发者不需要了解TCP协议,但是如果遇到了诸如延迟应答/TCP_NODELAY的问题,了解一些TCP协议相关知识是非常有用的。如今,分布式计算、分布式存储、微服务等架构的兴起,越来越多的系统需要和外部系统交互,其中大部分最终是基于TCP协议,没事了解一些TCP协议,在遇到性能调优、问题诊断时,可能会有意想不到的收获。


感谢魏星对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群InfoQ好读者(已满),InfoQ读者交流群(#2)InfoQ好读者)。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT