关于架构的一些理念

Posted q__y__L

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于架构的一些理念相关的知识,希望对你有一定的参考价值。

1.架构是进化而来的

        罗马不是一天建成的,大公司的复杂架构也不是一蹴而就的,而是从简单到复杂演变、进化而来的。以淘宝为例,它的第一个版本是几名开发人员用了一个月的时间给予一个php版拍卖网改造而来的,上线时淘宝只有一台web服务器和一台数据库服务器。在淘宝近20年的发展中,随着网络的访问量越来越大,功能越来越多,淘宝网才逐渐演变成现在这样复杂的架构。现在很多网站开发第一版的时候就以“上亿访问,百万并发量”为架构设计目标,导致项目迟迟无法交付,研发成本高昂,好不容易开发完成了,但是由于项目交付延迟,公司已经错过了绝佳的市场机会,最后导致项目失败。

        按照“精益创业”的理念,我们应该用最低的成本,最短的时间开发一个“量小的可行性产品”,然后把产品投入市场,根据市场的反馈再进行产品的升级。经过IT行业的发展,我们现在已经可以用非常低的成本在很短的时间内构建一个可承担较大访问量的高可用系统。我们只要给予成熟的技术开发,并对项目未来将断一断时间内的发展进行预测,在项目架构上做必要的准备就可以了,没必要“想的太长远”。架构在满足必要的可扩展性、隔离性的基础上,要尽可能简单。

        一个优秀的架构不应该是初期版本简单,升级过程经常需要推到重来的,而是要从简单开始,并且可以顺滑地持续升级。也就是架构最开始的版本很简单,但是为后续的进化、升级做好了准备,以便后续可以完美的升级架构。这样可以持续升级的架构叫“演进式架构”。设计一个优秀的演进式架构比设计一个大而全的架构对架构设计人员的要求更高。

        .Net是一个可以很好的支撑演进式架构的技术平台。在前期网站访问量低。没有专业运维人员的情况下,我们可以把用.net开发的程序部署到单机Windows服务器上。随着网站规模的扩大,我们可以在不修改代码的情况下把程序迁移到Linux+docker的环境下。在网站访问量低的时候,我们可以用内存作为缓存。随着网站访问量的增大,我们可以切换为使用redis作为缓存。.net的依赖注入让我们可以替换服务的实现类,而不需要修改服务消费者的代码。

        一个好的软件架构应该是可以防止软件退化的。软件退化指的是软件升级的时候,随着功能的增加和系统复杂度的提升,代码的质量越来越差,系统的稳定性和可维护性等指标越来越差。一个最大的软件的明显特征就是软件的第一个版本是代码质量最高的版本。之后的版本中,代码质量越来越差。软件的需求是不断变更的,软件的升级也是必然的,因此我们应该再进行架构设计的时候,避免后续软件需求变更,导致软件退化,并且在软件的升级过程中,我们要适时的进行架构的升级,以保持高质量的软件设计。如果我们每次软件升级的时候,没有及时的调整程序结构,而是在原有的程序结构上不断的加入代码,最终的软件就会退化。


2.DDD的基本概念

        随着IT行业的发展,传统的单体结构项目已经无法满足如今的软件项目的要求,越来越多的项目采用微服务架构进行开发,DDD是一个很好的应用于微服务架构的方法论。

传统的软件项目大部分都是单体结构,也就是项目中的所有代码都放到同一个应用程序中。一般他们也都运行在同一个进程中。单体结构的项目有结构简单。部署简单等优点。但是有如下个缺点:

  • 代码之间耦合严重。代码的可维护性低。
  • 项目只能采用单一的语言和技术站,甚至采用的开发包的版本都必须统一。
  • 一个模块的崩溃就会导致整个项目的崩溃。
  • 我们只能进行服务器扩容,无法对其中的一个模块进行单独的服务器扩容。
  • 当需求但需要更新某一个功能时,我们需要把整个系统重新部署一遍。这会导致新功能的上线流程变长。

微服务架构把项目拆分为多个应用程序,每个应用程序单独构建和部署,微服务架构有如下的优点:

  • 每个微服务只负责一个特定的业务,业务逻辑简单,代码简单,对于其他微服务的依赖非常低。因此易于开发和维护。
  • 不同的微服务可以用不同的语言和技术站开发。
  • 一个微服务的运行不会影响其他服务。
  • 可以对一个特定的微服务进行单独扩容。
  • 当需要更新某一个功能的时候,我们只需要重新部署这个功能所在的微服务即可。不需要重新部署整个系统。

当然,万事万物不会只有优点,没有缺点。微服务架构的缺点如下:

  • 在单体结构中,运维人员只需保证一个应用的正常运行即可。而在微服务架构中,运维人员需要保证多个应用的正常运行这给运维工作带来了更大的挑战。
  • 在单体结构中,各个模块之间是进程内调用据交互的效率高。而微服务架构中各微服务之间要通过网络进行通信。数据交互的效率低。
  • 在单体结构中,各模块之间的调用都是在进程内进行的,实现容错,事务一致性等比较容易。而在微服务架构中,做服务之间的通信,通过网络通。实现容错,事物一致性等非常困难。

我们讲过。架构应该是进化而来的。同样,微服务架构也应该是进化而来的。因此在进行系统架构设计的时候,我们应该认真思考,这个项目真的需要微服务吗?如果经过思考后我们仍然决定要采用微服务架构,那我也要在思考能不能减少微服务的数量。第一个版本的项目可以只有几个微服务,随着系统的发展,当我们发现一个微服务中某个功能已经发展到可以独立的程度时,我们再把这个功能拆分为一个微服务。总之,是否采用微服务及如何采用微服务,应该是仔细思考后的结果。我们不能盲目跟风。马丁-富勒(Martin Fowler)曾经提过:“分布是第一定律”,那就是“避免使用分布式”。因此我认为微服务第一定律,那就是“避免使用微服务,除非有充足的理由”。

3.DDD为什么难学

        DDD并不是一个技术,而是一种架构设计指导原则。DDD不是一种强制性的规范,各个项目可以根据自己的情况进行个性化的设计。DDD就像烹饪中餐时“盐少许、油少许”一样让人难以琢磨。而DDD中的概念非常多,表述非常晦涩。因此很多人都对DDD望而生畏。不同项目的行业情况、公司情况、团队情况、业务情况等不同,因此DDD不能给我们一个拿来就能照着用的操作手册。每个人每个团队对DDD的理解不同,如果说“一千个人心中就有一千个哈姆雷特”。那么也可以说“1000个人心中就有2000个DDD”,因为同一个人对滴也可能在不同时期有不同的理解。

        很多人把DDD当成一个技术,这是非常大的一个误区。DDD是一种设计思想。他分为战略设计和战术设计两个层次:DDD的战略设计可以帮助公司的领导人进行团队的划分,人员的组织,产品线的规划,也可以帮助产品经理对产品功能进行规划,还可以帮助架构师进行项目架构的规划,术站的选择等;DDD战术设计则是对公司全员进行DDD具体实施过程的指导

        很多开发人员学习DDD时候感觉无从下手。主要的原因就是他们把DDD当成一个整体去学习,从而找不到学习的落脚点。无论是公司管理人员、业务人员、架构师还是开发人员,在学习DDD的时候,应该先从自己能够把握的方面去学习DDD。随着对DDD应用的深入,在逐渐了解DDD的全貌。在DDD概念落地的时候,不同的技术站选择也会导致这些概念的实现方式不同。

微服务架构实践感悟

从去年初开始接触微服务架构的一些理念,然后到今年开始实施系统第四个大版本的架构升级决定采用这套架构理念。 
最近关于微服务架构的讨论还是多起来,因为国外一些著名互联网公司(如:Amazon、Netflix 等)从实践中摸索出了一套新的大型系统架构方法论,并取得了成功,树立了很好的示范,然后这套方法论渐渐就被一些技术理论派 
人士命名为微服务架构(Microservices)。

在微服务架构(Microservices)这个命名被正式提出来之前,我们做系统也有一套著名的思想理论,叫做面向服务架构(SOA)。 
去年初我就写过一篇文章 [《面向服务与微服务架构》]({% post_url 2014-04-26-面向服务与微服务架构 %}) 来阐述面向服务和微服务架构的关系,当时并没有给出明确定义,只是有个模糊认知,而在近一年的实践过程中两者的关系越发清晰起来, 
我们就从定义两者的关系这里开始吧。

微服务(Microservices)与 面向服务(SOA)架构

You should instead think of microservices as a specific approach for SOA 
in the same way that XP or Scrum are specific approaches for Agile software development.

上面这段引用自 《Building Microservices》 一书, 
通过过去一年的实践认知,我对这个定义是认同的,面向服务架构(SOA)的概念已有十多年,它提出了一种架构设计思想, 
但没有给出标准参考实现,而早期企业软件业界自己摸索了一套实践方式 —— 企业服务总线(ESB)。 
但历史证明 ESB 的实现方案甚至在传统企业软件行业也未取得成功,Martin Fowler 说正是因为 ESB 当年搞砸了很多项目, 
投入几百万美金,产出几乎为 0,因此 SOA 这个概念也蒙上了不详的标签,所以当微服务架构出现时, 
其拥护者开始拒绝使用包裹着失败阴影的 SOA 这个标签,而直接称其为微服务架构(Microservices Architecture Style), 
让人以为是一套全新的架构思想,我也因此困惑了一段时间,但事实上它的本质依然是 SOA 的一种实现。 
正如上面引文所说,就像早年流行的 XP(极限编程)和近年流行的 Scrum(好像没有标准的中文说法)实际都是敏捷软件开发思想 
的具体实践方法而已。

为什么选择微服务架构

首先,当然是该套架构方法有著名的成功经验才导致我去了解与学习它。 
微服务架构中的 “微” 体现了其核心要素,即服务的微型化,就是每个服务微小到只需专注做好一件事。 
这件事紧密围绕业务领域,形成高度内聚的自治性。

以前我做过的一些大型应用系统,采用模块化的分层式架构,所有的业务逻辑代码最终会打进一个代码库中统一部署。 
这种应用架构的问题是,全部开发人员会共享一个代码库,不同模块的边界模糊,实现高内聚、松耦合极其困难。 
如果你接手过这类应用的遗留系统,尝试去做重构改进时,肯定碰到过这类场景,改了一个地方好几个其他模块也需要同步改动, 
模块的边界轻易被穿透,这种应用的架构有一个很形象的名字叫 “洋葱架构”,洋葱的特点就是一层又一层的粘连, 
重构这样的系统就像切洋葱一样让人忍不住飙泪。

微服务架构强调 “微”,但之前有些采用了 SOA 服务化架构思想的系统会搞出很多胖服务来,一点也不微,这依然带来耦合。 
这一点只能依赖系统架构师的服务化建模能力了,但微服务架构强调每个服务一个进程, 
使用进程为边界来隔离代码库至少让同一应用系统不同层次的开发人员享有自己完全自治的领地,每个微服务都有一个掌控者。 
从某种程度上让不小心做错事,例如:跨出服务边界的代码耦合依赖,变得没那么容易。

去年对我们应用系统的代码行数做了个统计,有超过 40 万行。 
一个 20 人的团队维护一个 40 万行共享代码库的单一应用,在里面修改 bug 和添加功能都将十分困难。 
有一篇文章 《程序员的成长和代码行数的关系》 里提到大部分普通程序员成长生涯的瓶颈在 2 万行代码左右, 
超过这个代码行数的应用系统维护起来将倍感吃力,所以我们系统这两年的高速发展膨胀,已让团队维护起来倍感吃力了。 
所以我们想要把一个大系统拆分成许多不同的微服务,每个微服务的规模大小控制在一个普通程序员的舒适维护区能力范围内。

微服务架构实施

把 1 个应用进程部署到 1 台主机,部署复杂度是 1 x 1 = 1,我们有 200 台主机,那么部署复杂度是 1 x 200 = 200。 
把 1 个应用进程拆分成了 50 个微服务进程,则部署复杂度变成了 50 x 200 = 10000。 
部署变得复杂和麻烦多了,同时监控的进程数也大幅增加,监控的复杂度也上升了很多。

所以实施微服务架构是有很高成本的,只有系统的规模到了一定程度才适合,这也是为什么微服务架构实践诞生于大型互联网公司。 
微服务推崇一切自动化的文化,这也是因为其运维复杂度的乘数级飙升, 
从开发之后的构建、测试、部署都需要一个高度自动化的环境来支撑才能有效降低边际成本。

《Building Microservices》 
一书对实施微服务架构有系统性的描述和很多业界案例的简单引用描述,这里不展开讲实施细节,那样就太长了。 
我们这里简单总结下实施的要点:

  1. 自动化文化与环境:自动构建、自动测试、自动部署。

  2. 围绕业务能力建模服务,松耦合、高内聚、暴露接口而隐藏实现细节。

  3. 服务协作模型:中心化(乐队模型:中心指挥)和去中心化(舞蹈模型:群舞自组织),各自场景不同。

  4. 服务交互方式:RPC/REST/WS 技术很多但考虑统一。

  5. 服务部署的独立性、失败隔离性、可监控性。

  6. 服务流控:降级、限流

  7. 服务恢复:多考虑故障发生如何快速恢复而非如何避免发生故障。

  8. 服务发布:灰度。

  9. 服务部署:一服务一主机模型,需要虚拟化(Hypervisor)、容器化(LXC, Docker)等技术支持,实现硬件资源隔离。

  10. 服务配置:中心化配置服务支持

  11. 康威定律:任何设计系统的组织,最终产生的设计等同于组织之内、之间的沟通结构。系统架构的设计符合组织沟通结构取得的收益最大。

  12. 伯斯塔尔法则:服务健壮性原则 —— 发送时要保守,接收时要开放。

自进化的微服务架构

早期人们把软件开发和建筑学作类比,Architect 这个词来就源于建筑学,但软件产品和建筑物的性质完全不同。 
建筑物本身一旦建成则几无变化了,唯有老化后被替代了。 
软件系统会在其生命周期中不断变化,唯一不变的就是变化,拥抱变化,需用进化的观点看待架构演进。 
与此类似的是城市,城市的演进发展总是渐进式的,我们不会在一座旧城旁建一座新城,然后把旧城的居民迁到新城然后再把旧城废弃了。 
但经常我们会用这样的方法重写一个新系统并替换掉旧系统,付出高昂的成本。

而微服务架构思路是不鼓励这种方式的,系统的演进是通过局部的新增、改进或替换微服务来实现的。 
而微服务本身的变化周期是不同步的,从整体上就形成了一种渐进式的、符合自然进化的系统演进道路。 
所以 Architect(架构师)更像是城市规划师而非建筑师,对软件系统进行类似城市划分区域的规划。 
从常识上我们知道把学校和住宅放在一个区域内是合理的,但如果再放一个垃圾处理厂则不合理。 
学校和住宅就是提供两种不同能力的服务,垃圾处理厂是另一种服务,但现实中软件系统的规划其实不像城市规划那么有常识性, 
这是架构师能力和经验发挥作用的地方,前期规划的不合理会在后期带来维护成本的放大。

每个历史悠久的城市都有各自不同的味道,城市中的人、时间、技术进步共同决定了今天城市的面貌。 
微服务架构的妙处就在于它符合城市历史演进规律,随着人员变化、时间、技术改进而引发自然渐进式的进化。

微服务架构与架构师

架构师的一个角色是技术决策者,技术决策涉及很多权衡取舍(trade-off),而微服务架构给了架构师更多权衡取舍的空间。 
每个微服务实现层面的技术决策更多由服务负责人决定,服务的分拆伴随着决策权和责任的分拆,这也减轻了整体应用负责人的责任负担。 
架构师解放出来从整体和全局上将更加关注服务之间是如何交互,并确保能正确的监控系统全局的健康性。

分拆了服务实现的技术决策权,那何时又该适当的介入以避免服务实现不当危及整体系统的安全? 
就像教孩子骑车,你无法代替它们去骑,你小心的看着他们骑的歪歪扭扭,担心他们摔倒。 
事实上,孩子骑车摔倒的次数比你担心的要少,但如果每次快摔倒时都去扶住,那么他们也许永远学不会骑车。 
当孩子骑车失控时冲向了繁忙的马路或要冲下路边的深沟,那时才有必要介入去稳住他们。

架构师工作在抽象和具体两个层面:

  • 架构是一项技术工作,技术工作要服务于组织的战略目标。

  • 大量的工程实践在每日的工作中不断变化,而渐渐稳定的实践方式被抽象提炼为一系列原则。

  • 原则的普及带来整体效率的提升和边际成本的下降,以更有效的支持组织战略目标的快速达成。

  • 另外也要确保这些原则不是让开发人员的生活变得更凄惨而是更美好。

  • 跟踪新技术发展确保能在合适的时候做出正确的取舍折衷。

  • 让开发人员理解某项技术决策的影响和制约以便最有效的执行,甚至在特定情形下深入到代码的实现层面。

文章开头说了,这是我们实施系统的第四个大版本,而之前每一个大版本升级都是一次旧城倒新城的整体搬迁。 
而微服务架构天然的自然进化属性是否预示着这应该是最后一个大版本升级了? 
微服务架构述说着没有永恒的架构,只有进化的架构,但微服务架构不是银弹,也没有银弹。


出处:https://blog.csdn.net/mindfloating/article/details/45740573

以上是关于关于架构的一些理念的主要内容,如果未能解决你的问题,请参考以下文章

关于SOA和微服务架构的一些思考

架构设计的哲学

Spring技术内幕:设计理念和整体架构概述

从一个实验看微服务架构---不谈理念讲干货

微服务架构设计与实战”高级研修班

ArchKeeper(开篇):架构守护平台的问题与理念