我在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 ...
随机推荐
- android 上手维修设备和推断启动服务
下载链接:http://download.csdn.net/detail/a123demi/7511823 我们经常在开发的时候,通过获取系统已启动的服务来推断该server是否还须要再启动. 而本文 ...
- Python计算&绘图——曲线拟合问题(转)
题目来自老师的课后作业,如下所示.很多地方应该可以直接调用函数,但是初学Python,对里面的函数还不是很了解,顺便带着学习的态度,尽量自己动手code. 测试版代码,里面带有很多注释和测试代码: # ...
- 允许debian wheezy支持IOS7+的iphone.
IOS更新, 连接到数据线,不能使用 我想复制iphone照片只能用于内itunes对? 于linux这里面其实很容易处理. 在这里,我们使用了一个相对较新的组件libimobiledevice 为 ...
- 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
文件夹 [SSH进阶之路]一步步重构容器实现Spring框架--从一个简单的容器開始(八) [SSH进阶之路]一步步重构容器实现Spring框架--解决容器对组件的"侵入 ...
- JAVA在IO流量汇总
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42119261 我想你对JAVA的IO流有所了解,平时使用的 ...
- Eclipse+超快速的模拟器Genymotion开展Android申请书(第一步:安装和配置Genymotion)
一.安装和配置Genymotion (1)因为Eclipse自带SDK模拟器,慢启动,别说 今天给大家介绍一个更快速的模拟器Genymotion (2)第一次去Genymotion在官方网站上注册一个 ...
- [Java Web]Struts2加起来(一个)
Struts2环境配置 进口Struts2的需要jar包 在WEB-INF/classes(src)文件夹下创建struts.xml文件 在web.xml文件里加入Struts过滤器信息 经常使用配置 ...
- C++四种类型的转换
在C/C++使用的语言 (type) value(您还可以使用type(value))对于显式类型转换,经常提到投.转换程序猿的精度等完全掌握手,一个传统投往往是过度使用.成为C++要根源. 为了降低 ...
- SERVERCONFIG
-- Create tablecreate table ERP_SERVERCONFIG( id NUMBER not null, servicename VARCHAR2(500), service ...
- Windows Phone 8 应用内截图
WriteableBitmap wb = new WriteableBitmap(this.LayoutRoot, new MatrixTransform()); //wb.Render(this.L ...