我在Yahoo与ATS 九死一生的故事
我在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 九死一生的故事的更多相关文章
- 初识WEB:输入URL之后的故事
1. 概述2. HTTP请求过程3. 相关性能检测及优化手段4. 浏览器的呈现过程5. 浏览器的呈现引擎6. 引用及延伸阅读 概述 为什么输入www.cnblogs.com之后敲一个回车,浏览器就会显 ...
- 张艾迪(创始人):创始人故事无限N个
世界第一女孩+世界第一互联网女孩 创始人故事无限N个 全球第一互联网女孩EidyZhang艾迪.张 The World No.1 Girl :Eidyzhang The World No.1 Inte ...
- 初识WEB:输入URL之后的故事【转】
转载一篇文章,分析的是浏览器输入url后所执行的一系列操作!写得非常清晰易懂,分享给大家! 作者:Jesse 出处:http://jesse2013.cnblogs.com/ 本文版权归作者和博客园共 ...
- Skype的故事:几乎所有风投都想投 犯罪分子洗钱必备
Skype的故事:几乎所有风投都想投 犯罪分子洗钱必备 转载自: http://news.chinaventure.com.cn/11/7/1381032922.shtml 今年是 Skype 网络电 ...
- 数据分析侠A的成长故事
数据分析侠A的成长故事 面包君 同学A:22岁,男,大四准备实习,计算机专业,迷茫期 作为一个很普通的即将迈入职场的他来说,看到周边的同学都找了技术开发的岗位,顿觉自己很迷茫,因为自己不是那么喜欢钻 ...
- Yahoo浮沉录
Yahoo这一路曾经出过很多好技术 然而,任何人如果只是把 Yahoo 当作一家缺乏聚焦的企业来看也许忽视了公司内部的那些创新—偶尔甚至还有一些很好的产品创意.就拿搜索来说吧,我们说的不是付费搜索,而 ...
- ASP.NET_各个币种之间的汇率转换(实时)使用Yahoo汇率。
近期开发支付平台的时候有运用到各国的实时汇率之间的转换问题,于是在往上找了很多相关资料,以下就是一些参考网址: 1.提供API接口的网站:https://www.showapi.com:这个网站有提供 ...
- 背后的故事之 - 快乐的Lambda表达式(一)
快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...
- iOS的ATS配置 - 2017年前ATS规定的适配
苹果规定 从2017年1月1日起,新提交的 app 不允许使用NSAllowsArbitraryLoads来绕过ATS(全称:App Transport Security)的限制. 以前为了能兼容ht ...
随机推荐
- Python爬虫框架Scrapy获得定向打击批量招聘信息
爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这样的说法不够专业,更专业的描写叙述就是.抓取特定站点网页的HTML数据.只是因为一个站点的网页非常多,而我们又不可能事先知道全部网页的URL地址, ...
- C#多线程编程实例 螺纹与窗口交互
C#多线程编程实例 螺纹与窗口交互 代码: public partial class Form1 : Form { //声明线程数组 Thread[] workThreads = new Thread ...
- 惠普4431s 笔记本配置
hp-4431s驱动精灵硬件检测报告 版本:2015.3.26.1363(8.1.326.1363)================================================== ...
- 为什么windows dos和Linux shell有这样的差别??
Windows dos随着impdp导入数据库: impdp "sys/password@ip:1521/sidname as sysdba" directory=dbdir du ...
- Vim经常使用技巧总结1
我的主力博客:半亩方塘 1. 反复上次的操作在普通模式下用 . 命令 2. 取消上次的操作在普通模式下用 u 命令 3. 整行删除在普通模式下用 dd 命令,此命令在删除行后 不进入插入模式 4. 整 ...
- POJ 3076 Sudoku DLX精确覆盖
DLX精确覆盖模具称号..... Sudoku Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 4416 Accepte ...
- Memcahce(MC)系列(三)Memcached它PHP转让
由PHP转让Memcahce,首先,需要在server安装Memcache,如何安装Memcache这不是本文的重点, 大约memcache安装,谁的朋友有兴趣,请参阅这里:http://blog.c ...
- C++ Primer 学习笔记_35_STL实践与分析(9)--map种类(在)
STL实践与分析 --map类型(上) 引: map是键-值对的集合. map类型通常能够理解为关联数组:能够通过使用键作为下标来获取一个值,正如内置数组类型一样:而关联的本质在于元素的值与某个特定的 ...
- HDU 4359 Easy Tree DP? 带权二叉树的构造方法 dp
题意: 给定n deep 1.构造一个n个节点的带权树,且最大深度为deep,每一个节点最多仅仅能有2个儿子 2.每一个节点的值为2^0, 2^1 ··· 2^(n-1) 随意两个节点值不能同样 3 ...
- EJB(一)认识ejb
什么是ejb? 相同仍旧在这个系列博客之处,谈谈对ejb的认识和理解. sun微公司对于ejb的定义大体是这种,ejb是一套用于开发和部署分布式组件的的架构.採用ejb的架构应用能够是 ...