Back to home

一个优秀的系统会具备哪些特征

Edit

一个优秀的系统会具备哪些特征

前言

关于如何才是一个优秀的系统,其实个人有个人的看法,每个人也有每个人的道理,只是最近和组里的同学在一起讨论怎样才算一个良好的系统设计,大家讨论出了一些点,我将其中的一些点整理成blog。一家之言,与偏好有关,欢迎讨论。

系统设计往往跟具体的业务场景是紧密相联的。所以抛开业务场景,谈系统设计没有太多的实践意义。所以 how to 的事情也并不是本文的重点。但是剥离业务场景,在优秀的系统中总能抽出一些共性的特征,虽然这些特征无法像一个 todo 清单 list 一样教你如何一步一步得去做,但是却可以在我们大脑中建立一种意识,说得装 b 点叫系统设计哲学,以便后续在具体业务设计中能够有意识的往优秀系统设计方向靠拢,然后在大框架下逐步摸索出自己的方法论和自己的结合业务场景的 how to do。我想这就是本文要讨论的主题的意义。 下面就开始讨论一些具体的特征。

保持简单

简单是一个优秀的系统应该具备的最基本的特征,其他很多的特征也是因为简单而来。简单不仅要求接口简单,还要求实现简单。一个简单的系统,是易于理解的,是不容易出错的,是符合人的本性认知的。是小和轻量化的。对于这样的系统,具有天然的可维护性。因为大家一看就懂,一看就能上手。所有优秀的系统应该都是简单的,如果不够简单,就说明不够优秀。优秀设计的本质在于利于大脑的吸收,当一个设计能够很容易了解时,它就足够优秀。
尤其是在互联网行业,一个服务可能需要成百上千个子系统的支持,如果不能使每个系统足够简单,那整体的复杂性就会大大提高,迭代效率就会严重拖慢,这是不可接受的。所以,一个服务量级的提升,就对于系统的简单有了更高的要求。复杂度的控制,是软件工程中永恒的话题。

良好的运维性

一个优秀的系统必须是可以良好运维的。一个系统(如果最终可以上线,夭折的不算),在他的整个生命周期之内,最长的时间就是在生产环境中,所以无疑运维性问题是他最重要的问题。良好的运维性,可以提高整个团队的效率。那什么样的才算有良好的运维性。
(1)他是可视化的
一个好的系统,必须是可视化的,这个可视化,指得是他的运维状态。这里包含了当前的性能,当前的访问量,当前的异常量,包括各个环节的异常量,所有能够可视化的状态都应该可视化,这样才能够时刻掌握系统的状态,并且在系统异常时,能够及时准确的定位问题。
(2)他是可以方便扩容的
只有一个方便随时扩容的系统才能跟得上互联网的节奏。一个良好的系统,应该是随时可以扩容的。这就需要开发者尽量使系统无状态,尽量让最复杂的逻辑在系统的无状态端实现。这样可以充分借用扩容的优势降低系统复杂度。另外他应该是方便部署的。
(3)他是可以容灾的
每个系统应该都要拥抱失败,即使是在条件最恶劣的情况下能够尽可能提供服务。这就要求系统开发者对于哪些是系统的必要功能、哪些是系统的辅助功能非常清晰。在异常时刻,可以尽量服务,只提供最核心的服务(降级)或者只为一部分用户提供完整服务(限流)。

解决最主要的问题

系统的本质是要解决问题,但不是要解决所有问题。一个良好的系统,不会解决全部的问题,因为这势必增加系统的复杂度,优秀的系统,只解决最重要的问题。剩下的问题,交由其他系统解决或者交由下一个版本解决。这其实也是一个复杂度问题,人脑的短时效容量和关注度是有限的,如果关注了太多的问题,精力分散,就容易导致本该解决的问题解决不了。先把最主要的问题解决,先上线,下一个版本中才是优化、改进。

可进化的

不设计一劳永逸的系统,因为这是不现实的。我们不是上帝,技术的迭代取决于产品,而产品的迭代取决于用户,谁都不知道下一刻用户会喜欢什么,产品会往哪个方向发展。我们能够做的,就是让这个系统具备良好的进化能力。一个良好的系统应该是方便进化的,并随时做好可重构的准备。使进化成本降低到最小。比如无状态的系统相对于有状态的系统就更加容易进化,存储不方便进化,但逻辑就容易进化。大部分的系统是有状态的,所以就要求系统设计者在设计系统时,将迭代效率作为一个高优考虑因素,结合业务去考虑应该存储什么样的状态才能尽量不影响后续的迭代。

可组合的

一个良好的系统,应该是可以产生杠杆效应的。就是可以通过方便得和其他系统的组合,产生更大的价值。这里有一个最好的例子就是 shell 命令。每个 shell 都足够简单,功能单一,但如果通过管道将 shell 组合起来,确是能够无所不能。这是杠杆效应最好的例子。一个良好的系统,是应该可以和其他良好的系统组合使用的。当然,这首先要要求这个系统是简单的。只有达到足够简单,才可以更加方便的和其他系统组合。

尽量异步

异步是一种非常良好的解耦方式,有了异步,才有了真正的解耦。一个良好的系统会尽可能多用 event-driven 这种形式。这一点不多谈。

恰当 cache

一个良好的系统,一定是把 cache 用的恰到好处的系统。这里面包含了知道何时使用 cache 和 cache what。

使用了解的技术

这一点并不是强调不欢迎新技术。新技术需要持续探索,而我更加强调的是一个投入产出比。在互联网发展的最近10年,工程界的基本模型几乎没有改变,拿存储举例,无非就是关系模型、文档模型、图模型。所以技术间没有太明确的对比优势。在生产环境上,为了更大程度提高稳定性、可运维性,使用我们了解的技术会让整体性价比更高。而如果想用新技术,那就做好充分的调研,达到理解的程度之后再使用。使用了解的技术,不仅是自己了解,自己可以更方便的解决问题,更重要的是整个团队更了解,可以更好的使用合力。

尽可能在平台之上构建

如果公司有相应的基础服务、基础平台,那良好的系统应该尽可能的在公司的服务、平台之上构建。当然这需要是已成型的稳健的基础服务和基础平台。一来可以方便得使用公司的合力,另一方面,使用公司的平台,可以增加你系统的影响力。

后记

这不是一篇教你 how to do 的 blog,更多的是 what to do。上述的特征更多的是对于优秀系统的归纳总结,但具体如何去实现、如何做到,就像前言说的一样还需要每个人进一步去探索去摸索。就好像我们对一个优秀的人的特征归纳为靠谱,他究竟如何做到靠谱,每个人有每个人的做法。系统设计不是一个绝对对与错的话题。还需要我们在日常系统生活中不断思考不断总结。