共计 6452 个字符,预计需要花费 17 分钟才能阅读完成。
本章从架构倒退的角度来形容技术的倒退过程,依据不同阶段所面临的问题来推动架构的演变,从而更好地了解微服务的实质以及它所带来的的益处,本章内容次要会通过架构的演进过程帮忙大家建设一个整体意识,从而更好地把握微服务体系。
1.1 从单体架构到微服务架构的演进
1.1.1 单体架构
通过咱们之前的学习,咱们开发一个一个 Web 我的项目,能够应用 Spring、SpringMVC、Mybatis 等技术。比方之前的快递驿站我的项目,旅游网我的项目 SSM 版,账单治理我的项目等,我的项目构造如下图 1 - 1 所示。
图 1 -1 单体架构
整个零碎的架构非常简单,应用 Spring+SpringMVC+Mybatis 构建一个根底工程、MySQL 数据库作为长久化存储,在这个工程中创立不同的 Service 实现商场中不同的业务场景,如线路、线路分类、用户等。最初把我的项目构建成一个 war 包部署在 Tomcat 容器上即可应用,这时咱们之前常常采纳的架构。
通常来说,如果一个 war 包或者 jar 包外面蕴含一个利用的所有性能,则咱们称这种架构为单体架构。
很多传统互联网公司或者守业型公司晚期根本都会采纳这样的架构,因为这样的架构足够简略,可能疾速开发和上线。而且对于我的项目初期用户量不大的状况,这样的架构足以撑持业务的失常运行。
1.1.2 集群和垂直化
以商城零碎为例。随着业务的倒退,产品被越来越多的人应用,那么对于整个技术架构来说,可能会面临以下挑战:
用户量越来越大,网络访问量一直增大,导致后端服务器的负载越来越高。
用户量大了,产品须要满足不同用户的需要来留住用户,使得业务场景越来越多并且越来越简单。
当服务器的负载越来越高的时候,如果不进行任何解决,用户在网站上操作的响应会越来越慢,甚至呈现无法访问的状况,对于十分重视用户体验的互联网产品来说,这是无奈容忍的。
业务的场景越多越简单,意味着 war 包中的代码量会持续上升,并且各个业务代码之间的耦合度也会越来越高,前期的代码保护和版本公布波及的测试和上线,也会很困那。举个最简略的例子,当你须要在库存模块外面增加一个办法时,带来的影响是须要把整个零碎从新测试和部署,而当一个 war 包有几 GB 的大小时,部署的过程也是相当苦楚的。
因而,咱们能够从两个方面进行优化:
通过横向减少服务器,把单台机器变成多台机器的集群。
依照业务的垂直畛域进行拆分,缩小业务的耦合度,以及升高单个 war 包带来的伸缩性艰难问题。
如图 1 - 2 所示,咱们把商城零碎依照业务维度进行了垂直拆分:用户子系统、库存子系统、商品子系统,每个子系统由不同的业务团队负责保护并且独立部署。同时,咱们针对 Tomcat 服务器进行了集群部署,也就是把多台 Tomcat 服务器通过网络进行连贯组合,造成一个整体对外提供服务。这样做的益处是可能在扭转利用自身的前提下,通过减少服务器来进行程度扩容从而晋升整个零碎的吞吐量。
须要留神的是,图 1 - 2 中针对数据库进行了垂直分库,次要是思考到 Tomcat 服务器可能承载的流量大了之后,如果流量都传导到数据库上,会给数据库造成比拟大的压力。
总体来说,数据库层面的拆分思维和业务零碎的拆分思维是一样的,都是采纳分而治之的思维。
图 1 -2 集群及垂直化之后的架构
1.1.3 SOA
为了让大家更好地了解 SOA,咱们来看两个场景:
假如一个用户执行下单操作,零碎的解决逻辑是先去库存子系统检杳商品的库存,只有在库存足够的状况下才会提交订单,那么这个查看库存的逻辑是放在订单子系统中还是库存子系统呢?在整个零碎中,肯定会存在十分多相似的共享业务的场景,这些业务场景的逻辑必定会被反复创立,从而产生十分多冗余的业务代码,这些冗余代码的保护老本会随着工夫的推移越来越高,能不能够把这些共享业务逻辑抽离进去造成可重用的服务呢?
在一个集团公司下有很多子公司,每个子公司都有本人的业务模式和信息积淀,各个子公司之间不进行交互和共享。这个时候每个子公司尽管可能发明肯定的价值,然而因为各个子公司之间信息不是互联互通的,彼此之间造成了信息孤岛,使得价值无奈最大化。
基于这些问题,就引入了 SOA(Service-Oriented Architecture), 也就是面向服务的架构,从语义上说,它和面向过程、面向对象、面向组件的思维是一样的,都是一种软件组建及开发的形式。外围指标是把一些通用的、会被多个下层服务调用的共享业务提取成独立的根底服务。这些被提取进去的共享服务相对来说比拟独立,并且能够重用。所以在 SOA 中,服务是最外围的形象伎俩,业务被划分为一些粗粒度的业务服务和业务流程。
如图 1 - 3 所示,提取出了用户服务、库存服务、商品服务等多个共享服务。在 SOA 中,会采纳 ESB(企业服务总线)来作为零碎和服务之间的通信桥梁,ESB 自身还提供服务地址的治理、不同零碎之间的协定转化和数据格式转化等。调用端不离要关怀指标服务的地位,从而使得服务之间的交互是动静的,这样做的益处是实现了服务的调用者和服务的提供者之间的高度解耦。总的来说,SOA 次要解决的问题是:
信息孤岛。
共享业务的重用。
图 1 -3 SOA 架构
1.1.4 微服务架构
业务系统实施服务化革新之后,本来共享的业务被拆分造成可复用的服务,能够在最大水平上防止共享业务的反复建设、资源连贯瓶颈瓶颈等问题。那么被拆分进去的服务是否也须要以业务性能为维度来进行拆分和独立部署,以升高业务的耦合及晋升容错性呢?
微服务就是这样一种解决方案,从名字上来看,面向服务(SOA)和微服务实质上都是服务化思维的一种体现。如果 SOA 是面向服务开发的思维的雏形,那么微服务就是针对可重用业务服务的更进一步优化,咱们能够把 SOA 看成微服务的超集,一但服务规模扩充就意味着服务的构建、公布、运维的复杂度也会成倍增加,所以施行微服务的前提是软件交付链路及基础设施的成熟化。因而微服务在我看来并不是一个新的概念,他实质上是服务化思维的最佳实际方向。因为 SOA 和微服务两者的关注点不一样,造成了这两者有十分大的区别:
SOA 关注的是服务的重用性及解决信息孤岛问题。
微服务关注的是解耦,尽管解耦和可重用性从特定的角度来看是一样的,但实质上是有区别的,解耦是升高业务之间的耦合度,而重用性关注的是服务的复用。
微服务会更多地关注在 DevOps 的继续交付上,因为服务粒度细化之后使得开发运维变得更加重要,因而微服务与容器化技术的联合更加严密。
如图 1 - 4 所示,将每个具体的业务服务形成可独立运行的微服务,每个微服务只关注某个特定的性能,服务之间采纳轻量级通信机制 REST API 进行通信。仔细的读者会发现 SOA 中的服务和微服务架构中的服务粒度是一样的,不是说 SOA 是微服务的超集吗?其实咱们能够把用户服务拆分的更细,比方用户注册服务、用户鉴权服务等。实际上,微服务到底要拆分到多大的粒度没有对立的规范,更多的时候是须要在粒度和团队之间找均衡的,微服务的粒度越小,服务独立性带来的益处就越多,然而治理大量的微服务也会越简单。
图 1 -4 微服务
1.2 微服务简介
比方咱们网上购物,首先应该去购物网站搜寻商品,这个搜寻性能就能够开发成一个微服务。咱们也能够看到相干商品的举荐,这些举荐项也能够是一个微服务。前面比方退出购物车、下订单、领取等性能都能够开发成一个一个的独立运行的微服务。
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
— James Lewis and Martin Fowler (2014)
对这段话的了解,总结微服务应具备如下特点。
微服务是一种架构格调。
微服务把一个利用拆分为一组小型服务。
微服务每个服务运行在本人的过程内,也就是可独立部署和降级。
微服务的服务之间应用轻量级 HTTP 交互,个别应用 Json 替换数据。
服务围绕业务性能拆分。
能够由全自动部署机制独立部署。
去中心化,服务自治。服务能够应用不同的语言、不同的存储技术。
1.2.1 微服务框架性能
微服务具备以上的这些特点,那么作为一个微服务框架,比方 Spring Cloud,应该具备一些什么性能呢?微服务框架的性能次要体现在以下几个方面。
注册核心:服务提供者和消费者,可能从注册核心注册和失去服务信息。
配置核心:在微服务架构中设计服务较多须要对于配置文件对立治理。
服务链路追踪:对于服务之间的负载调用,要能通过链路追踪,失去具体参与者,调用链路呈现问题可能疾速定位。
负载平衡:服务调用服务会采纳肯定的负载平衡策略,来保障服务的高可用。
服务容错:通过熔断、降级服务容错策略,对系统进行无效的爱护,降级是在服务或依赖的服务异样时,返回保底数据,熔断是指依赖服务屡次生效,则熔断器关上,不再尝试调用,间接返回降级信息。熔断后,定期探测依赖服务可用性,若复原则复原调用。
服务网关:用户申请过载时进行限流、排队、过载爱护、黑白名单、异样用户过滤拦挡等都能够通过服务网关实现。
服务公布与回滚:蓝绿部署、灰度、AB Test 等公布策略,可疾速回滚利用。
服务动静伸缩、容器化:依据服务负载状况,可疾速手动或主动进行节点减少和缩小。
1.2.2 Spring Cloud 简介
Spring Cloud 是 Spring 提供的微服务框架。它利用 Spring Boot 的开发个性简化了微服务开发的复杂性,如服务发现注册、配置核心、音讯总线、负载平衡、断路器、数据监控等,这些工作都能够借助 Spring Boot 的开发格调做到一键启动和部署。
Spring Cloud 的指标是通过一系列组件,帮忙开发者迅速构件一个分布式系统,Spring Cloud 是通过包装其它公司产品来实现的,比方 Spring Cloud 整合了开源的 Netflix 很多产品。Spring Cloud 提供了微服务治理的诸多组件,例如服务注册和发现、配置核心、熔断器、智能路由、微代理、管制总线、全局锁、分布式会话等。
Spring Cloud 组件十分多,波及微服务开发的诸多场景,本节次要介绍 Spring Cloud 以及最为根底的 Spring Cloud 五大组件,后续在进行具体的学习。Spring Cloud 的架构图如图 1 - 5 所示。
图 1 -5 Spring Cloud 架构
Spring Cloud 实现微服务的治理性能产品很多,上面简略介绍下 Spring Cloud 各个产品的作用,以及采纳的准则,如图 1 - 6 所示
图 1 -6 微服务产品
1.2.3 Spring Cloud 版本
Spring Cloud 和 Spring Boot 版本对应关系如下:
Spring Cloud Spring Boot
2020.0.x aka Ilford 2.4.x, 2.5.x (Starting with 2020.0.3)
Hoxton 2.2.x, 2.3.x (Starting with SR5)
Greenwich 2.1.x
Finchley 2.0.x
Edgware 1.5.x
Dalston 1.5.x
官网对版本进行如下解释
Spring Cloud Dalston, Edgware, Finchley, and Greenwich have all reached end of life status and are no longer supported.
Spring Cloud Dalston、Edgware、Finchley 和 Greenwich 都已达到生命周期终止状态,不再受反对
因而课程采纳的 Spring Cloud,Spring Boot 版本。
Spring Boot 2.4.9
Spring Cloud 2020.0.3
Spring Cloud Alibaba 2021.1
1.3 搭建微服务工程
接下来模仿一个微服务调用的场景,有两个微服务,一个订单微服务,一个领取微服务,订单微服务通过 RestTepleate 调用领取微服务,实现领取性能。
领取微服务工程:服务提供者
订单微服务工程:服务使用者。
1.3.1 公共工程
应用 maven 创立公共工程“03_cloud_common”工程下,对立治理案例应用的实体类和工具类。
pom.xml
Payment
订单和领取工程都应用了 Payment 实体类代码如下。
1.3.2 领取工程
应用 Spring Initializr,创立领取微服务工程 01_cloud_payment,模仿领取。如图 1 - 7 所示。
图 1 -7 Spring Initializr 创立我的项目
留神:默认 https://start.spring.io,常常连不上,能够应用 Custom:https://start.springboot.io 创立。
抉择依赖
抉择上面依赖,如图 1 - 8 所示。
Spring Boot 2.4.8
Spring Boot DevTools
Lombok
Spring Web
图 1 -8 依赖抉择
pom.xml 配置文件如下。
启动器
application.yml
PaymentController
在 PaymentController 中模仿实现领取性能,代码如下。
启动测试
启动我的项目拜访 http://localhost:9001/payment…,成果如图 1 - 9 所示。
图 1 -9 领取测试成果
1.3.3 订单工程
抉择依赖
抉择上面依赖,如图 1 - 8 所示。
Spring Boot 2.4.8
Spring Boot DevTools
Lombok
Spring Web
图 1 -8 依赖抉择
pom.xml 代码如下。
启动器
Spring 提供了一个 RestTemplate 模板工具类,对基于 Http 的客户端进行了封装,并且实现了对象与 json 的序列化和反序列化,十分不便。RestTemplate 并没有限定 Http 的客户端类型,而是进行了形象,目前罕用的 3 种都有反对:
HttpClient
OkHttp
JDK 原生的 URLConnection(默认的)
application.yml
OrderController
启动并测试
启动我的项目拜访 http://localhost:9002/order/p…,成果如图 1 -10 所示。
图 1 -10 订单测试成果
1.3.4 小结和思考
简略回顾一下,方才咱们写了什么:
payment-service:对外提供了领取的接口
order-service:通过 RestTemplate 拜访 http://locahost:9091/order/{id} 接口,调用领取服务
存在什么问题?
在 order 中,咱们把 url 地址硬编码到了代码中,不不便前期保护
order 须要记忆 payment-service 的地址,如果呈现变更,可能得不到告诉,地址将生效
order 不分明 payment-service 的状态,服务宕机也不晓得
payment-service 只有 1 台服务,不具备高可用性
即使 payment-service 造成集群,order 还需本人实现负载平衡
其实下面说的问题,概括一下就是分布式服务必然要面临的服务治理的问题:
服务治理
如何主动注册和发现
如何实现状态监管
如何实现动静路由
服务如何实现负载平衡
服务如何解决容灾问题
服务如何实现对立配置
以上的问题,咱们都将在 SpringCloud 中失去答案。