2012.06.01 星期五 多云
忙活了近兩个月的悲崔项目 cui 终于全部上线,一路跌跌撞撞,走得甚是辛苦.上线后 PM 陆继报一些样式方面的问题,无论如此,已经上线,算是对兩个月的劳动成果有一个交代.
项目上线了,不代表工作结束了.大型项目,更需要系统总结一下.我不知道别的同事会不会,或者有没有时间,或者有没有想法,来总结,反正我觉得非常有必要我自己先来一番:
简述: 和百度大搜索合作的阿拉丁导流项目,我开发的服务主要响应用户检索对音乐的需求,返回生成好的 HTML 或 XML 代码片段供百度结果在渲染页面时使用.由于百度的海量检索请求,他们要求我们的服务峰值能力达到 500q/s.我们交付上线的服务经 QA 同学压力测试,得出的性能指标为: 单机极限压力 1000q/s 时 CPU idle 在 50% 左右,基本上无法正常提供服务; 800q/s 时 CPU idle 80% 左右,服务能力正常.上线后在用户高峰时段,查看实时并发,大搜索真正过来的并发为 50q/s 左右. cui 从性能方面讲,无疑远超预期.
1. 项目名称.
项目名字一定要启好,哪怕不能响当当,不能惊心动魄,但绝不能再叫做 cui,明摆要成为一个悲崔的代表.否则,各种灵异现象,各种闻所末闻,见所末见的悲崔会不断给你带来意外的收获,不停的放大你发现问题,定位问题,解决问题的能力.
2. 技术选型.
很重要.一直在讲,没有最好的技术,只有更适合的场景.最开始,我们考虑要不要用 php 来实现,后来了解到大搜索那边使用的是 nshead + mc_pack 方式的网络通信,归根结底是 socket 通信,考虑到 php 的性能问题,以及以它来实现网络编程的不稳定性,我们最终选择了 C.后来的事实证明,我们当时的决择是英明的.如果当时采用 php 或 Python,八成要在性能那块卡死,那真要悲崔到底了.
3. 指针与内存.
C 语言玩的是指针,玩的是内存的分配与使用.第一版实现中,为了图快捷, cui 大量的栈上开辟临时缓冲区,几十K或几百K的开,高并发下常出现堆栈空间不足,不出 core 而服务自动退出,甚是郁闷.后继的优化中,我将能在堆上申请的内存全部放到初始化时从堆上开辟了.我们知道 malloc 系统调用是非常消耗资源的,应尽可能减少动态内存分配.所以通常我们的做法是初始化的时候一次 malloc 足够多的内存 pool,放着慢慢用. 实践证明,cui 的优化过程就是一个活生生的教科书式的案例.通过将临时缓存区放到线程空间,在程序启动的初始过程,为它他申请好足够的内存,一次 malloc 调用,重复利用,效果相当明显.nginx 大量使用了内存池技术, python 内存大户,也从侧面反映了其内存分配与管理的思想.相比之下 php 在内存使用方面受自身架构的影响,在一定程度制约了其性能.
4. 初始化的学问.
我们曾有多个项目遭遇过 memset 的性能问题.大块内存使用它来清 0 时候会耗用超乎想象的时间.大量的实战表明,对于字符型缓存区,如果已经确认对它进行操作的 API 会自行加 ’\0’,那没有必要全部清 0,初始化的时候仅清 0 首字节就可以了.对于数组型的大块内存,给它一个记数器,标记每次处理时使用多少个 item,初始化时也不用每次都整块内存清 0 了,仅清 0 必须的成员.读的时候判断一下记数器,万事大吉.
5. 超时.
再 NB 的后端服务也得设置合适的超时时间.在酷讯时候,有一次太自信后端服务了,将超时设置为永不超时,刚上线感觉良好,片刻之后,后端服务跨掉了.大搜索只给了 200 毫秒供我们处理一次用户请求,起先联调时发现丢包现象严重.联合排查后发现是由于响应用户请求时间过长,大量超过时的链接,大搜索认为 cui 服务不可用,主动关闭了链接.经过地毯式的排查,确定主要有兩个因素引起了处理时间过长:1).API 使用不正确,错误的将连接,读和写的超时设置成近乎永不超时;2) cui 和它的后端数据服务之间的超时也设置不当,造成了甚至花了 900 多毫秒才处理完一个请求的情况.这对于一个需要应对高并发的服务来讲简直是笑谈.再次敲响了超时不当的警钟:只要用网络交互,一定要设置适当的超时.
6. cache.
cache 绝对是高性能的必杀器,无论前端后端,加一层 cache,性能提升立竿见影. cui 最初设计的时候没有 cache 层,几轮压力测试下来发现,如果不加缓存想要扛到 500q/s 相当的吃力.后继的优化过程中加入 cache 机制,效果非常理想.拖延近一周的时间,全部精力都在寻找丢包与性能提升上面.虽然最终确定丢包一个非常重要的原因是由虚拟机本身造成的,但优化过程对服务的稳定性给予了有力的支持.
7. check list.
我觉得项目最大的败笔就是没有建立良好的 check list.原因很简单,大家都很忙.从一开始,我们的很多需求,策略,注意事项等等,都散列在各种各样的文档,以及讨论区中,从来没有人提出整理,或主动整理出供大家参考,抑或使用项目 WIKI 这样工具来大家协同工作,共同维护 check list.如此,上线了, PM 们开始陆继发现问题了.缀使 QA 同学再怎么给力捉虫,线上问题也无力回天.于是乎各种紧急修复,紧急流程纷纷上演.紧急流程通常是一个个悲剧的续幕,而更为悲崔的是,一个悲剧总会引发一连串的悲剧,蝴蝶效应真实上映,却没有彩排的机会.
项目总会有,成长是关键.
1 条评论:
赞总结
发表评论