SpringCloud Alibaba实战第一课 架构演进之路

564 篇文章 136 订阅

开篇词 Spring Cloud Alibaba 未来的微服务生态标准

你好,我是老齐,一名从业近 20 年的 IT 老兵,曾在京东、财政部、宜信、工商银行等机构从事架构设计与核心研发工作,有多个亿级流量的软件架构设计经验。也曾多次基于 Spring Cloud Alibaba 对微服务架构项目进行落地与升级改造,有着丰富的实践经验。

出来工作我不觉得谈钱庸俗,我们学习本身就是为了未来有更好的发展、更多的收入。现在已经走进 21 世纪第三个十年,在未来十年内以互联网、IoT 物联网为代表的分布式应用必将成为主流,大量软件企业对掌握微服务与高可用、高性能、高并发的架构人才也必定趋之若鹜,在这样的时代拐角下,我们又该如何选择呢?

Drawing 0.png

某知名互联网企业招聘需求

为什么要掌握微服务架构?

架构圈有句名言“任何脱离场景的架构设计都是耍流氓”。没错,在分布式架构演进的几十年过程中出现了几十种架构模式,但目标只有一个,解决上一代架构遗留的各种问题。微服务架构也不例外,随着互联网、物联网的广泛应用,高并发应用程序在数量与体量上都在以指数级提高,传统的单体应用、SOA 等架构已经不足以支撑新环境对应用性能与可靠性的要求。

早些年我们在工行开发系统时,那时还在使用基于 ESB(企业服务总线)的 SOA 架构推进应用开发,ESB 作为分布式架构的核心枢纽良好地解决了异构系统间的消息传递问题,但好景不长,工商银行庞大的业务体量很快就让 ESB 不堪重负。再加上 ESB 本身属于重量级解决方案,扩展与维护都要依托于三方厂商进行,这也让架构的升级改造变得举步维艰。我们迫切需要更轻量级的解决方案,这也在我心里埋下了一颗种子,寻找更好的 SOA 替代方案。

直到 2015 年初,一次偶然机会,我从一次架构师线下交流中接触到“微服务架构”这个概念,它轻量级、标准化、业务驱动的特性引起了我的注意,这不正是我一直追寻的东西吗,于是开始潜心研究。但当时同为初学者,学习过程中也遇到了很多疑惑,比如:

  • 微服务的拆分粒度如何界定?

  • 传统的分布式架构数据一致性该如何保障?

  • 大型应用如何实施监控与链路跟踪?

  • ...

好在因为工作之便,不断摸索与项目积累后,对其中大多数问题已经有了成熟的答案。

随着技术的不断迭代,我有幸成为国内最早期一批微服务架构的践行者,并推进了多个亿级流量的微服务项目成功落地。在众多微服务解决方案中,Spring Cloud Alibaba 技术生态成为后起之秀,成为众多国内新软件项目架构落地的首选技术。

为什么 Spring Cloud Alibaba 会迅速崛起

你现在可能有疑问,这几年微服务架构上 Spring Cloud 官方生态已经很成熟了,为什么我还要去学 Spring Cloud Alibaba 呢?

其实微服务看似是将整体应用打散为小服务这种很简单的处理,实则操作起来非常复杂,针对新的微服务架构额外产生的数据一致性问题、网络通信故障、限流与熔断机制、调用链路跟踪、集群监控、甚至用户登录与权限管理都是全新的挑战。如果这些问题全部都要软件公司自己解决显然是行不通的,好在这几年以 Spring Cloud 为基础的微服务技术生态日渐成熟,前面提到的大多数问题确实都已得到了有效解决。

图片2.png

Spring Cloud官方架构

但好景不长,在这几年以 Netfilix Eureka 为代表的 Spring Cloud 核心中间件纷纷停止更新,再加上许多组件设计老旧,在性能上已无法满足互联网大厂的要求,我们迫切需要一套符合中国特色的微服务架构解决方案。

Spring Cloud Alibaba 就是在这种背景下诞生的,Spring Cloud Alibaba 是国产的微服务开发一站式解决方案,与原有 Spring Cloud 兼容的同时对微服务生态进行扩展,通过添加少量的配置注解,便可实现更符合国情的微服务架构。

图片1.png

Spring Cloud Alibaba 架构

相比 Spring Cloud 官方标准,Spring Cloud Alibaba 提供了更完整的功能、更好用的 API,同时在中文的加持下让复杂的微服务架构变得不再高不可攀,目前 Spring Cloud Alibaba 已经是事实上的国内微服务技术标准,这也是我为什么极力推荐学习 Spring Cloud Alibaba 的重要原因。

这便是我开设这门课程的初衷,为了让学习过程更加顺利,我也做了以下这些准备。

课程设计

微服务架构本质也是一种架构的实现方案,它在原有基础上对分布式架构作出进一步的扩展与标准化,本门课我们将利用大量的实际案例、图形、表格等形式为你全方面勾勒出 Spring Cloud Alibaba 的轮廓,在讲解的同时我也会跟你分享自己的架构设计经验。

课程按照构建微服务从基础搭建到上层应用的顺序进行讲解,主要分为六个模块:

  • 模块一 微服务架构设计:主要介绍什么是微服务架构,以及微服务架构设计时一些常见问题。

  • 模块二 Nacos 服务治理:Nacos注册中心是整个微服务架构的核心,我将详细介绍 Nacos的安装、使用与集群搭建过程,同时结合图文介绍 Nacos 服务发现的底层原理。

  • 模块三 微服务通信:当服务间要产生彼此通信,在 Spring Cloud Alibaba 中支持 RPC 与 RESTful 两种方案,对应产品为 Dubbo 与OpenFeign ,本阶段我将给出这些组件的最佳实践以及原理分析。

  • 模块四 系统保护:Sentinel 是 Alibaba 提供的服务保护中间件,利用 Sentinel 可以有效预防分布式架构的系统性崩溃,本阶段我们将讲解 Sentinel 的限流、熔断、代码控制等最佳实践。

  • 模块五 高级特性:本阶段我们要讲解 Spring Cloud Alibaba 提供的众多高级特性。例如:配置中心、链路追踪、性能监控、分布式事务、消息队列等,这些技术我们都将从应用入门到原理分析逐一进行讲解。

  • 模块六 微服务架构最佳实践:在这个阶段我将拿出自己的私货,为你讲解微服务架构的综合运用与项目实践。在这里我们会接触到 Seata 分布式事务架构、多级缓存设计、老项目升级改造策略、微服务认证与授权体系、数据一致性解决方案以及基于容器化的 DevOps 运维架构。

有这六大模块,结合我们严谨认真的学习,相信你一定能对 Spring Cloud Alibaba 有一个全面的认识和了解,并将这些知识运用在工作项目中。

另一方面,熟悉我的同学都知道,我从第一天做课程就在强调“说人话、讲实战”。在课程中,几乎见不到晦涩难懂的概念,也没有烧脑的逻辑,更不喜欢带你手撕晦涩的源码,我只希望使用最直白的案例为你诠释工作中最有价值的知识。

在开发这门课程前,我在思考这门课程的意义。现在很多课程上来就强调 XX 算法、XX 理论、XX 模型。其实在我看来无论是程序框架还是架构设计,首先要用起来解决眼下遇到的问题,再去深入剖析原理,这才能做到学以致用。

因此 Spring Cloud Alibaba 这门课程从始至终将贯彻实用性,通过模拟真实场景带你逐步了解每一个组件的用途,逐渐构筑完整的微服务架构。同时,在课程中我一直强调“魔鬼隐藏在细节”,课程不会空泛的带你陈列“各种源码”,而是尽可能描述操作过程,让你跟着文档也能够搭建完整的微服务架构,在遇到关键细节与致命缺陷时我也会特别强调,让你少走些弯路。

学习门槛

虽然本课是讲微服务架构,在设计课程时我还是尽量把门槛放低,你只要是会用 Java,了解过 Spring Boot 框架,就不存在门槛可以放心“食用”。

在认真学习完这门课程后,你将对微服务架构有了完整的认识,能够独立搭建微服务架构,在关键问题上也会有成熟的思路帮你避开各种陷阱。


01 一探究竟:从架构的演变看微服务化架构

本节课,让我们一起来了解到底什么才是微服务。

什么是微服务架构

首先,到底什么是微服务呢?微服务名词出现的历史其实并不久远。2011 年的 5 月份,威尼斯附近的一个软件架构师的研讨会上,微服务的概念第一次被人提起,但当时并没有给出微服务明确的定义。随着技术的发展,在 2014 年的 3 月份,由詹姆斯里维斯和他的伙伴马丁福乐在博客中发表了一篇关于微服务特点的文章。这篇文章对微服务概念定义进行了明确。

下面我们来看一下什么是真正的微服务。

所谓微服务架构风格是一种将单机应用程序开发为一组小型服务的方法,每个小服务运行在自己的进程中,并以轻量级的机制来进行通信。这些服务围绕着业务能力所建立,并且由完全自动化的部署机构独立部署,这些服务的集中管理只有最低限度,可以用不同的编程语言编写并使用不同的数据库存储技术。

以上就是关于微服务的定义,或许这个描述太过学术, 那我通过讲解架构的演化历史来帮助你了解微服务架构。要知道任何架构都不是一蹴而就的,每一种架构其实都是为了解决以往我们业务所产生的痛点而设计的。

垂直划分的分布式应用具有哪些问题?

要弄清楚微服务架构,首先我们要看以往的分布式架构到底有哪些问题。

在早期构建分布式应用时,多系统间协作其实是一件比较困难的事情。我们来看下面这张图:

图1.png

普惠金融借款流程

这是我带领开发的一个项目,主要负责普惠金融的借款服务,按照业务职能主要包含了 4 部分,分别是借款人门户网站信审风控系统贷后系统以及催收系统

具体的业务流程是:

  1. 借款人门户负责收集借款人的需求;

  2. 将借款人的信息送入信审和风控系统,风控进行评估;

  3. 如果满足借款要求,则将这些信息发给贷后系统来进行实际的放款操作;

  4. 最后在实际的分期还款过程中,通知借款人定期还款。

这个过程中可以看到我们把 1 个完整的业务流程拆解成 4 个子系统,每个子系统有独立的团队来进行维护,因为没有统一的标准,便衍生出一系列的后续问题,我们来看一下。

首先,系统间通信困难。 假如信审系统需要向贷后系统发送一个调用请求,通过 WebService 来实现,在 WebService 跨进程调用时,需要双方持有相同的传输对象才可以完成数据的交互。但如果服务的提供者,他将接口以及传输对象进行升级后,而客户端没有及时更新的话,此时便会因为对象的状态不一致导致传输失败的情况。要知道在互联网机构,接口的升级与扩展可能是一件频繁发生的事情,如果这类问题一再出现,必然会影响系统的稳定性和团队的协作,这是第一个问题。

图片2.png

强一致性的跨进程通信方式

其次,是系统的内部复杂度对外暴露。 假如信审系统目前需要访问贷后系统,贷后系统为了高可用的要求,提供了 IP 为 10 和 11 的两个节点,作为信审系统客户端持有了这两个静态的 IP 地址。但随着业务的发展,贷后系统的负载越来越大,此时作为贷后系统集群加入了额外的两个节点,它们分别是 12 和 13。如何通知信审系统额外扩展这两个新加入的节点呢?因为在原始并没有设计这样的动态扩展的机制,所以我们必须手动配置信审系统的 IP 列表,以及重启应用才可以做到。这就相当于信审系统必须了解贷后系统每一台服务器的实际运行情况,这显然就增加了两个系统之间的耦合,提高了项目维护的难度。

图片3.png

缺少动态发现机制

第三,系统间的调用关系复杂。 假设我们有 6 个不同的应用,如果没有提前规划,软件工程师想梳理清系统间的调用关系会非常困难。这里我们急需一种技术帮助我们梳理清系统间的调用关系。

图片44.png

难以梳理的调用关系

第四,过度的重复建设。 在公司进行项目开发时,因为是每一个团队负责独立的系统,而这些系统往往需要一些通用的底层设施。例如:用户认证与权限控制、黑名单白名单、流量控制与系统异常的处理以及系统参数的配置管理等模块。而这些模块在每一个子系统中都要重复的进行开发,这显然是一件费时费力的事情,不利于数据的集中管理。

第五,“大一统”的架构设计。 所谓大一统架构设计,是指很多公司希望采用一套统一的架构来适应公司各个不同职能的子系统。比如,之前所有的系统是将数据统一存放在性能强大的 Oracle 数据库集群中。但这里有一个弊端,作为借款人门户系统,需要对用户开放大量的全文检索。如果你对数据检索技术有了解,会明白Oracle这种关系型数据库并不擅长全文检索功能,实际应交给Elasticsearch全文检索引擎进行处理。

对于借款人门户网站的需求,需要额外引入 Elasticsearch 集群。因为新的集群是借款人门户网站专用的,所以理应由借款人门户的团队来独立管理与维护。此时你会发现,Elasticsearch对于其他的子系统是没有意义的,但因为大一统的架构设计约束,其他系统也必须要支持 Elasticsearch,这显然是不合理的。

图片55.png

大一统架构的弊端

以上的五点弊端,只是传统的分布式架构中的一个缩影。其他问题当然还有很多在这儿我就不一一列举。

微服务架构又是如何解决这些问题的

当我们引入微服务架构后,是如何解决这些问题的呢?

微服务的特点有三个:

  • 构建基于业务、可重用、职责明确的小型服务;

  • 统一的通信标准,轻量级的通信协议,通常这里的通信协议是指的 RESTful;

  • 可独立运行,独立存储由独立团队进行维护。

以上是微服务三个具体的特点。如果放在刚才的业务流程中,具体会变成什么样子呢?

当微服务改造以后,我们的架构会变成这个样子。

图片66.png

微服务架构

我们将原有的各个子系统中的核心的服务进行了抽象形成服务层,而在服务层中又可以按照是否与业务相关,分为业务服务层和基础服务层。

其中业务服务层是原有各个子系统中抽象出来的可以被充分重用的服务模块,原有借款人门户中普惠金融的业务逻辑可以剥离为普惠金融服务,同时由专门的团队对其进行维护。作为服务,它有着独立的 Oracle 数据库进行存储,相类似的贷后催收也都有相应的服务来进行支撑,拥有独立的团队以及独立的数据存储。

而在最下方的基础服务层,则是抽象出一个与业务无关的底层的基础设施。例如数据同步服务、配置中心服务、全文检索服务它都是面向所有服务对外暴露的。

以上就是改造后的微服务架构。那么,分布式系统传统的问题是如何通过微服务架构解决的,咱们分别来看。

首先,微服务架构提供了轻松而统一的进程间通信标准。以信审与贷后系统的通信为例,之前采用 WebService,要求客户端和服务端必须持有相同的通信对象。在改为 RESTful 通信后,RESTful 是基于 HTTP 协议的轻量级通信方式。它并不强制要求客户端一定持有通信对象,可以使用 Java 中的 HttpClient或者 OkHttp 组件,发起标准的 HTTP 请求就可以通信,返回的数据也是标准的 JSON 结构。对于这样的通信形式,在我们实际使用时,如果单纯由服务端进行了响应数据的扩展,在后续通信时是并不强制要求调用端必须对代码进行升级,服务端与调用端是彼此兼容的。

图片7.png

RESTful 消息通信

其次,屏蔽分布式应用的应用复杂度,假设贷后服务额外增加了两个节点,对于微服务架构来说,它有一个关键组件名为注册中心,下面是具体的执行顺序:

  1. 信审服务和贷后服务,它在启动时会将服务可用的节点的 IP 以及相应状态在注册中心中进行登记。

  2. 当信审服务向贷后服务发起调用通知之前,首先信审服务从注册中心中获取贷后服务可用的 IP 列表。

  3. 信审服务根据某种负载均衡规则,向具体的节点发起 HTTP 请求来完成业务的处理。

因为所有的 IP 地址以及节点的状态都是由注册中心来维护的,所以信审服务作为使用者,是不需要了解贷后服务有具体哪些节点的。这就有效地降低了分布式应用之间的耦合,提高了程序的可维护性。

图片8.png

基于“注册中心”的动态发现机制

第三,内建链路跟踪体系。在传统的分布式应用中,要梳理服务间的调用关系,实际是一件很烦琐的事情。到了微服务体系下,这个问题就很好解决。因为微服务标准中提供了链路跟踪的技术实现。以当前为例,有三个服务 A、B、C,如图所示,ABC 三个服务之间的调用顺序以及调用时长一目了然。通过可视化的形式,可以直观了解服务间的通信过程以及通信的状态,帮助我们对程序进行进一步的管理。

图片99.png

内建链路跟踪体系

第四,是减少重复建设,基础数据管理更加集中。在微服务体系中,这里有一个用户认证中心的服务,其本意在前端应用实际发起请求前,对用户的身份和权限来进行判断。不同系统用户认证的过程都是类似的,我们把它抽象出一个通用的用户认证中心,这样做不但可以减少每一个子系统的重复建设,还可以将用户这个信息来进行集中的统一存储。

第五,更有弹性的架构设计。假如借款人门户需要全文检索的支持,那么与之对应的普惠金融服务中,便可以为其专门增加 Elasticsearch 来进行支持。对于某一个服务加入新的特性,并不影响其他服务的运行。

图片1010.png

“专物专用”的弹性架构

之后随着业务的不断演化,其他服务假如也需要 Elasticsearch 全文检索的话,这时我们便可以进行进一步抽象。剥离出"全文检索服务"基础服务,来为其他服务提供支撑。因为在微服务架构中,我们采用了统一的标准来进行开发,所以它的升级改造工作难度比较小。

图片1111.png

下沉为基础服务

可以看到引入微服务后因为有了统一的分布式应用标准,以往的分布式系统各种问题都可以得到较好的解决。

小结与预告

微服务架构是目前构建互联网应用的主流解决方案,本节课我们总结了微服务的三大特点:

  • 基于业务、可重用的、职责明确的小型服务。

  • 统一的通信标准,轻量级的通信协议。

  • 可独立运行,独立存储由独立团队进行维护。

与此同时,还通过案例分析的方式讲解了微服架构解决了哪些传统分布式应用的弊端。

这里给你留一道思考题:《人月神话》一书中反复提到“世界上没有银弹”,任何架构都有自己的缺点。请你思考,在引入微服务架构后会产生哪些新的问题呢?

在下一课时,我们将对微服务在设计与实践过程中会遇到哪些新问题展开讨论,并逐一通过技术或者管理手段解决这些新问题。


02 经验教训:微服务设计时的五条宝贵经验

前文我们探讨了什么是微服务,尽管微服务架构有着高度独立的软件模块、单一的业务职责、可灵活调整的技术栈等优点,但也不能忽视它所带来的弊端,本节我们将针对引入微服务架构后带来的新问题展开讨论,并分享一些我在微服务实践中的心得。

微服务架构的新挑战

在著名软件著作《人月神话》中提到,软件世界没有“银弹”,这句话当然适用于架构领域,随着从单体架构过渡到微服务架构,因为将原有系统打散,给系统增加了许多不稳定因素。

图片1.png

单体架构向微服务架构转变

下面我从网络、性能、运维成本、组织架构与集成测试五个方面分别进行阐述。

第一点,跨进程通信带来的新问题。 以往单体应用是在单机中进行进程内通信,通信稳定性相当好。但是打散为分布式系统后,变为进程间通信,往往这个过程还伴随着跨设备的网络访问,架构师在设计时必须考虑上下游系统因为网络因素无法通信的情况,要假设网络是不可靠的,并设计微服务在网络异常时也能进行符合预期的异常处理。以支付模块为例,用户支付成功后系统自动调用短信服务向用户手机发送“订单支付成功”的消息,此时架构师就必须假设短信服务在服务或者网络不可用时不会影响到订单业务的正常执行。

图片2.png

微服务间跨进程RESTful调用

第二点,较高的响应延迟。 相比传统单体架构进程内通信,跨进程、跨网络的微服务通信在网络传输与消息序列化带来的延迟是不可被忽略的,尤其是在五个以上微服务间消息调用时,网络延迟对于实时系统的影响是很大的。早些年我和军事院校合作了一个雷达仿真训练的系统,因为要模拟“导弹打飞机”的场景,在计算飞行轨道时1毫秒的响应增加都可以会影响到最终的结果,显然这类系统采用分布式设计就不再合适。

图片3.png

雷达指挥训练系统流程

第三点,运维成本会直线上升。 早期单体应用因为结构简单,规模也较小,发版时通常面对几台服务器部署几个Jar/War文件就可以了。同时,应用的交付周期也是以周甚至月为单位,此时硬件设备成本与运维人员技术要求都比较低,采用手动部署即可满足要求。而对于微服务架构而言,每一个服务都是可独立运行、独立部署、独立维护的业务单元,再加上互联网时代用户需求的不断变化以及市场的不稳定因素,运维人员每天面对成百上千台服务器发布几十次已是家常便饭,传统手动部署显然已经无法满足互联网的快速变化。

图片4.png

京东 JDOS 自动化运维架构图

第四点,组织架构层面的调整。 微服务不但是一种架构风格,同样也是一种软件组织模型,以往软件公司会以职能划分研发、测试、运维部门进行独立管理考核,而在微服务的实施过程中,是以业务模块进行团队划分,每一个团队是内聚的,要求可以独立完成从调研到发版的全流程,尽量减少对外界的依赖。如何将传统的职能团队调整为按业务划分的研发团队,同样是对管理者的巨大挑战,要知道人的思想比架构更难改变。

图片5.png

独立的全生命周期研发团队

第五点,服务间的集成测试变得举步维艰。 传统单体架构集成测试是将不同的模块按业务流程进行组合,在进程内验证每一种可能性下其模块间协作是否符合预期即可。但对于微服务而言,系统被拆解为很多独立运行的单元,服务间采用接口进行网络通信。要获取准确的测试结果,必须搭建完整的微服务环境,光这一项就需要花费大量的人力物力。同时,因为微服务是跨网络通信,网络延迟、超时、带宽、数据量等因素都将影响最终结果,测试结果易产生偏差。

微服务最佳实践

刚刚我们总结了引入微服务架构的一些新挑战,下面我将结合自己多年的微服务落地经验,总结出五点微服务架构最佳实践,希望能对你日后的工作提供帮助。

第一点,微服务的划分原则。 将已有系统拆分为多个微服务,本就没有统一的标准。举个例子,一个初创电商公司,要开发一套电商系统,将“促销活动”单独剥离出来作为“促销服务”是没有问题的。但是如果在“淘宝”“京东”这种体量的电商平台,“促销服务”就显得粒度太粗了。可以继续拆解为“价格服务”“优惠券服务”“京豆服务”等更细粒度的小服务,每个服务有专门团队负责维护。

图片6.png

京东商城的微服务业务划分

因此,在微服务拆分过程中,我们通常会从业务场景、团队能力、组织架构等多种因素综合考虑,这特别考验架构师的业务能力。一般来说,我们总结出几点通用原则:

  • 单一职责原则。 每一个微服务只做好一件事,体现出“高内聚、低耦合”,尽量减少对外界环境的依赖。比如,在公司创业之初,完全可将订单与仓储服务进行合并。因为订单与仓储在业务与数据上紧密相关,如果强行拆分会导致出现跨进程通信带来的数据一致性难题。随着业务的发展,仓储的业务职责扩展,派生出许多与订单无紧密联系的功能,到时再将其剥离形成独立的“仓储服务”。

  • 服务依赖原则。 避免服务间的循环引用,在设计时就要对服务进行分级,区分核心服务与非核心服务。比如订单服务与短信服务,显然短信服务是非核心服务,服务间调用要遵循“核心服务”到“非核心服务”的方向,不允许出现反向调用。同时,对于核心服务要做好保护,避免非核心服务出现问题影响核心服务的正常运行。

  • Two Pizza Team原则。 就是说让团队保持在两个比萨能让队员吃饱的小规模的概念。团队要小到让每个成员都能做出显著的贡献,并且相互依赖,有共同目标,以及统一的成功标准。一个微服务团队应涵盖从设计到发布运维的完整生命周期,使团队内部便可以解决大部分任务,从人数上4~6人是比较理想的规模。

Drawing 6.png

Two Pizza Team

第二点,为每一个微服务模块明确使命。 这里推荐一套标准的微服务叙述模板,集中体现“只做好一件事”的原则。

模板
XX 微服务用来
在出现痛点场景的情况下
解决现有的 XX 问题
从而达到了 XXX 的效果
体现了微服务的价值
示例
商品检索微服务用来
在商品数据全量多维度组合查询的情况下
解决了 MySQL 数据库全表扫描查询慢的问题
从而让查询响应降低到 50ms 以下
有效提升了用户体验

通过这种描述,服务的职责与边界就十分明确,团队便以此为目标确认职责。在实施过程中因为我们是以解决问题为目标,切分时可能会比较细碎。经过漫长时间沉淀,系统中出现了类似于“商品检索服务”“订单检索服务”“商铺检索服务”等多个小服务,这时可以对这些服务形成聚合生成新的“通用检索服务”,以此来控制微服务的整体规模。反之,对于庞大的服务,可以考虑拆分为多个小服务进行细粒度的管理。总之,拆与合是伴随着公司业务的演进而变化的,一切以解决问题为准。

第三点,微服务确保独立的数据存储。 数据是任何系统最重要的资产。以往单体应用通常会选择 MySQL 这种关系型数据库作为数据的唯一存储,这样做的好处是涉及多表操作时,利用数据库自带的事务机制便可最大程度保证数据完整性。但这样做却存在诸多问题,以下图为例,不同的微服务对数据存储的需求也是不同的,订单服务需要 MySQL 数据保存订单与订单明细;新闻服务需要Elasticsearch提供全文检索支持;朋友圈需要图数据库表达现实世界人际关系;文件存储服务则需要分布式文件系统。如果将所有数据都揉在 MySQL 中使用会变得十分蹩脚,好的做法是为每一个微服务提供符合自身业务特性的数据库。

图片7.png

独立的数据存储

但理想很丰满现实很骨感,在分库后涉及跨库操作会变的难以处理。比如,订单依赖会员数据,原本单库处理时一条 SQL 语句便可实现。

SELECT order.* , member.* FROM order,member WHERE order.member_id = member.member_id

但在微服务架构下,因为数据库绝不允许其他团队访问,关联查询只能变为 API 调用形式,程序实现层面比单库复杂不少。

图片8.png

通过 RESTful 通信实现数据关联

与之类似,如果涉及多表写入时一致性问题更复杂。

BEGIN ;
写入表A;
写入表B;
COMMIT;

在拆分为服务后,数据被分散到多库,为保证异构多库的数据一致性是所有分布式应用的巨大挑战,至今没有完美的解决方案,这块内容我在后面课程单独做一个专题进行讲解。

第四点,服务间通信优先采用聚合器模式。在微服务间通信时存在两种消息传递模式:链式模式聚合器模式。下图所展示的是链式模式,请求按业务流程在各个服务间流转,最终处理完成返回客户端。

图片9.png

链式模式

因为请求是按业务流程传递,很容易能被开发人员理解,链式模式成为最常用的服务间通信模式。但链式模式采用串联模式,调用的整体成功率等于单个服务成功率的乘积,假设每个服务可靠性为 90%,一个业务在 4 个服务执行后的最终成功率只有 90%*90%*90%*90%≈66%,有将近一半的请求会处理失败,这是无法接受的。此外,链式模式因默认采用同步方式传输,在服务处理完成前应用会一直处于阻塞状态,当调用链较长时,系统整体性能会严重下滑。

聚合器模式则是通过服务作为入口,组装其他服务的调用。以下图为例,因为“订单流程服务”是将其他服务进行聚合操作,所以称其为聚合器模式。以“订单流程服务”为例,将“订单”“支付”“库存”服务进行聚合,一个服务实现了下单、支付、减库存的完整流程。

图片10.png

聚合器模式

采用聚合器模式后,业务流程与编排集中在“订单流程服务”中,可对整体业务进行有效编排,支付与扣库存可以并行调用,可以有效提高系统的性能。

第五点,不要强行“微服务”化。 在以前公司任职时因为业务需要,要开发一个工单系统让售后人员在线为客户提供售后服务,但当时因为公司产品已经非常成熟,每天产生的工单只有几十笔,如果做成单体应用配合 Nginx 反向代理,从存储到应用便能满足需求。此任务分配给一位“年轻”的架构师,可能是为了证明实力,他采用了全套微服务技术来“炫技”,并在会议上侃侃而谈。结果老板反问他“你这么设计有必要么,为一个工单系统投入超过10台服务器成本你考虑了吗?” ,当时那场景别提多尴尬了。其实在我看来,微服务也不过是一种方案,没必要盲从。它也没有违背架构的基本规律:架构是解决当前需求和痛点而演进的。在满足需要的前提下,选择合适的而不是选择最好的,合理降低成本才是好架构师该考虑的事情。

以上微服务的经验都是我在实际工作中总结归纳出来的,如有不足的地方欢迎同学们在评论中给予补充。

微服务架构的适用场景

本节最后一部分,我总结了适合微服务使用场景,首先咱们梳理下适合做微服务的场景:

  • 新规划的大型业务系统, 这肯定是最适合引入微服务架构的情况了, 微服务强调“高内聚,低耦合”,每一个团队负责一个服务,这就意味着从根本上和传统的整体性应用有本质不同,从规划阶段采用微服务架构是再好不过的。

  • 敏捷的小团队系统,公司在大型项目微服务实践前,往往这类边缘化的小项目会起到“试验田”的作用, 引入快速迭代、持续交付等模式,积累适合本公司特点的微服务实践经验,再将这些经验扩大到其他大型项目中。

  • 历史的大型留存业务系统,之前多年我一直在金融软件领域工作,在银行内部许多系统已经使用超过10年时间,成百上千个模块错综复杂维护愈发困难,无论架构、框架乃至技术人员都需要更新迭代,但都不可能一次大动手术,这时微服务的“微”就体现出来,重构时可以将某一个部分剥离为微服务独立运行,确保无误后再继续剥离出下一个服务,通过抽丝剥茧一般的剥离,逐步将原有大系统剥离为若干子服务,虽然过程十分痛苦,但这是必须做的事情。

下面咱们再来列举几个不适合引入微服务的场景:

  • 微型项目,前面提到的工单系统,系统压力很小,需求变化也不大,利用单体架构便可以很好解决,使用分布式架构反而增加了架构复杂度,让系统更容易不稳定。

  • 对数据响应要求高的系统,就像前面文中提到的“导弹打飞机”的科研项目,对实时性要求极高,那显然是不合适的。

小结与预告

从本课时开始,我们针对引入微服务架构后带来的诸多新问题进行了分析,之后给出了多条微服务架构最佳实践,最后总结了微服务架构的使用场景。

这里给你留一道思考题:微服务架构作为一种设计风格,必须要依托具体的技术与开发框架才可以实施落地,那你能列举出具体包含哪些技术吗?

在接下来的课程中,我们将 Spring Cloud 与 Spring Cloud Alibaba 微服务生态进行分解,了解每一个技术组件的职能与用法。


03 顶层设计:微服务生态与 Spring Cloud Alibaba

之前的课程我分享了微服务在生产实践中的一些经验教训,但我也强调微服务架构是一种风格,需要具体的技术来支撑,而在 Java 领域微服务是如何实现的?本讲我将通过下面三个方面来阐述:

  • 通用的微服务架构应包含哪些组件;

  • Spring Cloud 是如何支撑微服务架构的;

  • 我为什么强烈推荐 Spring Cloud Alibaba?

通用的微服务架构应包含哪些组件

相对于单体式架构的简单粗暴,微服务架构将应用打散,形成多个微服务进行独立开发、测试、部署与运维。虽然从管理与逻辑上更符合业务需要,但微服务架构也带来了诸多急需解决的核心问题:

  1. 如何发现新服务节点以及检查服务节点的状态?

  2. 如何发现服务及负载均衡如何实现?

  3. 服务间如何进行消息通信?

  4. 如何对使用者暴露服务 API?

  5. 如何集中管理众多服务节点的配置文件?

  6. 如何收集服务节点的日志并统一管理?

  7. 如何实现服务间调用链路追踪?

  8. 如何对系统进行链路保护,避免微服务雪崩?

可以发现,上述这些问题并不是针对某种语言或某种技术的,任何软件厂商要构建微服务架构就必须面对这些问题,要么独立开发要么将已有多种技术整合形成整体解决方案。好在经过多年沉淀,业内已经有了标准答案,下图清晰的说明微服务架构需要的标准组件。

图片1.png

微服务架构标准组件

下面我来介绍每种组件的职责。

  • 注册中心(Service Registry):注册中心是微服务架构最核心的组件。它起到新服务节点的注册与状态维护的作用,通过注册中心解决了上述问题 1。微服务节点在启动时会将自身的服务名称、IP、端口等信息在注册中心中进行登记,注册中心会定时检查该节点的运行状态。注册中心通常会采用心跳机制最大程度保证其持有的服务节点列表都是可用的。

图片2.png

服务注册流程

  • 负载均衡(Load Balance):负载均衡器解决了问题 2。通常在微服务彼此调用时并不是直接通过IP、端口直接访问,而是首先通过服务名在注册中心查询该服务拥有哪些可用节点,然后注册中心将可用节点列表返回给服务调用者,这个过程称为“服务发现”。因服务高可用的要求,服务调用者会接收到多个可用节点,必须要从中进行选择,因此在服务调用者一端必须内置负载均衡器,通过负载均衡策略选择适合的节点发起实质的通信请求。

图片3.png

服务发现与负载均衡

  • 服务通信(Communication):服务通信组件解决了问题 3。在微服务定义中阐述服务间通信采用轻量级协议,通常是 HTTP RESTful 风格。但因 RESTful 风格过于灵活,必须加以约束,通常在应用时对其进行上层封装,例如在 Spring Cloud 中就提供了 Feign 和 RestTemplate 两种技术屏蔽底层实现 RESTful 通信细节,所有开发者是基于封装后统一的SDK进行开发,这有利于团队间协作。

  • API 服务网关(API Gateway):服务网关解决问题 4。对于最终用户来说,微服务的通信与各种实现细节应该是透明的,用户只需关注他要使用的 API 接口即可。因此微服务架构引入服务网关控制用户的访问权限。服务网关是外部环境访问内部微服务的唯一途径,在这个基础上还可以扩展出其他功能,例如:用户认证与授权、容错限流、动态路由、A/B测试、灰度发布等。

图片4.png

API 服务网关

  • 配置中心(Config Management):配置中心解决问题 5。微服务架构下,微服务节点都包含自己的各种配置文件,如JDBC地址、自定义配置、环境配置等。要知道互联网公司微服务节点可能是成千上万个,如果这些配置信息分散存储在节点上,如发生配置变更就必须逐个调整,这必将给运维人员带来巨大的工作量。配置中心便因此而生,通过部署配置中心服务器,将原本分散的配置文件从应用中剥离,集中转存到配置中心。一般配置中心会提供 UI 界面,可以方便快捷的实现大规模集群的配置调整。

图片5.png

庞杂而重复的配置文件

图片6.png

引入配置中心集中管理配置

  • 集中式日志管理(Centralized Logging):集中式日志解决问题 6。因为微服务架构默认将应用日志分散保存在每一个微服务节点上,当系统进行用户行为分析、数据统计时必须收集所有节点日志数据。那如何有效收集所有节点的运行日志,并对其进行分析汇总呢?业内常见的方案有 ELK、EFK,通过搭建独立的日志收集系统,定时抓取增量日志形成有效的统计报表,为决策提供数据支撑。

图片7.png

ELK 日志手机系统

  • 分布式链路追踪(Distributed Tracing):分布式追踪解决问题 7。一个复杂的业务流程可能需要连续调用多个微服务,我们需要记录一个完整业务逻辑涉及的每一个微服务的运行状态,再通过可视化链路图展现,帮助软件工程师在系统出错时分析解决问题。

图片8.png

微服务链路追踪

图片9.png

Zipkin 链路图

  • 服务保护(Service Protection):服务保护解决问题 8。在服务间通信过程中,如果某个微服务出现响应高延迟可能会导致线程池满载,严重时会引起系统崩溃。这里就需要引入服务保护组件实现高延迟服务的快速降级,避免系统崩溃。

以上是在微服务架构过程中派生的新问题以及对应的解决方案,这些组件是微服务架构设计时必须考虑的事情。在实现层面,Java 是目前对微服务生态支持最好的编程语言,下面我们就来介绍在Java中如何实现微服务架构的。

Spring Cloud 是如何支撑微服务架构的

在 Java 领域可以说 Spring 无人不知无人不晓,我们现代的企业级应用与互联网应用,绝大多数都是构建在 Spring 这个生态体系上。同样的,Spring Cloud 也是在 Spring 基础上生根发芽的。

Drawing 9.png

Spring Cloud 微服务介绍

下面这张图很好地诠释了 Spring、Spring Boot、Spring Cloud 它们之间的关系。

Spring 是整个微服务开发生态的基石,在此基础上 Spring 经过封装和简化,形成了Spring Boot 敏捷开发框架,而 Spring Cloud 开发微服务则必须掌握 Spring Boot,如果此时你对Spring 以及 Spring Boot 还不了解,可以在拉勾教育找到相关课程补充学习。

Spring Cloud 提供了完整的微服务架构的技术生态,像刚才我们提到的微服务架构标准组件,在 Spring Cloud 中都有着对应的实现。

Drawing 10.png

Spring Cloud 内置组件

不过这里有一点需要注意,Spring Cloud 并不是完全由 Spring 机构自主开发的,秉持不重复造轮子的理念,Spring 机构整合了多家厂商的优秀开源产品,比如注册中心就选用了 Netflix 的 Eureka,在此基础上进行整合形成了完整的 Java 微服务架构解决方案。刚才我们列举出来的 8 个微服务的标准组件在 Spring Cloud 中都有对应的具体实现,值得注意的是同一类组件 Spring Cloud 可能给出多种不同的开源产品供我们选择,这些产品在 Spring Cloud 下是彼此兼容的。

图片13.png

以上是 Spring Cloud 的主要组成部分,这里还有许多没有提到的功能组件,如果你对此感兴趣,可以到 Spring Cloud 官网(https://spring.io/projects/spring-cloud)了解更详细的内容。

仔细看上面的表格,你会发现其中问题,正是因为 Spring Cloud 是集众家所长,但这也受制于第三方厂商的约束。以 Zuul 为例,Netflix 宣布停止维护,Spring 机构便不得不寻找替代品或者自行研发。与此同时,Spring Cloud 作为国外产品引入国内后也出现了水土不服,例如 Spring Cloud Config 默认将配置文件转存在Github仓库,但国内开发商并不喜欢这种做法,他们更希望将这些配置信息存储到自己的数据库中。因此,阿里巴巴在原有 Spring Cloud 基础上,结合阿里巴巴多年的开源技术沉淀,设计了更符合国情的 Spring Cloud Alibaba。

功能更强大的国产微服务生态Spring Cloud Alibaba

Spring Cloud Alibaba是直接隶属于 Spring Cloud 的子项目。官网是:https://spring.io/projects/spring-cloud-alibaba#overview

Spring Cloud Alibaba是国产的微服务开发一站式解决方案,与原有 Spring Cloud 兼容的同时对微服务生态进行扩展,通过添加少量的配置注解,便可实现更符合国情的微服务架构。

Drawing 11.png

下面是 Spring Cloud 与 Spring Cloud Alibaba 的对比表格。

图片14.png

我将两者从不同维度进行比对,可以发现相比 Spring Cloud,Spring Cloud Alibaba 对服务注册、配置中心与负载均衡功能都整合进 Nacos,这样简化了微服务架构的复杂度,出问题的概率也会降低。原有的服务保护组件也调整为 Sentinel,相较Hystrix功能更强大,使用也更加友好。在表格最下方也可看到 Spring Cloud Alibaba 基于阿里云强大的能力提供了更多的新特性,很多复杂的应用场景通过 Spring Cloud Alibaba 结合阿里云便可轻松实现。在后面的内容,我们以这个表格作为主线对组件进行逐一讲解,让你轻松掌握各组件用法与设计原理。

小结与预告

本节我们讲解了微服务架构应包含哪些标准组件,同时介绍了 Java 的 Spring Cloud 解决方案,最后我们通过技术栈比对,使你对 Spring Cloud Alibaba 解决方案有了整体的认知。

这里给你留一道思考题:如果公司领导让你带领团队开发三方支付平台,峰值 TPS 过万,请你列出这个系统架构将首要解决的三个最主要的重难点,欢迎你把思考后的结果发布在评论中。

在接下来的课程中,我们将接触到 Spring Cloud Alibaba 体系最重要的核心组件 Nacos,了解 Nacos 的使用方法与设计原理。


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

办公模板库 素材蛙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值