演进中的架构

单体架构

“单体”只是表明系统中主要的过程调用都是进程内调用,不会发生进程间通信,仅此而已。

Monolith means composed all in one piece. The Monolithic application describes a single-tiered software application in which different components combined into a single program from a single platform.

单体意味着自包含。单体应用描述了一种由同一技术平台的不同组件构成的单层软件。

由于所有代码都运行在同一个进程空间之内,所有模块、方法的调用都无须考虑网络分区、对象复制这些麻烦的事和性能损失。获得了进程内调用的简单、高效等好处的同时,也意味着如果任何一部分代码出现了缺陷,过度消耗了进程空间内的资源,所造成的影响也是全局性的、难以隔离的。譬如内存泄漏、线程爆炸、阻塞、死循环等问题,都将会影响整个程序,而不仅仅是影响某一个功能、模块本身的正常运作。

同样,由于所有代码都共享着同一个进程空间,不能隔离,也就无法(其实还是有办法的,譬如使用OSGi这种运行时模块化框架,但是很别扭、很复杂)做到单独停止、更新、升级某一部分代码,因为不可能有“停掉半个进程,重启1/4个程序”这样不合逻辑的操作,所以从可维护性来说,单体系统也是不占优势的。程序升级、修改缺陷往往需要制定专门的停机更新计划,做灰度发布、A/B测试也相对更复杂。

 

SOA架构(Service-Oriented Architecture)

面向服务的架构是一次具体地、系统性地成功解决分布式服务主要问题的架构模式。

烟囱式架构(Information Silo Architecture):信息烟囱又名信息孤岛(Information Island),使用这种架构的系统也被称为孤岛式信息系统或者烟囱式信息系统。它指的是一种完全不与其他相关信息系统进行互操作或者协调工作的设计模式。

微内核架构(Microkernel Architecture):微内核架构也被称为插件式架构(Plug-in Architecture)。既然在烟囱式架构中,没有业务往来关系的系统也可能需要共享人员、组织、权限等一些的公共的主数据,那不妨就将这些主数据,连同其他可能被各子系统使用到的公共服务、数据、资源集中到一块,成为一个被所有业务系统共同依赖的核心(Kernel,也称为Core System),具体的业务系统以插件模块(Plug-in Modules)的形式存在,这样也可提供可扩展的、灵活的、天然隔离的功能特性,即微内核架构。

事件驱动架构(Event-Driven Architecture):为了能让子系统互相通信,一种可行的方案是在子系统之间建立一套事件队列管道(Event Queues),来自系统外部的消息将以事件的形式发送至管道中,各个子系统从管道里获取自己感兴趣、能够处理的事件消息,也可以为事件新增或者修改其中的附加信息,甚至可以自己发布一些新的事件到管道队列中去,如此,每一个消息的处理者都是独立的,高度解耦的,但又能与其他处理者(如果存在该消息处理者的话)通过事件管道进行互动,

 

软件架构来到SOA时代,许多概念、思想都已经能在今天微服务中找到对应的身影了,譬如服务之间的松散耦合、注册、发现、治理,隔离、编排,等等。这些在今天微服务中耳熟能详的名词概念,大多数也是在分布式服务刚被提出时就已经可以预见的困难点。SOA针对这些问题,甚至是针对“软件开发”这件事情本身,都进行了更加系统性、更加具体的探索。

  • 有清晰软件设计的指导原则,譬如服务的封装性、自治、松耦合、可重用、可组合、无状态
  • 明确了采用SOAP作为远程调用的协议

过于严格的规范定义带来过度的复杂性。而构建在SOAP基础之上的ESB、BPM、SCA、SDO等诸多上层建筑,进一步加剧了这种复杂性。

 

微服务架构(Microservices)

微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。

微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。

  • 围绕业务能力构建(Organized around Business Capability)。这里再次强调了康威定律的重要性,有怎样结构、规模、能力的团队,就会产生出对应结构、规模、能力的产品。这个结论不是某个团队、某个公司遇到的巧合,而是必然的演化结果。如果本应该归属同一个产品内的功能被划分在不同团队中,必然会产生大量的跨团队沟通协作,跨越团队边界无论在管理、沟通、工作安排上都有更高昂的成本,高效的团队自然会针对其进行改进,当团队、产品磨合调节稳定之后,团队与产品就会拥有一致的结构。
  • 分散治理(Decentralized Governance)
  • 通过服务来实现独立自治的组件(Componentization via Services)。之所以强调通过“服务”(Service)而不是“类库”(Library)来构建组件,是因为类库在编译期静态链接到程序中,通过本地调用来提供功能,而服务是进程外组件,通过远程调用来提供功能。
  • 产品化思维(Products not Projects)
  • 数据去中心化(Decentralized Data Management)
  • 强终端弱管道(Smart Endpoint and Dumb Pipe。如果服务需要上面的额外通信能力,就应该在服务自己的 Endpoint 上解决,而不是在通信管道上一揽子处理。微服务提倡类似于经典 UNIX 过滤器那样简单直接的通信方式,RESTful 风格的通信在微服务中会是更加合适的选择
  • 容错性设计(Design for Failure)。不再虚幻地追求服务永远稳定,而是接受服务总会出错的现实,要求在微服务的设计中,有自动的机制对其依赖的服务能够进行快速故障检测,在持续出错的时候进行隔离,在服务恢复的时候重新联通。
  • 演进式设计(Evolutionary Design)。容错性设计承认服务会出错,演进式设计则是承认服务会被报废淘汰。
  • 基础设施自动化(Infrastructure Automation)。基础设施自动化,如 CI/CD 的长足发展,显著减少了构建、发布、运维工作的复杂性。由于微服务下运维的对象比起单体架构要有数量级的增长,使用微服务的团队更加依赖于基础设施的自动化,人工是很难支撑成百上千乃至成千上万级别的服务的。
posted @ 2021-09-08 19:53  ted  阅读(200)  评论(0编辑  收藏  举报