我在Yahoo与ATS 九死一生的故事

http://www.sunchangming.com/blog/post/4667.html

去年9月,我去Yahoo后领导交给我的第一件事,就是把Yahoo内部一个过时的、已经End-Of-Life的http server换成Apache Traffic Server(ATS)。这件事情就类似于把某网站的架构从apache+tomcat变成nginx+tomcat一样,可以说非常简单。我只管更改一下安装脚本,剩下的让运维工程师去线上操作就行了。Too easy!! 然而没想到遇坑无数,我悲惨的人生就此开始。详情见下文。

100-continue导致响应慢

请见这个jira https://issues.apache.org/jira/browse/TS-1125 的Description。

调用我们服务的client service是使用C++基于libcurl实现的。而curl默认开启了一个很废柴的功能,就是当post body大于1k的时候,它会在Headers中加上"Expect: 100-Continue"。 当它收到100 continue的response header之后,它才会继续把body post过去。而ATS以及我们后端的App Server默认根本不理解这个东西,于是就导致curl一直卡在那里,等到timeout,然后才post body。

解决方法: Yahoo的Feifei Cai在2014年4月提交了一个补丁,使得ATS能够识别"Expect: 100-Continue"。该补丁已经被merge进去了。我只需要在配置文件中打开proxy.config.http.send_100_continue_response,那么ATS就会自动回复100 continue。问题"似乎"解决了。其实如果我们能说服调用方修改下他们的代码,禁用掉curl的这个功能,那么不仅能降低相应延迟(因为能减少一个RTT),而且也没有100 continue的麻烦了。可惜,不能。

本地端口耗尽

很遗憾的是,ATS与我们的backend(即origin server)之间并不是长连接,每来一个请求就需要建立一个TCP连接,每建立一个TCP连接就需要占用一个端口,于是很快就遇上了本地端口耗尽的问题。 Linux默认的time wait是180秒,也就是说5万个端口只够应对每秒270个HTTP请求。

这是一个非常常见的问题,通常有以下三种解决办法:

解决办法1: 减少time wait时间。 不靠谱,180秒是写死的,要改只能重新编译kernel。网上那些说可以通过sysctl改的,都是胡扯蛋。

解决办法2: sysctl中打开tcp_tw_recycle。 不安全。这台机器还要连接memcached等服务,而这些服务挂在VIP后面。

解决办法3: sysctl中打开tcp_tw_reuse。 可行。但是我测试发现,有轻微的性能损失。虽然很轻微,那就是因为这一点点改变,让我们项目的自动化测试中的性能测试挂掉了。领导斟酌再三,决定,不能因此而更改性能测试的阈值。所以此路不通。

实际上呢,我采用的是解决办法4: 127.0.0.x轮流用。虽然1个IP只有5万个端口,但是10个IP就有50万个端口,100个IP就有500万个端口。哈哈!我不得不为我的机智点个赞!

最后方法4使得ATS顺利上线。

上线后触发了bdb的bug

这又是一段苦痛的巨长无比的血泪史啊。我们ATS和backend是放在同一台物理机器上。上线后发现

(1). 在流量高峰期,backend莫名其妙的死掉,该进程的CPU几乎占满所有核。

(2). ATS偶尔会自动重启,大约1小时1次,伴随有core dump。

这构成了我部门2014年最大的线上故障。领导当即决定回滚,把ATS撤下,其它更改保留。其实我当时心里很冤。就好比你用apache+tomcat,然后高峰期发现tomcat CPU100%,可这关apache什么事情啊?!作为新人我心里很冤,争辩无力。总之,出问题的机器全掉格掉,重装系统,重新部署。

第二天,高峰期,backend继续死掉,死掉的依然还是昨天那些机器。这时候已经跟ATS一毛钱关系都没有了,硬盘都格过了啊……可是没想到组里还有人一口咬定就是ATS引起的,理由实在是太牵强我就不复述了。

CPU 100%这事其实并不难查,用perf看下CPU占哪了,然后打几个backtrace看看。

放两张第二天的截图。第一张是top的结果。

第一行是我们的backend server的进程。第二行是那个legacy的http server的进程(被该被ATS替换掉的那个)。

下面这张是perf top的结果。

还有pstack的结果我就不放了。

然后我认定是bdb的bug,证据已如此充分,并且我详细的解释了为什么bdb的mutex会耗费这么多CPU。但是没几个人能认同我。 :-( 依然还有人怀疑是ATS搞的鬼。

查找ATS coredump的原因

虽然ATS发生coredump只是次要原因,但是总归也是该解决的。我司有个team专门负责ATS的开发。这个问题最棘手在于,我们加载了Yahoo另外一个部门写的plugin。于是这事情就说不清楚,到底是ATS本身的问题,还是那个plugin的问题。在有的公司,这就成了两部门扯皮的事情。还好Yahoo不是。感谢ATS team的大力支持!backtrace显示,是那个插件在调用send的时候,传递给了一个无效的buffer,导致空指针异常。但是经ATS team和我一起合作分析发现,这是因为那个buffer被错误的提前释放了。当ATS收到"Expect: 100-Continue",它会准备好一个message block,填上"100 continue OK" 发回给client。当ATS收到body的时候,它会以为刚才那个答复已经发完了,所以它就会把之前的message block删掉。而实际上可能还没发完呢……

具体的技术细节可见此:https://issues.apache.org/jira/browse/TS-3285

Sudheer Vinukonda也是Yahoo的员工,ATS组的。是他去掉plugin后重现并修复了此bug。

5. fd耗尽,ATS僵死

系统监控图显示,在很偶然的情况下,ATS的fd会突然暴涨到30000万个,近乎耗尽,然后就不工作了。但是呢,ATS内部的监控又显示这个进程还活着,还能serve。这个简直比core dump还要命啊!!经我debug发现,是因为ATS的UnixNetVConnection::mainEvent函数错误的收到了VC_EVENT_WRITE_COMPLETE事件。我们使用了inception插件,所以它永远不该收到这个事件。于是我提了一个Bug Report:https://issues.apache.org/jira/browse/TS-3289 至于为什么会收到这个事件,以及如何稳定重现,我实在无能为力。

至此,我与ATS的恩怨情仇暂告一段落,下面是领导安排我在ATS的基础上开发一个基于脚本的HTTP router模块,择日再述。

我在Yahoo与ATS 九死一生的故事的更多相关文章

  1. 初识WEB:输入URL之后的故事

    1. 概述2. HTTP请求过程3. 相关性能检测及优化手段4. 浏览器的呈现过程5. 浏览器的呈现引擎6. 引用及延伸阅读 概述 为什么输入www.cnblogs.com之后敲一个回车,浏览器就会显 ...

  2. 张艾迪(创始人):创始人故事无限N个

    世界第一女孩+世界第一互联网女孩 创始人故事无限N个 全球第一互联网女孩EidyZhang艾迪.张 The World No.1 Girl :Eidyzhang The World No.1 Inte ...

  3. 初识WEB:输入URL之后的故事【转】

    转载一篇文章,分析的是浏览器输入url后所执行的一系列操作!写得非常清晰易懂,分享给大家! 作者:Jesse 出处:http://jesse2013.cnblogs.com/ 本文版权归作者和博客园共 ...

  4. Skype的故事:几乎所有风投都想投 犯罪分子洗钱必备

    Skype的故事:几乎所有风投都想投 犯罪分子洗钱必备 转载自: http://news.chinaventure.com.cn/11/7/1381032922.shtml 今年是 Skype 网络电 ...

  5. 数据分析侠A的成长故事

    数据分析侠A的成长故事 面包君  同学A:22岁,男,大四准备实习,计算机专业,迷茫期 作为一个很普通的即将迈入职场的他来说,看到周边的同学都找了技术开发的岗位,顿觉自己很迷茫,因为自己不是那么喜欢钻 ...

  6. Yahoo浮沉录

    Yahoo这一路曾经出过很多好技术 然而,任何人如果只是把 Yahoo 当作一家缺乏聚焦的企业来看也许忽视了公司内部的那些创新—偶尔甚至还有一些很好的产品创意.就拿搜索来说吧,我们说的不是付费搜索,而 ...

  7. ASP.NET_各个币种之间的汇率转换(实时)使用Yahoo汇率。

    近期开发支付平台的时候有运用到各国的实时汇率之间的转换问题,于是在往上找了很多相关资料,以下就是一些参考网址: 1.提供API接口的网站:https://www.showapi.com:这个网站有提供 ...

  8. 背后的故事之 - 快乐的Lambda表达式(一)

    快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...

  9. iOS的ATS配置 - 2017年前ATS规定的适配

    苹果规定 从2017年1月1日起,新提交的 app 不允许使用NSAllowsArbitraryLoads来绕过ATS(全称:App Transport Security)的限制. 以前为了能兼容ht ...

随机推荐

  1. STL内存分配

    STL内存创建 Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu  转载请标明来源 1.      Stl内存创建基类模板__malloc_alloc_tem ...

  2. 最小二乘法拟合java实现源程序(转)

    因为我所在的项目要用到最小二乘法拟合,所有我抽时间将C++实现的程序改为JAVA实现,现在贴出来,供大家参考使用./** * <p>函数功能:最小二乘法曲线拟合</p> * @ ...

  3. SDUT 2894-C(最短spfa)

    C Time Limit: 7000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描写叙述 给出一个带权无向图.包括n个点,m条边.求出s,e的最短路.保证最短路存在 ...

  4. 【原创】构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施

    原文:[原创]构建高性能ASP.NET站点 第六章-性能瓶颈诊断与初步调优(下前篇)-简单的优化措施 构建高性能ASP.NET站点 第六章—性能瓶颈诊断与初步调优(下前篇)—简单的优化措施 前言:本篇 ...

  5. 编程基础——C/C++,Java,ObjC讨论回调模式

    什么是回调? 因为它是从C开始进入编程世界.术语改只是口.叫习惯了.java里通常叫listener(监听器).C/C++里通常叫callback(回调),ObjC里面叫delegate(托付) 回调 ...

  6. Base64编码和解码

    Base64这是一个二进制编码方法转换成可打印字符.主要用于邮件传输. Base64将64人物(A-Z,a-z,0-9,+,/)由于基本字符集.把所有的符号转换成字符集. 编码: 编码每次3节转为4字 ...

  7. SQL Server 2008 R2 跟踪标志

    原文:SQL Server 2008 R2 跟踪标志 跟踪标志用于临时设置特定服务器的特征或关闭特定行为.例如,如果启动 SQL Server 的一个实例时设置了跟踪标志 3205,将禁用磁带机的硬件 ...

  8. STL--F - Sequence(n*m-&gt;之前的最低要求m个月)

    F - Sequence Time Limit:6000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit ...

  9. Spring-MVC4 + JPA2 + MySql-5.5 + SLF4J + JBoss WildFly-8.1开发环境的搭建

    面试被问Spring4,它的目的是把过去Spring3所有升级项目Spring4.现在将记录在此环境搭建过程. 第一次使用Maven Archetype创建一个项目框架,运行以下命令: mvn arc ...

  10. vs2015web工程中的html引用压缩后css后无法智能提示的问题解决

    环境:win10x64 vs2015企业版 项目:空白web项目(.net framework4) 问题:html页面加入压缩后的css(eg:bootstrap.min.css),编码的时候无法智能 ...