周末阅读了下陈硕老师的分布式系统的工程化开发方法,原地址连接请猛击这里(blog, 视频),也将blog上的一页页演讲稿整理成了pdf借花献佛一下,点击这里下载。

在阅读完陈硕老师的演讲稿以及相关视频后,回顾了下自己工作一年来碰到的一些问题,梳理下一些设计中需要考虑的点。与陈硕老师的题目不同,这里主要针对大型互联网后台程序,存在模块间的交互,但部署同一个服务模块的不同机器之间的状态是一致的,因此不讨论分布式系统中常见一致性、通信、选举等问题。

  • Design for failure —— 大型互联网的后端服务是7*24 online service的,因此当出现异常时(单个或者多个节点异常,必须在尽可能保证服务的前提下,尽快恢复)
  • 能重启、快速重启 —— 一个服务启动的速度对该模块的日常更新,以及异常情况下的快速恢复有着决定性的作用,在开发时应该尽可能的缩短启动的时间,在完成必须启动和加载的相关配置后,优先提供服务。此外陈硕老师提到的优雅重启,也是需要考虑的问题,尽可能的减少停止服务重启时刻对现在正在service的请求造成的影响。
  • 避免阻塞 —— 对于多个模块通过tcp交互的场景,如果某个模块的工作线程被阻塞,则会导致上游不断的超时,甚至请求堆积到被阻塞的模块,因此需要尽可能的减少阻塞。可以通过设置合理的超时时间,调高工作线程数等方式。
  • 监控 —— 对于7*24 online的service尤为重要,最好能全方位的提供一个方便的探测当前模块服务状态的接口,unix文件系统都会预留proc这样的接口,可以观察正在运行的进程状态。这里的探测不仅仅包括常用的硬件如CPU、内存、网卡、句柄等探测,甚至包含与上下游交互的健康状态,以及其他业务相关的信息。
  • 操纵性 —— 除了监控,对于自己写的online service,在上线服务后,应该具备一定的可操控能力,例如运行时改变一些行为状态,避免异常时只能选择回滚。对于一些关键的功能点,应该有一些可运行时reload的开关控制,在特殊情况时进行操作。
  • 分步升级 —— 多个模块不可能同时升级,如果涉及接口的变动,采用C buffer传递字节信息会造成接口不兼容的依赖,考虑idl/protocol buffer。

————————分割线——————————扯点其他的————————————

在陈硕老师的PPT中提到了在epoll的水平触发(LT)方式下,accept返回EMFILE时的异常问题解决,自己实验了下,并没有持续返回可读,通过tcpdump查看,发现accept失败后,系统发送了FIN包主动断开的连接,怀疑与linux内核版本有关。可以查看下面tcpdump的数据。

阅读全文…

,