全文共 24658 个字,建议阅读需 20 分钟
架构漫谈(一):什么是架构?
-
必须由人执行的工作(不需要人介入,就意味着不需要改造,也就不需要架构了) -
每个人的能力有限(每个人都有自己的强项,个人的产出受限于最短板,并且由于人的结构限制,同时只能专注于做好一件事情,比如虽然有两只眼睛,但是只能同时专注于一件事物,有两只手,无法同时做不同的事情。ps. 虽然有少部分人可以左手画圆右手画框,但是不是普遍现象) -
每个人的时间有限(为了减少时间的投入,必然会导致把工作分解出去,给擅长于这些工作的角色来完成,从而缩短时间) -
人对目标系统有更高的要求(如果满足于现状,也就不需要进行架构了) -
目标系统的复杂性使得单个人完成这个系统,满足条件2,3(如果个人就可以完成系统的提高,也不需要别的人参与,也就不需要架构的涉及,只是工匠,并且一般这个工作对时间的要求也不迫切。当足够熟练之后,也会有一定的架构思考,但考虑更多的是如何提高质量,提高个人的时间效率)
总结一下,什么是架构,就是:
-
根据要解决的问题,对目标系统的边界进行界定。
-
并对目标系统按某个原则的进行切分。切分的原则,要便于不同的角色,对切分出来的部分,并行或串行开展工作,一般并行才能减少时间。
-
并对这些切分出来的部分,设立沟通机制。
-
根据3,使得这些部分之间能够进行有机的联系,合并组装成为一个整体,完成目标系统的所有工作。
架构漫谈(二):认识概念是理解架构的基础
事实上,这些基础概念对于做架构是非常重要的,大部分人对于每天都习以为常的概念,都自以为明白了,但实际上都是下意识的,并不是主动的认识。比如说“什么是桌子?”,做培训的时候,我经常拿这个例子来问大家,回答千奇百怪。这实际上就导致了做架构的时候,不同角色的沟通会出很多问题,那么结果也就可想而知了。
架构漫谈(三):如何做好架构之识别问题
-
被告知要处理一个问题,但是交过来的实际上是一个解决方案,不是问题本身。 -
被告知要处理一个问题,直接通过直觉就有了一个解决方案,马上考虑解决方案如何落地,或者有几种解决方案,选哪个合适。
-
女主人提出一个问题,要切土豆下锅煮。 -
男主人有一个问题,女主人交代了自己必须要完成的一个任务。
-
女主人公提出的实际上是解决方案,而不是烧土豆这个问题本身。女主人当时执行这个解决方案可能有困难,就把执行解决方案作为一个任务,委托给了男主人。 -
男主人得到了一个任务,尽心尽职地把这个任务完成了。
-
这是谁的问题? -
有什么问题?
架构漫谈(四):如何做好架构之架构切分
-
某个或者某些利益相关人负载太重。 -
时间上的负载太重。 -
空间上的负载太重,本质上还是时间上的负载太重。 -
某个或者某些利益相关人的权利和义务不对等。
-
必须在连续时间内发生的一个活动,不能切分。比如孕妇怀孕,必须要10月怀胎,不能够切成10个人一个月完成。 -
切分出来的部分的负责人,对这个部分的权利和义务必须是对等的。比方说妈妈10月怀胎,妈妈有权利处置小孩的出生和抚养,同样也对小孩的出生和抚养负责。为什么必须是这样呢? 因为如果权利和义务是不对等的话,会伤害每个个体的利益,分出来执行的效率会比没有分出来还要低,实际上也损害了整体的利益,这违背了提升整体利益的初衷。 -
切分出来的部分,不应该超出一个自然人的负载。当然对于每个人的能力不同,负载能力也不一样,需要不断的根据实际情况调整,这实际上就是运营。 -
切分是内部活动,内部无任怎么切,对整个系统的外部应该是透明的。如果因为切分导致整个系统解决的问题发生了变化,那么这个变化不属于架构的活动。当然很多时候当我们把问题分析的比较清楚的时候,整个系统的边界会进一步的完善,这就会形成螺旋式的进化。但这不属于架构所应该解决的问题。进化的发生,也会导致新的架构的切分。
-
架构的切分的导火索是人的负载太重。 -
架构的切分实际就是对stakeholder的利益进行切分或合并,使得每个stakeholder的权责是对等的,每个stakeholder可以为自己的利益负责。 -
架构切分的最终结果都会体现在组织架构上,只有这样才能够让架构落地并推进。 -
架构切分的结果一定是一个树状,这也是为什么会产生分层。层数越多沟通越多,效率越低,分层要越少越好。尽可能变成一颗平衡树,才能让整个系统的效率最大化。
架构漫谈(五):什么是软件
架构漫谈(六):软件架构到底是要解决什么问题?
-
如何把现实生活用软件来模拟? -
模拟出来的软件,需要哪些硬件设施才能够满足要求?并且当访问量越来越大的时候,软件能否支持硬件慢慢长大,性能线性扩展? -
因为硬件是可能会失效的,软件如何在硬件失效的情况下,仍然能够保证可用性,让用户能够不中断的访问软件提供的服务? -
怎么收集软件产生的数据,为下一阶段的工作提供依据?
-
业务的owner需要提升业务的效率,降低业务的成本,这是动机。这个实际上就是业务的问题,所以一般软件开发的出发点就在这里。 -
是软件工程师的问题,要解决业务owner把业务虚拟化的问题,并且要解决软件开发和运营的生命周期的问题。
-
业务问题的本质,是业务所服务的对象的利益问题,明白了这个,就很容易搞清业务的概念和组织方式。再次强调一下,有了软件,可以降低业务的成本,没有软件的情况下,业务是一样跑的。如果只是为了跟风要用软件,说不定反而提高了成本,这个是采用软件之前首先要先搞清楚的。我们经常说软件和技术是业务的enabler,实际就是把原来成本很高的降到到了很低的程度而已,并不是有了什么新的业务。另外,软件也不是降低业务成本的唯一方式。 -
为了能够让软件很好的跑起来,软件工程师必须理解业务所服务的对象,他们的利益所在,即业务问题。业务面对这些问题是如何分拆解决的?涉及到了哪些概念?这些概念分别解决了哪些哪些问题?我们不能自己按照自己的理解,用自己的一套概念体系来表述。如果这么做的话,会导致两个问题:
1)业务无法和我们交流,因为他们无法明白我们所自己创建的概念,所以他们无法确认我们的理解是否正确。
2)我们所表述的东西,并没有在实际生活中实践过,我们也不知道这些概念是否能够解决业务的问题。 -
软件工程师还必须要考虑,用什么样的硬件把软件跑起来,怎样跑得好,跑得快,并且可以随着业务的流量逐渐的长大?
-
学习业务知识,认识业务所涉及的stakeholders的核心利益述求,以及业务是如何分拆满足这些利益诉求,并通过怎样的组织架构完成整个组织的核心利益的,以及业务运作的流程,涉及到哪些概念,有哪些权利和责任等。 -
通过对业务知识的学习,针对这些概念所对应的权利和责任以及组织架构,对业务进行建模,并把建模的结果用编程语言实现。这是业务的模型,通常是现实生活中利益斗争的结果,是非常稳定的。 -
学习业务所参与的stakeholder是如何和业务打交道,并完成每个人的权利和义务的,并通过编程语言,结合业务模型实现这些打交道的沟通通道。这部分是变化最频繁的,属于组合关系。明白了这一点,对后续的实现非常有帮助。 -
如何把业务运行的结果持久化,并通过合适的手段把持久化后的数据,在合适的时间合适的地点加载出来。这部分和基础设施有关,变化可能也会比较频繁。
-
需要多少硬件设备来满足访问的需求? -
代码要分成多少个组件部署到哪些硬件设备上? -
这些代码如何通过硬件设备互相连接在一起? -
当业务流量增大到超过一台机器的容量时,软件能否支持通过部署到新增机器上的方式,扩大对业务的支撑? -
当某台或某些硬件设备失效时,软件是否仍然能够不影响用户的访问。 -
软件运行产生的数据,能否支持提取出来并加以分析,为下一轮的业务决策提供依据。
-
完成一和二所列的这些事情,需要哪些角色参与? -
这些事情基本都需要顺序的发生,如何保证信息在不同角色的传递过程中不会有损失?或者说即使有损失,也能快速纠正? -
这些角色之间是如何协调,才能共同完成虚拟化业务的需求?
-
当流量越来越大,我们就会发现,软件所部属的机器就会开始按照树状的结构开始分拆,就会形成硬件的部属架构。这就是为什么会形成部署的分层。 -
为了把业务在软件中实现并落地,需要前端人员、业务代码人员、存储层等不同技巧的人同时工作,需要切分成代码的架构。这就是为什么会形成代码的分层,形成代码的架构。当然,当这些角色由一个人来完成的时候,不一定会有代码架构,往往会比较乱。 -
当参与的人员越来越多,就会形成开发体系的组织架构。因为代码开发的过程是一个连续的过程,会用流程来把不同的角色串联起来,这就是软件工程。 -
为了完成业务的工作,需要识别出来业务架构和支撑业务的组织架构,以及业务运作的流程。这是被虚拟化的业务架构和组织架构,也需要体现在代码中,保持和现实生活中一致。
-
软件因为流量增大而分拆成不同的运行单元,在不同的机器上部署所形成的架构,属于软件架构。 -
每个运行单元为了让不同角色的人,比如前端,业务,数据存储等能够并行工作,所分成的代码架构,也属于软件架构。
什么是架构师
架构漫谈(八):从架构的角度看如何写好代码
-
表达业务逻辑的代码。很多人把这部分叫做Domain Logic,或者叫Domain Model。这部分实际是来源于生活的,必须保持和现实生活中的切分一致,并非人为的抽象而成。 -
对用户提供访问并保存业务逻辑运行结果的代码。计算机的状态保存有一个缺陷,本机保留业务运行结果有很大的问题,一般都在外存储设备上保存,也便于扩展。
-
Service就专注于user的需求,并组合Glue Code提供的服务完成需求。 -
Glue Code专注于组合business的调用,管理Business里面对象的生命周期,并且通过Repository保存或加载Business的状态 -
Business专注于实现业务的核心模型。 -
Repository专注于数据的保存,并和存储设备一一对应。
-
如果service里面不是严格的顺序调用,有很多分支,那么说明这个service做了两件或者两件以上的事情。必须把这个service分拆,确保每个service只做一件事情。因为如果不这么分拆的话,一旦这个service中的某各部分发生变动,其他的部分的执行必定会受影响。而确定到底有哪些影响的沟通成本非常高,其他相关利益方没有动力去配合,我们往往不会投入精力仔细评估。最后上线会出很多不可预料的问题,最终会导致损失用户的利益,并且肯定会导致返工,损坏自己的利益。如果是有计算的逻辑的话,比如受益计算,订单金额计算等,那么这部分应该是Business代码需要完成的,不能交给service代码来实现。 -
Glue Code里面如果不是严格的顺序调用,同理会和service一样遇到同样的问题。 -
Repository里面如果不是严格的顺序调用,包括存储访问的代码里面(比如SQL),会导致逻辑进入到存储设备中。存储设备的主要目的是拿来存储的,一旦变成了逻辑计算的主体,就会导致存储设备无法通过增加机器的方式横向扩展长大。这个时候就没有架构了,只能换性能更好的机器,这个叫scale up。只有scale out才能算架构。
-
Service、Glue Code、Repository里面的代码是严格的顺序调用,那么这些代码只要做连通性测试即可,不需要单元测试。因为这些代码都需要和很多上下文打交道,很难做单元测试。这样才算是真正的组合。 -
Business不访问任何上下文,不访问任何具体的设备,所以这部分代码是非常容易写单元测试的,并且单元测试必须100%覆盖。因为其他地方没有业务逻辑,所以一旦有问题,就可以断定是Model的问题,单元测试肯定可以发现。如果单元测试没有发现问题,那么单元测试一定有问题。线上问题的模拟也就变得非常的简单,单元测试也能够得到进一步的补充。 -
Repository很容易按照存储设备本身的最小访问粒度来完成工作,比如DB,完全可以做到单表访问。因为这个时候存储设备只关心存取数据,完全和业务没有关系。做表的分拆也是非常容易的事情,存储设备通过增加机器就可以横向扩展长大。很多人会担心说,没有了join,访问DB的次数是不是更多了,会导致性能下降?按照现在网络的条件,网络访问和Disk IO访问的差距已经不大了,合理的设计下,多访问几次DB并不会导致这个问题。另外如果多台DB的话,还能通过并行加速访问。 -
由于Service、Glue Code、Repository代码简单了,才可以让我们的开发人员投入更多的时间研究业务,毕竟这部分才是软件所真正服务的对象。
-
不能把Business Model当做数据对象来处理,Model关心的实际上是业务行为,数据只是是这些行为的结果。所以Glue Code需要把Model转换为Entity,Entity和存储设备里面的存储粒度一一对应。比如在DB中,每个Entity对应一张表,并且跟着表的变化而变化,这样就保证存储的变更不会影响Model。同样Service和用户之间的数据交互,也是不会和Model之间相关的,确保用户的需求变化,不会影响到Model。因为用户的需求变化是最频繁的,没有逻辑,可以让我快速的满足业务的需求。 -
在Service这里,最好不要考虑代码重用。因为当多个不同的角色访问同一个接口,一旦某个角色的需求发生了变化,就会要求开发人员去修改。而这个修改往往会影响到其他的角色,需要这些角色一起配合来确定是否受影响,但是这些角色因为没有需求,往往不会配合。这样就给开发人员造成了很多不必要的沟通,成本是非常高的。最终都会导致线上Bug,影响最终的用户。所以尽量给不同的角色不同的Service,避免重用,降低沟通成本。很多人会说这样Service不就太多了吗?这样Service注册,查找等管理需求就出现了,Service治理中心就是来解决这个问题的。因为Service里面没有逻辑,所以开发和管理非常的简单,可以快速应对业务的变化。我们只有更快地变,更容易的变,才能更好地应对变。 -
Business Model是必须要重用的,一旦发现重用出现问题,那么说明Business Model的识别出现了问题,这是一个我们要重新思考Model的信号。Business Model必须是一个完美的树状,如果不是,也说明Model的识别出了问题。
架构漫谈(九):理清技术、业务和架构的关系
-
业务目标是为了取火,钻木取火这个技术的出现解决了这个问题。 -
钻木取火的效率不高,影响了业务(取火)的效率,就有了进一步改进的动机,改进转动木棍的方式,产生了弓弦转动木棍的技术。
-
技术是为了解决业务的问题而产生的,没有了业务,技术就没有了存在的前提。 -
有了更好的技术,效率更差的技术,就会慢慢的被淘汰,消失,一切都遵从人类的利益诉求——也就是业务。有人会问,不用钻木取火了,但是弓弦加速转动木棍还可以用啊?没错,因为弓弦转动木棍这个技术,不是来生火的,是用来加速木棍转动的,所解决的问题不一样。但是两种不同的技术,合理结合起来,会更好更有效率的解决业务问题。
-
在解决同一个业务问题的前提下,更高效,更低成本的技术,会淘汰低效,高成本的技术。这是人类利益诉求所决定的。 -
一般刚开始解决根本问题的技术(钻木取火)的效率是比较低的,只是把不可能变成了可能(从这一点上来说,技术才是业务的enabler)。然后就会有提高效率的需求出现,要求改进这个技术。这个技术的低效率部分就会被其他人(或者技术发明人自己)加以改进,这部分就会形成新的技术。
-
当技术所解决的问题和分拆出来要解决的问题,完全匹配的时候,这是最完美的。比如需要提供web要访问的service,很多MVC的framework就可以很好的满足这一点。而这个时候如果非要自己实现一个,很有可能就是重新发明轮子。 -
当技术所提供的能力远远超过需要解决的问题时,往往掌握技术和维护技术会成为瓶颈。因为越复杂的技术,成本越高。如果自己实现一个仅仅是解决当前问题的方案,可能成本反而更低。这也是为什么很多大型的互联网公司不断地开源出来自己的技术的原因。而这些技术对于我们来说是否适用?他们原本是用来解决谁的问题的?什么问题?如果不清楚这些,就冒然采用,可能会导致更高的成本。 -
当技术所提供的能力和我们所要解决的问题部分匹配时,还是要看成本。比如当我们需要一个锤子的时候,手边正好没有,但是却有一只高跟鞋,勉强也可以替代锤子。但是长期来看,这么用不划算,因为高跟鞋的价格比锤子高很多,耐用性差很多,维护成本也高很多。 所以,准确识别采用什么技术的能力,也是架构师所要具备的能力之一。考虑的主要因素也是长期的成本和收益。
原文始发于微信公众号(谈数据):架构漫谈:从冯诺依曼结构到成本收益!
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论