700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 《深入理解 Spring Cloud 与微服务构建》第一章 微服务简介

《深入理解 Spring Cloud 与微服务构建》第一章 微服务简介

时间:2020-06-28 06:04:17

相关推荐

《深入理解 Spring Cloud 与微服务构建》第一章 微服务简介

《深入理解 Spring Cloud 与微服务构建》第一章 微服务简介

文章目录

《深入理解 Spring Cloud 与微服务构建》第一章 微服务简介一、单体架构及其存在的不足1.单体架构简介2.单体架构存在的不足3.单体架构使用服务器集群及存在的不足二、微服务1.什么是微服务2.微服务单元按业务来划分3.微服务通过 HTTP 来互相通信4.微服务的数据库独立5.微服务的自动化部署6.服务集中化管理7.分布式架构8.微服务的优势三、微服务的不足1.微服务的复杂度2.分布式事务3.服务的划分4.服务的部署四、微服务的设计原则

一、单体架构及其存在的不足

1.单体架构简介

软件设计三层模型

表示层:用于直接和用户交互,也称为交互层,通常是网页、UI 等

业务逻辑层:即业务逻辑处理曾,例如用户输入的信息要经过业务逻辑层的处理后,才能展现给用户

数据访问层:用于操作数据库,用户在表示层会产生大量的数据,通过数据访问层对数据库进行读写操作

经典的单体应用架构

一个典型的单体应用就是将所有的业务场景的表示层、业务逻辑层和数据访问层放在一个工程中,最终经过编译、打包,部署在一台服务器上。例如,将表示层的 JSP、业务逻辑层的 Service、Controller 和 数据访问层的Dao,打包成 war 包,部署在 Tomcat、Jetty 或者其它 Servlet 容器中运行

LAMP 应用服务器

在一个小型应用的初始阶段,访问量较小,应用只需要一台服务器就能够部署所有的资源,例如将应用程序、数据库、文件资源等部署在同一台服务器上。最典型的就是 LAMP 系统,即服务器采用 Linux 系统,开发应用程序的语言为 PHP,部署在 Apache 服务器上,采用 MySQL 数据库。在应用程序的初始阶段,采用这种架构的性价比是非常高的,开发速度快,开发成本低,只需要一台廉价的服务器

2.单体架构存在的不足

业务越来越复杂,单体应用的代码量越来越大,代码的可读性、可维护性和可扩展性下降,新人接手代码所需的事件成倍增加,业务扩展带来的代价越来越大随着用户越来越多,程序承受的并发越来越高,单体应用的并发能力有限测试的难度越来越大,单体应用的业务都在同一个程序中,随着业务的扩张、复杂度的增加,单体应用修改业务或者增加业务或许会给其它业务带来一定的影响,导致测试难度增加

3.单体架构使用服务器集群及存在的不足

随着业务的发展,大多数公司会将单体应用进行集群部署,并增加负载均衡服务器(例如 Nginx)。另外,外需要增加集群部署的缓存服务器和文件服务器,并将数据库读写分离,以应对用户量的增加而带来的高并发访问量

服务器集群的优点

用负载均衡服务器分发高并发的网络请求,用户的访问被分配到不同的应用服务器,应用服务器的负载不再成为瓶颈,用户量增加时,添加应用服务器即可。通过添加缓存服务器来缓解数据库的数据以及数据库读取数据的压力。大多数的读取操作是由缓存完成的,但是仍然有少数读操作是从数据库读取的,例如缓存失效、实时数据等。当有大量的读写操作时,将数据库进行读写分离是一个不错的选择,例如 MySQL 的主从热备份,通过相关配置可以将主数据库服务器的数据同步到数据库服务器,实现数据库的读写分离,读写分离能够改善数据库的负载能力

服务器集群的不足

系统仍然为单体应用,大量的业务必然会有大量的代码,代码的可读性和可维护性依然很差面对海量的用户,数据库将会成为瓶颈,解决方案将使用分布式数据库,也就是将数据库进行分库分表持续交付能力差,业务越复杂,代码越多,修改代码和添加代码所需的时间越长。新人熟悉代码的时间长、成本高

二、微服务

1.什么是微服务

微服务发明者 Martin Fowler 对微服务的定义

简而言之,微服务架构的风格,就是将单一程序开发成一个微服务,每个微服务运行在自己的进程中,并使用轻量级机制通信,通常是 HTTP RESTFUL API。这些服务是围绕业务能力来划分构建的,并通过完全自动化部署机制来独立部署。这些服务可以使用不同的编程语言,以及不同的数据存储技术,以保证最低限度的集中式管理

总结微服务具有如下特点:

微服务单元按业务来划分微服务通过 HTTP 来互相通信微服务的数据库独立自动化部署服务集中化管理分布式架构

2.微服务单元按业务来划分

微服务的 “微” 可以从三个方面来界定

根据代码量根据开发时间根据业务大小

按业务划分的微服务单元独立部署,运行在独立的进程中。这些微服务单元是高度组件化的模块,并提供了稳定的模块边界,服务与服务之间没有任何的耦合,有非常好的扩展性和复用性

3.微服务通过 HTTP 来互相通信

微服务单元之间的通信方式一般倾向于使用 HTTP 这种简单的通信机制,更多的时候是使用 RESTful API 的。这种接受请求、处理业务逻辑、返回数据的 HTTP 模式非常高效,并且这种通信机制与平台和语言无关

服务与服务之间也可以通过轻量级的消息总线来通信,例如 RabbitMQ 和 Kafka 等。通过发送消息或者订阅消息来达到服务与服务之间通信的目的

但是,通过 HTTP 或者消息总线的方式进行通信存在一定的弊端,其通信机制是不可靠的,虽然成功率很高吗,但还是会有失败的时候

4.微服务的数据库独立

微服务的特点就是按业务划分服务,服务与服务之间无耦合,就连数据库也是独立的。一个典型的微服务的架构就是每个微服务都有自己独立的数据库,数据库之间没有任何联系

数据库独立的好处

随着业务的不断扩张,服务与服务不需要提供数据库集成,而是提供 API 接口相互调用;还有一个好处是数据库独立,单业务的数据量少,易于维护,数据库性能有着明显的优势,数据库的迁移也很方便。另外,随着存储技术的发展,数据库的存储方式不再仅仅是关系型数据库,非关系型数据库的应用也非常广泛,例如 MongoDB 和 Redis,它们有着良好的读写性能,因此越来越受欢迎。一个典型的微服务的系统,可能每一个服务的数据库都不相同,每个服务所使用的数据存储技术根据业务需求来选择

5.微服务的自动化部署

随着技术的发展,尤其是 Docker 容器技术的推进、Kubernetes 容器编排技术的发展,以及自动化部署工具(例如开源组件 Jenkins)的出现,自动化部署变得越来越简单。自动化部署可以提高部署的效率,减少人为的控制,部署过程中出现错误的概率降低

6.服务集中化管理

微服务系统是按业务单元来划分服务的,服务数量越多,管理起来就越复杂,因此微服务必须使用集中化管理。目前流行的服务注册与发现组件有 Eureka、Zookeeper、Consul、Etcd 和 Nacos

7.分布式架构

分布式系统是集群部署的,由很多计算机相互协作共同构成,它能够处理海量的用户请求

分布式系统通过网络协议来通信,所以分布式系统在空间上没有任何限制,即分布式服务器可以部署在不同的机房和不同的地区

微服务架构是分布式架构,分布式系统比单体系统更加复杂,主要体现在服务的独立性和服务相互调用的可靠性,以及分布式事务、全局锁、全局 Id 等,而单体系统不需要考虑这些复杂性

另外,分布式系统的应用都是集群化部署,会给数据一致性带来困难。分布式系统中的服务通信依赖于网络,网络不好,必然会对分布式系统带来很大的影响。在分布式系统中,服务之间相互依赖,如果一个服务出现了故障或者是网络延迟,在高并发的情况下,会导致线程阻塞,在很短的时间内该服务的线程资源会消耗殆尽,最终使得该服务不可用。由于服务的相互依赖,可能会导致整个系统的不可用,这就是 “雪崩效应”。为了防止此类事件的发生,分布式系统必然要采取相应的措施,例如 “熔断机制”

熔断机制

在 Spring Cloud 构建的微服务系统中,采用了熔断器(即 Hystrix 组件的 Circuit Breaker)去做熔断

熔断机制很好理解,当某一个服务出现故障,请求失败次数超过设定的阈值之后,该服务就会开启熔断器,之后该服务不进行任何的业务逻辑操作,执行快速失败,直接返回请求失败的信息。其它依赖该服务的服务就不会因为得不到响应而线程阻塞

熔断器还有一个机制,即自我修复的机制。当一个服务熔断后,经过一段时间,半打开熔断器。半打开的熔断器会检查一部分请求是否正常,其它请求执行快速失败,检查的请求如果响应成功,则可以判定服务正常了,就会关闭该服务的熔断器。如果该服务还不正常,则继续打开熔断器

最后,熔断组件往往会提供一系列的监控,例如服务可用与否、熔断器是否被打开、目前的吞吐量、网络延迟状态的监控等,从而很容易让开发人员和运维人员实时地了解服务的状况

8.微服务的优势

将一个复杂的业务分解成若干个小的业务,每个业务拆分成一个服务,服务的边界明确,将复杂的问题简单化。服务按照业务拆分,编码也是按照业务来拆分,代码的可读性和可扩展性增加微服务系统是分布式系统,服务与服务之间没有任何耦合,随着业务的增加,可以根据业务再拆分服务,具有极强的横向扩展能力。随着应用的用户量地增加,并发量增加,可以将微服务集群化部署,从而增加系统的负载能力服务与服务之间通过 HTTP 网络通信协议来通信,高内聚,低耦合。这使得微服务可以采用任何地开发语言和技术来实现在重写一个单体应用时,要求重写应用的人员了解所有的业务,并且重写风险也较高。如果是微服务系统,由于微服务系统是按照业务进行拆分的,并且有明确的边界,所以重写某个服务就相当于重写某一个业务的代码,非常简单微服务的每个服务单元都是独立部署的,单个服务的修改和部署对其它服务没有任何影响,大大减少了测试和部署的时间微服务在 CAP 理论中采用的是 AP 架构,即具有高可用和分区容错的特点。高可用主要体现在 7 × 24 不间断的服务,这要求系统有大量的服务器集群。另外,分区容错使得系统更加健壮

CAP 理论

在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)不能同时成立

三、微服务的不足

1.微服务的复杂度

构建一个微服务系统并不是一件容易的事,微服务系统是分布式系统,构建的复杂度远远超过单体系统,开发人员需要付出一定的学习成本去掌握更多的架构知识和框架知识。服务与服务之间通过 HTTP 协议或者消息传递机制通信,开发者需要选出最佳的通信机制,并解决网络服务较差时带来的风险

此外,服务与服务之间相互依赖,如果修改某一个服务,会对另一个服务产生影响,如果掌握不好,会产生不必要的麻烦。由于服务的依赖性,测试也会变得复杂,比如修改一个比较基础的服务,可能需要重启所有的服务才能完成测试

2.分布式事务

微服务架构所设计的系统是分布式系统。根据 CAP 理论,在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性)不能同时成立

在分布式系统中,分区容错性是必须的,如果因为一个分区故障或者分区之间通信故障,导致整个分布式系统不可用,这显然违背了分布式系统的初衷。既然 P 已经确定,那么就要在 C 和 A 之间取舍

选择 C,就意味着,如果出现分区之间通信故障,那么任何一个分区都不能写入数据,因为各个分区之间无法进行数据同步,会导致分区之间数据不一致。如果出现分区故障,导致各个分区之间的数据版本不一致,那么所有分区都无法读取数据

选择 A,就意味着,即使分区数据不一致,各个分区也要正常地独立处理请求

综上,要想 CA 同时满足,那么分布式系统就不能出现任何异常,或者当一个节点出现异常时就关停整个系统,这显然不可能

根据一致性和可用性的选择不同,开源的分布式系统往往被分为 AP 系统和 CP 系统,如果一套系统发生分区故障后,客户端依然可以访问系统,但是获取的数据有的是最新的数据,有的还是老数据,那么这套系统就是 AP 系统,经典的比如 Eureka。如果一套系统发生分区故障后,客户端的任何请求都被卡死或者超时,但是,系统的每个节点总是会返回一致的数据,那么这套系统就是 CP 系统,经典的比如 Zookeeper

微服务系统通常是选择 AP 架构,这就有了一个难题,如何尽可能地保证数据的一致性,也就是分布式事务。微服务架构中,分布式事务一直是一个难以解决的问题,业界给出了很多解决办法,比如两阶段提交、三阶段提交、TCC(Try Confirm Cancel)等

两阶段提交

第一阶段,service-account 发起一个分布式事务,交给事务协调器 TC 处理,事务协调器 TC 向所有参与的事务的节点发送处理事务操作的准备操作。所有的参与节点执行准备操作,将 Undo 和 Redo 信息写进日志,并向事务管理器返回准备操作是否成功

第二阶段,事务管理器收集所有节点的准备操作是否成功,如果都成功,则通知所有的节点执行提交操作;如果有一个失败,则执行回滚操作

两阶段提交,将事务分成两部分能够大大提高分布式事务成功的概率。如果在第一阶段都成功了,而执行第二阶段的某一个节点失败,仍然导致数据的不准确,这时一般需要人工去处理,这就是当初在第一步记录日志的原因。另外,如果分布式事务涉及的节点很多,某一个节点的网络出现异常会导致整个事务处于阻塞状态,大大降低了数据库的性能。所以一般情况下,尽量少用分布式事务

3.服务的划分

将一个完整的系统拆分成很多个服务,是一件非常困难的事,因为这涉及了具体的业务场景。对于微服务的拆分原则,Maritin Fowler 给出的建议是:服务是可以被替换和更新的。也就是服务和服务之间五耦合,任何一个服务都可以被替换,服务有自己严格的边界

领域驱动设计是一个全新的概念,也是一个比较理响的微服务拆分的理念。领域驱动设计通过代码和数据分析找到合理的切分点,并通过数据分析来判断服务的划分边界和划分力度

数据驱动开发

需求分析→数据建模(E-R 图)→建库建表(写 DAO)→编写业务逻辑

领域驱动设计

需求分析→领域分析→领域建模→核心业务逻辑→技术细节(DB、Cache、Message…)

数据驱动和领域驱动的最大区别在于第二步,数据驱动开发是建立数据模型、领域驱动设计是建立业务模型。前者的问题在于在做多个类似的功能点的时候,我们会发现虽然功能点类似,但是很难复用

领域驱动设计概念理解推荐视频 DDD-领域驱动设计

4.服务的部署

一个简单地单体系统可能只需要将程序集群部署并配置负载均衡服务器即可,而部署一个复杂的微服务架构的系统就复杂得多。因为每一个微服务可能还涉及比较底层的组件,例如数据库、消息中间件等。微服务系统往往由数量众多的服务构成,例如 Netflix 公司有大约 600 个服务,而每个服务又有大量的实例。微服务系统需要对每个服务进行治理、监控和管理等,而每个服务有大量的配置,还需要考虑服务的启动顺序和启动时机等

部署微服务系统,需要开发人员或者运维人员对微服务系统有足够强得控制力。随着云计算和云服务器的发展,部署微服务系统并不是一件难事,例如使用 PaaS 系统、使用 Docker 编排等。这就是人们往往提到微服务,就会想到 Docker 和 DevOps 的原因。其中,微服务是核心;Docker 为容器技术,是微服务最佳部署的容器;DevOps 是一种部署手段或理念

四、微服务的设计原则

软件设计每一个版本都在变化,所以软件设计应该是渐进式发展。软件从一开始就不应该被设计成微服务架构,微服务架构固然有优势,但是它需要更多的资源,包括服务器资源、技术人员等。追求大公司的技术解决方案,刻意地追求某个新技术,企图使用技术解决所有地问题,这些都是软件设计的误区

技术应该是随着业务的发展而发展的,任何脱离业务的技术是不饿能产生价值的。在初创公司,业务很单一时,如果单体架构够用的情况下,就应该使用单体架构,因为它的开发速度快,性价比高。随着业务的发展,用户量地增加,可以考虑将数据库读写分离、加缓存、加复杂的负载均衡服务器、将应用程序集群化部署等。如果业务还在不断发展,这时可以考虑使用分布式系统,例如微服务架构的系统。不管使用什么样的架构,驱动架构发展的一定是业务的发展,只有当前架构不再适合当前业务的发展,才考虑更换架构

在微服务架构中,有三大难题,那就是服务故障的传播性、服务的划分和分布式事务。在微服务设计时,一定要考虑清楚这三个难题,从而选择合适的框架。目前比较流行的微服务解决方案有 Spring Cloud 和 Kubernetes 容器编排等。不管使用哪一种框架或者工具,都需要考虑这三大难题。为了解决服务故障的传播性,一般的微服务框架都有熔断机制组件。另外,服务的划分没有具体的划分方法,一般根据业务来划分服务,领域驱动设计具有指导作用。最后,分布式事务一般的解决办法就是两阶段提交或者三阶段提交,不管使用哪一种都存在事务失败,导致数据不一致的情况,关键时刻还得人工恢复数据。总之,微服务的设计一定是渐进式的,并且是随着业务的发展而发展的

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。