网络应用系统设计的基本原则

Posted on Fri 07 May 2010 in 我思

昨天和一个同事闲聊,说起了他近期在做的工作,一个信息聚合系统。在设计开发时没遇到什么问题,但到了真正部署,每次部署都会冒出之前没有想到的问题,使系统不能真正上线。听他讲完,我立刻想起了以前看过的ppt《Hadoop取舍之间──高性能、高流量和多数据中心互联网应用架构设计》中提到的一个重要原则:Design with failure in mind。当时和这个同事一起分享了这个原则和KISS原则。脑子里面又回想了另外几个和架构有关的原则。觉得对当前工作还是挺有意义的,应该和大家一块分享。

这篇ppt的作者信息,来自FreeWheel,这个ppt的原文请自己google吧,网上挺多的。

当时关心这篇文字,是对Hadoop感兴趣,不过这个ppt最后告诉大家,他们觉得Hadoop不适合自己,最后自己搞了一个类似的系统。这部分可以不看了,因为毕竟现在已经有很多公司成功部署了基于自己业务的Hadoop应用,每天好几个TB的数据都处理得很好。但本文前半部分提到的系统架构设计的六个原则,还是留下了很深的印象:

- 系统功能

KISS原则: keep it simple and stupid

从目前来看,最不符合这个原则的地方就是需求了。参加需求评审的时候,经常看到复杂度很高的功能点,比如决定是否给一个用户推送一条消息,需要和当前用户软件安装的信息、一个排除逻辑规则以及这条消息所属的类型三个变量相关。并且每个变量都是集合的概念,集合里面还有全集的概念。这样一个需求,实现起来需要花很大的代价不说,使用人员真的能够闹明白这些概念的关系,把逻辑配对了吗?如果出了问题,能够比较容易的发现吗?

在实现层面,有时也能够发现一些不够SS的地方,还可以通过重构改进。但需求复杂了,以后改进的代价就大了。

而到了设计评审的时候才发现的复杂地方,其实已经回天乏力了:需求方脑子里面已经形成定式了,非得这么干;开发人员也投入精力去设计了,再改张易调的代价也太大了。

所以我们开始强调,开发人员要把控需求,就是这个目的。在需求讨论期,就要小心的控制,避免需求的复杂化。这这个工作上,我们还有很长的路要走。

- 系统实现

容错原则:Design with failure in mind

因为没有无故障的软件 也没有无故障的硬件 ,所以,没有无故障的系统。

经验丰富的程序员开发时,总是很悲观的:对方请求如果没有及时传过来怎么办?传过来的格式不符合要求怎么办?网络连接超时了怎么办?就拿上面提到的聚合系统来说,如果你考虑到故障无处不在,那么代码的实现上一定会步步为营:先保证把对方的数据拿到,这里面要考虑网络异常甚至超时,完成的工作就是正确的取到了对方的数据;下个阶段就是分析拿来的数据,看看格式和约定是不是一样,是数据验证的阶段;接下来再做入库,也得考虑数据库异常什么的。这么实现的系统,才能有健壮性。

过犹不及原则:Just in time

  . 设计够用就好
  . 部分重构优于整体重构

和前面的KISS原则可以接合着一块用。另外8020原则也差不多是这个意思。

- 系统架构

数据拆分原则:Partition your data

  . 负载均衡
  . 容易继续拆
  . 减少依赖

月初出现了系统负载过高的问题,目前看本质原因是代码不够优化造成的,但这也给我们敲响了警种,数据拆分工作该做起来了。

对公司目前的负载均衡,从系统部拿到了参数。下一步需要接合Apache文档和代码级模拟,验证参数的合理性。希望摸索出效率更高的配置参数。

目前的分发服务和应用服务都还比较合理,而数据库拆分需要着手调研了。先从用户访问量最大且业务逻辑相对较简单的业务入手。

对依赖的降低,已经在着手进行了,第一个公共服务应用将在本月20日部署。

冗余原则:Redundancy

  . 减少单点故障
  . 系统能够自动恢复

监控原则:Monitor, monitor, monitor

  . 业务透明
  . 多角度:客户角度和系统角度