从演进的视角理解微服务架构
服务架构演进史
想要了解一种技术,最好先了解下它的历史,知道它是怎么来的,解决了怎样的问题,还遗留了哪些问题。对架构风格的理解更是如此。
单体架构
首先是单体架构,正如我们熟悉的“图书管理系统”、“学生管理系统”、“OA 系统”等等。
这些系统,因为满足某种业务功能而起,一个应用、一口气就能将所有的功能做出来。
它的优点很明显:易于开发、易于测试、易于部署,且由于系统中各个功能、模块、方法的调用过程都是进程内调用,因此也是运行效率最高的一种架构。
这样的系统看似“不可拆分”,但主要还是在部署层面上而已。纵向角度上,系统内部会采用诸如 MVC 之类的分层架构;在横向角度,也会按照不同的职责,有不同的包、组件等。
在“拆分”这方面,单体系统的真正缺陷不在如何拆分,而在拆分之后的隔离与自治能力上的欠缺。譬如内存泄漏、线程爆炸、阻塞、死循环等问题,都将会影响整个程序,甚至影响还将会波及整台机器,甚至是集群中其他单体副本的正常工作。
单体架构在系统规模小的时候会有优势;但当系统规模大,或程序需要修改的时候,其部署的成本、技术升级的迁移成本都会变得更为昂贵。就好比:当公司小时,让安保部和质检部两个不相干的部门在同一栋大楼中办公是节约资源,但当公司人数增加,办公室已经拥挤不堪,最多只能在楼顶加盖新楼层(相当于增强硬件性能)来解决办公问题,而不能让安保、质检分开地方办公,这便是缺陷所在。
而最最重要的,这种架构风格潜在的观念是希望系统的每一个部件,每一处代码都尽量可靠,靠不出或少出缺陷来构建可靠系统。随着软件架构演进,构筑可靠系统从“追求尽量不出错”,到正视“出错是必然”的观念转变,才是微服务架构得以挑战并逐步开始取代运作了数十年的单体架构的底气所在。
面向服务架构
随着用户规模与业务功能的的增长,单体的架构无法满足这些变化,必然面临着拆分。
拆分之后的应用往往又需要彼此的通信,于是又有了“微内核架构”、“事件驱动架构”。
当系统演化至事件驱动架构时,在并行发展的远程服务调用也迎来了 SOAP 协议的诞生,此时“面向服务的架构”(Service Oriented Architecture,SOA)已经有了它登上软件架构舞台所需要的全部前置条件。
软件架构来到 SOA 时代,许多概念、思想都已经能在今天微服务中找到对应的身影了,譬如服务之间的松散耦合、注册、发现、治理,隔离、编排,等等。
SOA 在 21 世纪最初的十年里曾经盛行一时,最终却还是偃旗息鼓,沉寂了下去。SOAP 协议被逐渐边缘化的本质原因是过于严格的规范定义带来过度的复杂性,而构建在 SOAP 基础之上的 ESB、BPM、SCA、SDO 等诸多上层建筑,进一步加剧了这种复杂性。
微服务架构
微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。
微服务的九个核心的业务与技术特征:
围绕业务能力构建(Organized around Business Capability)。这里再次强调了康威定律的重要性,有怎样结构、规模、能力的团队,就会产生出对应结构、规模、能力的产品。这个结论不是某个团队、某个公司遇到的巧合,而是必然的演化结果。如果本应该归属同一个产品内的功能被划分在不同团队中,必然会产生大量的跨团队沟通协作,跨越团队边界无论在管理、沟通、工作安排上都有更高昂的成本,高效的团队自然会针对其进行改进,当团队、产品磨合调节稳定之后,团队与产品就会拥有一致的结构。
分散治理(Decentralized Governance)。这是要表达“谁家孩子谁来管”的意思,服务对应的开发团队有直接对服务运行质量负责的责任,也应该有着不受外界干预地掌控服务各个方面的权力,譬如选择与其他服务异构的技术来实现自己的服务。这一点在真正实践时多少存有宽松的处理余地,大多数公司都不会在某一个服务使用 Java,另一个用 Python,下一个用 Golang,而是通常会有统一的主流语言,乃至统一的技术栈或专有的技术平台。微服务不提倡也并不反对这种“统一”,只要负责提供和维护基础技术栈的团队,有被各方依赖的觉悟,要有“经常被凌晨 3 点的闹钟吵醒”的心理准备就好。微服务更加强调的是确实有必要技术异构时,应能够有选择“不统一”的权利,譬如不应该强迫 Node.js 去开发报表页面,要做人工智能训练模型时,应该可以选择 Python,等等。
通过服务来实现独立自治的组件(Componentization via Services)。之所以强调通过“服务”(Service)而不是“类库”(Library)来构建组件,是因为类库在编译期静态链接到程序中,通过本地调用来提供功能,而服务是进程外组件,通过远程调用来提供功能。前面的文章里我们已经分析过,尽管远程服务有更高昂的调用成本,但这是为组件带来隔离与自治能力的必要代价。
产品化思维(Products not Projects)。避免把软件研发视作要去完成某种功能,而是视作一种持续改进、提升的过程。譬如,不应该把运维只看作运维团队的事,把开发只看作开发团队的事,团队应该为软件产品的整个生命周期负责,开发者不仅应该知道软件如何开发,还应该知道它如何运作,用户如何反馈,乃至售后支持工作是怎样进行的。注意,这里服务的用户不一定是最终用户,也可能是消费这个服务的另外一个服务。以前在单体架构下,程序的规模决定了无法让全部人员都关注完整的产品,组织中会有开发、运维、支持等细致的分工的成员,各人只关注于自己的一块工作,但在微服务下,要求开发团队中每个人都具有产品化思维,关心整个产品的全部方面是具有可行性的。
数据去中心化(Decentralized Data Management)。微服务明确地提倡数据应该按领域分散管理、更新、维护、存储,在单体服务中,一个系统的各个功能模块通常会使用同一个数据库,诚然中心化的存储天生就更容易避免一致性问题,但是,同一个数据实体在不同服务的视角里,它的抽象形态往往也是不同的。譬如,Bookstore 应用中的书本,在销售领域中关注的是价格,在仓储领域中关注的库存数量,在商品展示领域中关注的是书籍的介绍信息,如果作为中心化的存储,所有领域都必须修改和映射到同一个实体之中,这便使得不同的服务很可能会互相产生影响而丧失掉独立性。尽管在分布式中要处理好一致性的问题也相当困难,很多时候都没法使用传统的事务处理来保证,但是两害相权取其轻,有一些必要的代价仍是值得付出的。
强终端弱管道(Smart Endpoint and Dumb Pipe)。弱管道(Dumb Pipe)几乎算是直接指名道姓地反对 SOAP 和 ESB 的那一堆复杂的通信机制。ESB 可以处理消息的编码加工、业务规则转换等;BPM 可以集中编排企业业务服务;SOAP 有几十个 WS-*协议族在处理事务、一致性、认证授权等一系列工作,这些构筑在通信管道上的功能也许对某个系统中的某一部分服务是有必要的,但对于另外更多的服务则是强加进来的负担。如果服务需要上面的额外通信能力,就应该在服务自己的 Endpoint 上解决,而不是在通信管道上一揽子处理。微服务提倡类似于经典 UNIX 过滤器那样简单直接的通信方式,RESTful 风格的通信在微服务中会是更加合适的选择。
容错性设计(Design for Failure)。不再虚幻地追求服务永远稳定,而是接受服务总会出错的现实,要求在微服务的设计中,有自动的机制对其依赖的服务能够进行快速故障检测,在持续出错的时候进行隔离,在服务恢复的时候重新联通。所以“断路器”这类设施,对实际生产环境的微服务来说并不是可选的外围组件,而是一个必须的支撑点,如果没有容错性的设计,系统很容易就会被因为一两个服务的崩溃所带来的雪崩效应淹没。可靠系统完全可能由会出错的服务组成,这是微服务最大的价值所在,也是这部开源文档标题“凤凰架构”的含义。
演进式设计(Evolutionary Design)。容错性设计承认服务会出错,演进式设计则是承认服务会被报废淘汰。一个设计良好的服务,应该是能够报废的,而不是期望得到长存永生。假如系统中出现不可更改、无可替代的服务,这并不能说明这个服务是多么的优秀、多么的重要,反而是一种系统设计上脆弱的表现,微服务所追求的独立、自治,也是反对这种脆弱性的表现。
基础设施自动化(Infrastructure Automation)。基础设施自动化,如 CI/CD 的长足发展,显著减少了构建、发布、运维工作的复杂性。由于微服务下运维的对象比起单体架构要有数量级的增长,使用微服务的团队更加依赖于基础设施的自动化,人工是很难支撑成百上千乃至成千上万级别的服务的。
微服务与 SOA
首先 SOA 和微服务架构是一个层面的东西,而对于 ESB 和微服务网关是一个层面的东西,一个谈到是架构风格和方法,一个谈的是实现工具或组件。
1.SOA(Service Oriented Architecture)“面向服务的架构”:他是一种设计方法,其中包含多个服务, 服务之间通过集中管理,最终提供一系列的功能。一个服务通常以独立的形式存在与操作系统进程中。
2.微服务架构:其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。
微服务架构 = 80%的 SOA 服务架构思想 + 100%的组件化架构思想 + 80%的领域建模思想
后微服务时代(Cloud Native)
从软件层面独力应对微服务架构问题,发展到软、硬一体,合力应对架构问题的时代,此即为“后微服务时代”。
分布式架构中出现的问题,如注册发现、跟踪治理、负载均衡、传输通信等,其实在 SOA 时代甚至可以说从原始分布式时代起就已经存在了,只要是分布式架构的系统,就无法完全避免,但我们不妨换个思路来想一下,这些问题一定要由软件系统自己来解决吗?
如果不局限于采用软件的方式,这些问题几乎都有对应的硬件解决方案。而之所以微服务时代,人们选择在软件的代码层面而不是硬件的基础设施层面去解决这些分布式问题,很大程度上是因为由硬件构成的基础设施,跟不上由软件构成的应用服务的灵活性的无奈之举。
微服务时代所取得的成就,本身就离不开以 Docker 为代表的早期容器化技术的巨大贡献。
一旦虚拟化的硬件能够跟上软件的灵活性,那些与业务无关的技术性问题便有可能从软件层面剥离,悄无声息地解决于硬件基础设施之内,让软件得以只专注业务,真正“围绕业务能力构建”团队与产品。
服务网格(Service Mesh)
但 Kubernetes 仍然没有能够完美解决全部的分布式问题,一些问题处于应用系统与基础设施的边缘,使得完全在基础设施层面中确实很难精细化地处理。
举个例子,微服务 A 调用了微服务 B 的两个服务,称为 B1 和 B2,假设 B1 表现正常但 B2 出现了持续的 500 错,那在达到一定阈值之后就应该对 B2 进行熔断,以避免产生雪崩效应。
如果仅在基础设施层面来处理,这会遇到一个两难问题,切断 A 到 B 的网络通路则会影响到 B1 的正常调用,不切断的话则持续受 B2 的错误影响。
以上问题在通过 Spring Cloud 这类应用代码实现的微服务中并不难处理,只要合乎逻辑,想要实现什么功能,只受限于开发人员的想象力与技术能力;但基础设施是针对整个容器来管理的,粒度相对粗旷,只能到容器层面,对单个远程服务就很难有效管控。
为了解决这一类问题,虚拟化的基础设施很快完成了第二次进化,引入了今天被称为“服务网格”(Service Mesh)的“边车代理模式”(Sidecar Proxy)。
它将分布式服务的通信抽象为单独一层,在这一层中实现负载均衡、服务发现、认证授权、监控追踪、流量控制等分布式系统所需要的功能,作为一个和服务对等的代理服务,和服务部署在一起,接管服务的流量,通过代理之间的通信间接完成服务之间的通信请求。
如果我们从一个全局视角来看,就会得到如下部署图:
当然,Service Mesh 目前也面临一些挑战:
Service Mesh 组件以代理模式计算并转发请求,一定程度上会降低通信系统性能,并增加系统资源开销;
Service Mesh 组件接管了网络流量,因此服务的整体稳定性依赖于 Service Mesh,同时额外引入的大量 Service Mesh 服务实例的运维和管理也是一个挑战;
微服务架构技术体系
技术体系架构
1.接入层
也可以叫负载均衡层,把外部的流量引入到系统中来。一般负载均衡软件有 nginx,lvs,还有各大云服务厂商自己的负载均衡服务。2.网关层
内部接口的一些认证、安全、鉴权、过滤、限流等服务,一般处于这一层。这一层把内部的服务接口做一层安全隔离,保护内部服务,同时也可以实现一些其他需求,比如前面讲的鉴权、黑名单过滤等等需求。3.业务服务层
基础服务:根据业务特点又可以分为核心基础服务、公共服务、中间层服务等。 聚合服务:把下面细粒度的基础服务再进一步封装、关联,组合成新的服务,供上层调用。这一层可以实现多变的需求。 上面的这种划分是根据逻辑来划分,各个公司可以根据自己实际的业务需求来进行划分。4.支撑服务层
微服务能够成功实施落地,这一层与下一层 CI/CD 的配套设施是非常重要。这一层包括注册服务中心,配置中心,监控报警服务,日志聚合服务,调用链监控几大服务,后台服务涉及的服务有消息队列,定时任务,数据访问等内容。
a.注册服务中心
相当于是一个注册表,用于管理服务提供者、消费者的信息,应对在服务在扩、缩容情况下产生的变化。
b.配置中心
以前,开发人员把配置文件放在开发文件里面,为了解决无法追溯配置人员,每次需要发布,不便管理等问题,因此就有配置中心。 常见的有 Disconf,spring cloud config,Apollo
5.平台服务层
这一层是实施业务弹性治理的关键。集群的资源调度:扩缩容。在微服务建设过程中,可能会遇到一些突发事件。比如微博明星热点事件,会导致访问量暴增,这就需要能实时增加服务资源应对这种突发情况,热点过后,又要减少资源。 镜像管理和发布系统配合使用可以应对出现的这种情况。所以很多团队后面会引入 docker+k8s,容器,镜像管理,容器服务编排。此外,基于 CI/CD 的 DevOps 也是构建在这一层能力。6.基础设施层
这个是最底层的基础设施,网络,存储,硬盘,IDC 的部分。laas 这个概念就是针对这一层。
SpringcloudNetflix vs Springcloud Alibba
参考资料
服务架构演进史 https://icyfenix.cn/architecture/architect-history/
图解微服务技术架构体系 https://blog.51cto.com/u_10180481/2999392
微服务架构技术栈选型手册 https://www.infoq.cn/article/micro-service-technology-stack
微服务架构技术体系 https://www.bilibili.com/video/BV1of4y1g7R7/?vd_source=e50eb56d5e5301be2d91d9843bb479ff
微服务架构学习与思考(03):微服务总体架构图解 https://www.cnblogs.com/jiujuan/p/13295147.html
架构设计-SOA 架构和微服务架构的区别 https://www.cnblogs.com/xuwc/p/13989081.html
什么是 Service Mesh https://zhuanlan.zhihu.com/p/61
版权声明: 本文为 InfoQ 作者【苏格拉格拉】的原创文章。
原文链接:【http://xie.infoq.cn/article/670f2b6201192f086b331d726】。文章转载请联系作者。
评论