Big ball of Mud

Big ball of Mud

第一种死法:Big ball of Mud

架构里最常用的反面案例是 big ball of mud。很大程度上可以说打格子,把复杂的系统拆解成小格子是架构师最重要的工作。这个小格子有很多种名字,比如:组件,模块,子系统,库,bounded context林林种种。

但是仔细想想?为什么需要打这些格子?为什么要把一个进程干的活拆分出这么多进程去干?

一个东西打成多少个格子来做,不是受一种因素影响的。不同类型的应用,其面临的主要挑战是不同的,所以上面三种因素里对解决方案的影响的权重就不同。

比如说:如果我们做的是微信的架构。微信的主要架构问题是什么?其实是给海量低价值的用户情况下提供免费服务。微信的后台架构里决定因素的是成本,所以在腾讯的后台业务里决定架构师能否做得好,主导的是对计算机体系架构是否足够精通。微信的kv存储能够做到同城三园区容灾,同时比竞争对手少一分备份达到同样的数据安全性,这就是核心竞争力之一。在海量但是业务逻辑简单的系统里,主要要考虑是怎样打格子可以最大化利用现代计算机体系架构。也就是这些格式主要是为了非功能性需求切分出来的。一个进程挂了就挂了,三个进程负载均衡就可以做到很高的可用性。一个流程写在一个函数内,一次执行需要很长时间,并发来跑可能需要很多进程。但是考虑SEDA的因素,可能把一个流程切成三个函数来写,每个函数独立成不同的线程或者进程来并发可以获得更好的总并发性能。等等这些,切分的模块的时候考虑的是内核,cache友好,网卡带宽,copy-less这些因素。如果我们做的业务是海量的简单逻辑的互联网业务,不精通Linux内核,TCP/IP协议栈和算法与数据结构是无法做一个好的架构师,打好格子做出高性能低成本的架构的。这个方面的架构师的典型代表是:Google 的 Jeff Dean,以及 Map/reduce Spanner 为代表的经典分布式架构。

但是系统是多种多样的。除了海量简单逻辑的业务,世界的另外一端是业务极端复杂但是使用量并不大的架构,比如典型的企业流程自动化系统。在处理复杂业务的时候,业务架构就是主要的影响因素。什么是业务架构?比如说电子商务要处理真实世界的商品交易流程,就需要把系统与真实世界的业务边界对应起来。一个电子商务系统需要拆分成“库存管理系统”,“定价系统”,“商品目录系统”等等。这种拆分不是因为架构师精通红黑树,认为这几个模块的数据结构不一样必须分开,而是不这么分的业务复杂度无法控制。越是架构做得好的系统,其子系统越是可以写得简单,因为每个都只处理一个领域的业务逻辑,而不是把不同的业务逻辑交织地扯在一块来写。决定系统的架构必须跟着业务架构走的根本原因在于普通人的脑容量是有限,不分治之,复杂度根本hold不住。这个方面的架构师典型代表是:Eric Evan 和 Udi Dahan,以及他们代表的领域驱动设计思想。

世界是多样的,很多事情不是在台面上的。摆在台面上的拆分系统的理由往往是业务逻辑,性能与稳定性等等。实际上真正主宰一个系统的模块怎么拆分的其实是组织架构。如果开发者向同一个管理40人左右的leader汇报,那么这些命运紧密相关的人(从年终奖的角度)无论写的系统是什么很难不紧密耦合,如果两个leader带的团队共同参与一个项目开发,很难去阻止他们把工作拆成两个模块来写,中间再各自加一道隔离层来保护自己。要是哪天这哪个团队合了,或许他们做的第一件事情就是把两个模块给合回去,名义可能是这样开发效率更高。这个现象叫Conway‘s Law,最有名的架构师是:James Coplien,以及他所撰写的Organization Patterns(http://orgpatterns.wikispaces.com/BookOutline

big ball of mud的系统有三种死法:

  • 因为性能和稳定性不满足要求而死,这个时候需要懂内核懂数据结构的架构师来好好做一下拆分。
  • 因为业务逻辑复杂得hold不住而死,开发效率慢到爆,这个时候需要做过复杂业务的架构师来重新梳理一下模块拆分。
  • 因为软件架构不符合组织架构,导致团队间吵架吵到死的,这个时候老板重新思考什么样的组织架构才是合适的(大boss通过组织架构体现其才是最终极的一切的架构师)。

如果一个系统兼具三个难点,简直难到爆:首先对延迟及其敏感,需要超级懂计算机体系的人。其次业务逻辑很复杂,需要很强的建模能力。同时又开发工作量巨大,需要很多人参与从而引入各种政治问题。金融衍生品交易等领域可能符合这些特征。假如微信的架构师来做办公自动化系统,上来就搞共享内存和高性能队列,我只能呵呵了。

第二种死法:Dependency Hell or RPC Hell

这是淘宝的某个人写的ppt的截图。QZone的后台其实也差不多。互联网现在解决big ball of mud的所谓最佳实践就是“微服务”。把一个大的系统拆成小的服务,用RPC一级级连接起来。A调用B,B再调用C。一个用户的请求要经过n个团队的系统转一圈出来。现在干什么事情都要讲求资历,而资历往往又和业务成功是挂钩的。淘宝的业务牛x了,意味着其架构就是完美无缺的么?当然我没有身披某某大公司技术副总裁的光环,而自动具有资格来评价这个问题。但是仅仅从一些技术细节的狭窄视角来看,这个架构也是有很多问题的,我称之为dependency hell:

1、从业务解耦的角度来看:RPC与共享数据库没有本质区别,拆开之后两个系统仍然是强依赖

这很糟糕

但是改成这样就真的更好了么?服务C和DB没有什么本质区别。

2、从非功能需求的角度。RPC依赖双方是绑死的。多次RPC调用叠加的可用性是叠加下降的,每个点都要保证自己的高可用,这对基础设施(运维自动化,集群管控)提出了很高的要求。而且对升级的依赖关系造成了很大挑战,哪个升级会影响哪个。同时对于容量规划简直是灾难,谁都不知道一个服务降级之后对其他所有依赖的方的雪崩效应到底是如何的。像QZone为了理解自己的后台服务架构到底是怎样互相依赖的,已经开始用上网络抓包的手段了,因为已经没有人知道这个网状的关系到底是怎样的了。从一个具体的技术细节来看,RPC调用需要主调方保留上下文的context在内存中(以及tcp socket),下游相应越慢对上游保留context的压力就越大。当然这一切都可以通过加机器,更好的负载均衡,更好的高可用机制来弥补。无非就是请几个高工来做集群管理系统,再加上机器和带宽费用嘛。大部分互联网公司的估值不是因为这个公司如何能节省成本,而是如何能花钱。所以非功能性需求不是决定性因素。

3、从组织架构的角度,要想获得最大的效率,必须要团队自治。RPC Hell的后果是每个团队都与其他团队紧耦合了。做个小功能,也需要拉一个跨组织架构的虚拟团队来协调接口。每个开发者脱离了所谓的那个线下环境就无法开发了,每个功能都有n个rpc call别人的系统,而别人的系统当然是我们自己搭不起来的。因为你去搭A系统的时候就会发现依赖B系统,B系统依赖C系统。在没有很好的基础设施支撑的情况下,比如分布式日志收集,docker的开发环境管理。开发者在这个微服务架构下是欲死欲仙的,干什么都是联调。每个人都对别的团队做阻塞的call,体现出来是日常开发也是阻塞的。老板为了提高整体开发团队的产出,就是加线程的方式,招更多的人。而招更多人为了职级晋升又需要把组织架构划分得更加的细。这个和网络异步编程的原理其实是一样的。

其实在我看来,这种RPC的解法的来源应该是来自于这个循环:

需求做不完=>那么加人吧=>加人没有坑,那么加坑吧=>我是leader我做主,咱们拆分模块吧=>模块拆分哪家强,RPC谁都懂,那就上吧=>继续循环

RPC可能不是最优的解法

诚然,BAT都是RPC嵌套的解法。诚然,我也不是什么专家。但是拆分子系统显然不是只有RPC一途,Event Driven的架构其实历史同样悠久。

具体的做法三言两语讲不清楚。最好有实际的案例。这里有两个非常具体的案例:

电子商务的案例:http://pan.baidu.com/s/1i3o6J7f

医疗记录的案例:http://pan.baidu.com/s/1c05BXLm

http://www.cnblogs.com/taowen/p/4887824.html

时间: 2024-10-12 16:08:07

Big ball of Mud的相关文章

Introduction to Microservices

原文出自:http://nginx.com/blog/introduction-to-microservices .我在其中加入了简单的翻译和自己的一些看法.  This is a guest post by Chris Richardson. Chris is the founder of the original CloudFoundry.com, an early Java PaaS (Platform-as-a-Service) for Amazon EC2. He now consul

个人阅读作业7

一.No Silver Bullet - Essence and Accidents of Software Engineering-Brooks 二.There Is a Silver Bullet – Brad J Cox 三.big ball of mud 四.CatB – Cathedral and the Bazaar 五.Lost in CatB. 六.Worse is Better – Richard Gabriel 七.Managing the development of la

软工个人博客-week7

Part 1       No Silver Bullet - Essence and Accidents of Software Engineering软件工程中没用通用的方法或者技术让软件工程在短时间内快速进步,这一点其实我也没有很明确的概念.其实近几年的敏捷开发框架,mvc结构,rest风格,这些的出现都大大提高了软件工程的效率,在我看来银弹的出现也是不无可能,毕竟单纯一个rest风格结合html5,给我的感觉让开发效率提高了起码百分之三十.Part 2 big ball of mud你的

开发体验心得总结

开发体验心得总结 Part One 阅读总结 [No Silver Bullet: Essence and Accidents of Software Engineering] 本文介绍了软件开发的要点以及开发过程中将碰到的问题,目的在于说明在软件开发中没有“银弹”,也就是没有解决一切问题的绝对武器. [There Is a Silver Bullet] [Big Ball of Mud]

学习领域驱动设计(二)之上下文映射图及架构

前一篇文章 :"学习领域驱动设计开篇"给大家主要了解了下领域驱动设计是什么!这篇文章主要介绍下上下文映射图及架构相关方面的知识. 1.上下文映射图 1.1上下文映射图为何如此重要 当项目中开始采用DDD时,首先你应该为当前的项目绘制一个上下文映射图,该图主要描述当前项目中的限界上下文之间的集成关系!而上下文映射图的作用就是帮助我们从解决方案空间的角度来看待问题.(限界上下文已在上篇文章中介绍了) U表示上游(Upstream).D表示下游(Downstream) 1.2绘制上下文映射图

软件工程的瀑布, 大泥球, 教堂,集市,和银弹

0x1 No Silver Bullet 1           There is no royal road, but there is a road 软件工程缺乏一剂良药,在硬件成本随着发展速度快速下降的同时,软件工程的成本并没有出现明显的下降,然而,随着软件工程持续的.坚持不懈的发展,软件工程正在发生着重量级的变化. 2           Does It Have to Be Hard?--Essential Difficulties 必须观察到异常不是软件进展如此缓慢,而是计算机硬件进

软件工程个人阅读作业2

转眼到了第九周,软工也过半了,老师要求阅读文章并根据自身体会写一下阅读感受,我只读了前三篇,以下是文章大意和个人的一些体会. 文章一: No Silver Bullet: Essence and Accidents of Software Engineering 文章大意:软件工程发展到现在遇到了很多问题:复杂性.整合性.易变性和不可视性这几点是软件工程开发所面临的本质问题.为了解决这些问题,人们使用了很多方法:高级语言.分时系统和统一编程环境,然而这些都没办法解决本质问题,只是从一些程度上减少

阅读作业2

我同学讲的一句话让我觉得非常好.我的团队是一个7人的团队.那么团队能达到的效果应该是1*7而不是1/7.大三是一个关键时刻,当这种软工团队作业要对分数比重进行分配的时候,很容易会有这样的情况.这是我看了第二篇“Big Ball of Mud”之后,首先引发的感想,其次,这篇文章中,对所要完成的任务进行的架构也显得尤其重要,否则就会变成文章中所说的“一团mud”:这让我回顾到大一最开始学习C语言的时候,晏海华老师告诉我们的,调试一个程序实际上比写一个程序更能锻炼人,因为调试一个程序是在全局的角度看

阅读作业中软件开发书籍阅读后的一些体会

No Silver Bullet: Essence and Accidents of Software Engineering(Frederick P. Brooks, Jr.) 在这篇文章中,作者将内容分成了三大部分,第一部分介绍了软件开发中根本的——软件特性中固有的困难,而这些困难是:软件实体的复杂性.软件和其它接口的一致性.软件实体的可变性以及软甲本身的不可见性.这是这些根本的特性导致了软件开发的困难. 第二部分讲了次要的——出现在目前生产上的那些困难.作者列举了软件领域中取得的最富有成效