我在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. 玩转Web之Json(二)----jquery easy ui + Ajax +Json+SQL实现前后台数据交互

    最近在学Json,在网上也找过一些资料,觉得有点乱,在这里,我以easy ui的登录界面为例来说一下怎样用Json实现前后台的数据交互 使用Json,首先需要导入一些jar包,这些资源可以在网上下载到 ...

  2. hdu 5091 Beam Cannon(扫描线段树)

    题目链接:hdu 5091 Beam Cannon 题目大意:给定N个点,如今要有一个W∗H的矩形,问说最多能圈住多少个点. 解题思路:线段的扫描线,如果有点(x,y),那么(x,y)~(x+W,y+ ...

  3. Java Enum使用演示样品枚举

    package cn.edu.shu.web.util; /** * * <p> * ClassName FileType * </p> * <p> * Descr ...

  4. Hadoop之—— CentOS Warning: $HADOOP_HOME is deprecated解

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46389499 启动Hadoop时报了一个警告信息.我安装的Hadoop版本号是ha ...

  5. java流的性能优化1-文件复制

    传统的I/O速度相对照较慢,它会成为系统性能的瓶颈,所以在java1.4之后提供了NIO,它是一种全新的流:它具有下面特性: 1.为全部的原是类型提供Buffer缓存支持: 2.使用java.nio. ...

  6. php 二维数组传递给 js 问题解决记录

    需求: php从数据库中读取到二维数组.传递到js中 实现步骤: php:json_encode  →   json  →  js:eval 即在php中使用json_encode()将php的二维数 ...

  7. hdu4496 D-City(扭转和支票托收啊 )

    主题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4496 D-City Problem Description Luxer is a really bad ...

  8. Ping azure

    最近azure在虚拟机上打开(欧式世纪互联),这其实并不能ping虚拟机! 查了一下资料,发现azure不支持被ping这个功能(貌似是不开放ICMP-in这个协议).有些用户跟客服问过这个问题,可是 ...

  9. RH253读书笔记(7)-Lab 7 Electronic Mail

    Lab 7 Electronic Mail Goal: To build common skills with MTA configuration Estimated Duration: 90 min ...

  10. STL源代码分析 集装箱 stl_set.h

    本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie set ------------------------------------------ ...