04 2010存档
我们的消息中间件,要在每个通信的机器上启一个daemon,负责转发。我们还为这个中间件开发了php接口(尽管我并不看好php,但它毕竟是前端的常用语言)。
在 处理业务部门反馈的问题时,发现一个奇特的现象:php程序通过中间件收发消息,设置是3ms超时,运行正常,没有超时的消息;但如果在php里加一个循 环(加循环的位置与中间件的调用无关),超时出现了。php自己傻循环怎么会影响中间件消息的response time呢?
先是怀疑我们的php module写得不对,参考了一下别人的代码,发现没有什么特别的,用的是极简单的php module API,如果这样写都不对,真不知道什么是对的了。
再 是怀疑php本身,于是换了几个php版本(php接口也要重新编译,累人),问题依然出现。再把我们的中间件API加入php的 basic_function里,即做为php的内置函数(就像split,sleep这些函数一样),问题还是一样。可能不是php的问题。
接着怀疑apache,于是降低apache的进程数,发现httpd进程数为1或2的时候真的没有超时了,但进程数如果多于3就不行。难道apache的调度有问题?我们默认用的是prefork任务模式,换成worker试试(参见这里),换mpm了,php给apache的so也要重新编译(还是累人),最后发现换成worker任务内模式当进程数多了还是一样超时。
难道和php、apache都没有关系?干脆启动两个独立的php进程,没有超时;启动3个,没有超时;启动4个,超时来了。看来4这个数字很神秘。最后猜测是机器乃4核CPU,4个php进程占完了4个CPU,中间件daemon就没有保障了。
这个猜测有点跳跃,要想办法证明之,于是想到了CPU affinity,我们用taskset把4个php进程都绑定到0,1,2三个CPU上,此时超时消失了。看来之前确实是php进程占了4个CPU,导致中间件daemon无法足够快的分配到CPU。
解决方案呢?
如果我改改daemon,是不是能解决这个问题?于是把daemon的优先级设为最高(RT),超时依旧。
仔 细想想有了个结论:daemon用的CPU并不多,但是其睡眠和唤醒非常频繁(daemon主要是IO操作,转发来自网络的包),当其从睡眠中醒来时,必 须很快分配给它一个CPU,但是php占了4个CPU,所以不能很快的给daemon,所以daemon出现了延时(睡过头了),造成消息超时。这大概能 说明为什么把daemon设成高优先级不能解决问题——优先级虽高,但终究是要睡的。
我的结论就是这样,最后的证明还是要看看内核代码了。未完待续。
看了“涂0实验室”的QCon 2010观后感,结尾的小故事很有趣。几个星期前我去Intel的软件大会,微软的一位工程师讲解新版VisualStudio的功能,还操作给我们看,我当时觉得那是大会最无聊的一个演讲,现在看来大家都有同感。
其 实推销也并没有什么不好,如果QCon上Redhat过来吹吹他们新的Rhel 6,我相信听众也会很高兴。所以事情的关键在于:微软的软件产品已经被互联网边缘化了。大家管理项目的时候用xplanner,不用 VisualStudio了;大家开发的时候用vim/emacs + gcc,不用VisualC++了;大家的服务器都用linux了,不用windows NT了(好像一直用的人也不多)。互联网公司用微软产品的估计是凤毛麟角。当然,也真有“凤毛”,比如MySpace就用.NET加windows服务器,不过facebook出现之后,估计很多人都早就忘了啥叫MySapce了,所以这里就不考虑他了。
那为什么MS这位软件业的霸主现在这么不讨互联网工程师的喜欢呢?因为在我们的眼里,动辄几百兆的软件已经是老掉牙的化石了:Office几百兆,可我用twiki或google docs不也够了吗?Outlook几百兆,可我只是收个邮件啊!VisualStudio更是臃肿,可我不过是想写几行代码跑跑而已......辛苦MS的销售经理了,要把过时的产品卖出去,也不容易。
另外声明一下,我并不是在鄙视微软,至少我觉得NT还是不错的,毕竟有David Cutler这样的高手为了NT费尽心血、妻离子散(参见《观止》)。但是还是那句老话——时代在发展——所以微软如果继续在各种大会上推销他的巨型软件,那将是越来越不讨好。
塔西佗为他的岳父写了《阿古利可拉传》,讲述了他岳父任不列颠总督期间的作为,既然是写岳父大人,难免很多溢美之词,着实让人肉麻(毕竟我们从小看夸赞类的书看多了,容易过敏),但里面有一段很让我惊奇:
阿古利可拉与不列颠人的反抗军有一场决战,决战前双方将领都有演讲,塔西佗详细的记述了不列颠首领的演讲。演讲里谴责了罗马军队的凶残——罗马人在不列颠烧杀抢掠,将孩子据为奴隶,虐待致死,于是不列颠人奋起反抗,如果放抗失败,大家就要么钉死在十字架要么成为奴隶,所以没有选择,一定要奋勇杀敌云云。然后是罗马将领阿古利克拉(岳父大人)讲话,这番讲话就是在拿帝国荣誉啊、战利品啊来了一番劝诱。之后双方开始对砍。
塔西佗是罗马人,而他在史书里却不替罗马帝国的暴行“遮丑”,相反,却流露出了对“蛮族”的同情,并借蛮族首领的演讲揭露了罗马帝国的凶残暴戾的“征服”。千年以来,这样的历史执笔者,又有几个?
1. read与recv
read和recv的语义有差别。read主要用来读文件,recv主要用来读socket,如果非要混用也可以,但有些细节就很磨人:
对着socket(异步的)调用read时,如果返回0,说明数据已经拿完了;而对这个socket调用recv时,如果返回0,说明该链接已经关闭了。
2. TCP_NODELAY
通常我们记得对于connect到server的socket设上TCP_NODELAY,却忘了accept出来的新socekt也需要设上TCP_NODELAY
周一去了一趟在长城饭店的“Intel软件技术大会”
坦率的说,长城饭店这种地方不适合办技术人员的会议,因为它透出一股自以为是的傲慢气,和技术人员朴素的气质不符——说虚了,说点实在的——先是保安问我们有没有请帖,我说不需要这东西,参会者打印注册码就行,于是保安一副不满的表情,好像用注册码就不够档次似的;再是卫生间里的保洁大叔也苦大仇深,不停对上厕所的人说:“把手擦干!不然地面弄湿了”,地面如果一直干着你还有这份工作吗?这长城饭店真牛,连上厕所的客人都要进行“教育”。如果大家谁要举办大会,尽量避开这个贵族饭店。
闲言少叙。
参会的有两百人左右,由TBB的带头人Jame Reinder先讲,大概说单序列的编程方式已经成为历史,未来属于“并行编程”(就是多线程或多进程),Intel提供的较为平滑的解决方案是使用Thread Builing Block库来帮助把单序列的程序“稍微改动一下”就变成可榨干多核CPU的“并行程序”。还举了个例子,图像处理软件maya就是使用了TBB以后,性能提高了7倍,当然,是在8核机器上。
记得《计算机程序设计艺术》的作者Knuth曾经鄙视过“并行编程“,觉得那是因为硬件厂商的无能,无法再完成摩尔定律的高要求,才把多个CPU压在一起卖,把麻烦丢给了软件开发人员。虽然Knuth大师的话很有道理,但是,做为一个默默无闻朝九晚五辛辛苦苦赚钱还贷的程序员,不可能像这位大师这样只是一味的抱怨,你的老板不可能因为“硬件厂商无能”而同意你继续写单线程程序,所以,不管怎样,还是学学并行编程,关注关注TBB吧。
TBB可是Intel的第一个开源软件喔。以前的那些编译器、调试器、优化工具不仅不开源,还老贵的哩!Intel也算是进步了,不枉我当年对他的鞭策。
之后是微软的一个人讲怎样用Visual Studio实现团队合作,这是最为乏味的部分,略去。
中场休息,喝牛奶、吃小薄饼。
然后是大唐的一个工程师讲他们的手机模拟设备在使用Intel的数学库以后性能大增,这个讲的不错,例子很生动,也很简洁。比那个微软的推销讲座好多了。
临走的时候填了反馈表,领了一本讲TBB的书。还不错。
互联网公司,多数的服务都是“一个请求,一个答复”模式,做一个这样的程序,然后启动过个实例,就把多核CPU用完了,不需要TBB来辅助。倒是网游公司里做图形客户端的可以用一用。
最后感谢一下唐勇,要不是他出差把名额给我,我还喝不上Intel的牛奶哩 ^_^