当前位置: 首页 > 科技观察

SpringCloud——SpringCloud之于架构演进的起源

时间:2023-03-20 14:46:24 科技观察

学习目标回顾架构的演进。springcloud到底是什么?理清spring、springboot、springcloud的关系。了解springcloud的常用组件及其作用。Chapter1ArchitectureEvolution1.Monolithicarchitecture相信大部分同学都使用过SSM框架进行开发。那个时候你的项目组肯定已经把所有的功能模块都放在了同一个框架里面了,只不过是不一样的。为功能构建不同的包,然后将所有功能模块数据存储在数据库中,然后通过Tomcat容器启动服务。这种架构在公司业务量、数据量、并发量都比较小的时候,一开始是没问题的,对开发者就更加友好了。但是它来了,但是随着你公司的发展,当业务量增加,功能需求增加,数据量和并发量增加时,单体架构就不行了。为什么?随着业务量的增加,单台Tomcat很容易达到性能瓶颈,一般服务器上Tomcat的最大并发数在200左右。因为只有一台服务器,一旦出现问题,会直接挂掉。此时客户端无法访问该服务。这时候让我想起上大学的时候选选修课要等好几个小时,体验极差。2、要解决以上问题,必须从根源上优化集群架构。此时集群架构就出现了。集群架构的逻辑其实很简单。它将整个系统的部署从一台服务器改为多台服务器的部署,只是整个系统的一个副本。然后添加Nginx服务器进行负载均衡。但是,集群架构也存在一些问题:如果系统中的一个小功能进行了版本迭代,那么此时需要停止所有系统,然后再进行更新。而且整个系统可能非常庞大,开发这个大系统的部门人员也可能有大量的组织架构,不好管理。虽然你的系统有集群,但是数据库往往是制约你系统性能的最大因素。当并发量大,数据量大时,数据库无法处理。3、业务垂直拆分针对以上问题,需要再次对架构进行改进。如果整个大系统不适用,则将不同的功能模块拆分成小系统。业务垂直拆分,简单来说就是可以根据系统的业务功能,拆分出多个业务模块子系统。每个子系统负责不同的业务团队。4、服务化转型随着业务系统的垂直转型,根据业务功能的纬度,拆分出多个子系统,在每个子系统中,会有更多的共享服务,比如用户信息查询、支付业务等。参与,首页也会参与。那么势必会造成重复开发产生大量的冗余代码。那么这个时候就引入了服务改造的思想,就是SOA将一些公共的模块分离出来,这些模块会被多个上层服务独立调用,形成一些共享的基础服务。这些拆分后的共享服务相对独立,可重用。例如用户管理服务,包括用户注册、用户查询等功能。比如单点登录服务。SOA的核心目标是通过服务的过程实现业务的灵活性,而这个过程实际上是由一系列相关的任务组成的。这一系列的相关任务可以通过一系列的服务组合来实现。业务功能SOA面向服务架构,从语义上讲,它与面向过程、面向对象、面向组件相同,是一种软件构建和开发方式。因此,在SOA中,服务是最核心的抽象方法,业务被划分为一系列粗粒度的业务服务和业务流程。在SOA中,更强调ESB企业服务总线,它可以使服务之间的交互动态化,服务位置透明化。这样做的好处是服务的调用者和服务的提供者之间高度解耦。这使得服务更加灵活和隔离。ESB:由面向阶段的服务架构(SOA)发展而来,主要是为了解耦多个系统中的服务调用者和服务提供者。ESB本身提供了服务暴露、接入、协议转换、数据格式转换、路由等功能。SOA主要解决的问题是:信息孤岛。互连。业务复用。5、微服务架构业务系统进行服务化改造后,将原有的共享业务进行拆分,形成可复用的服务,可以最大程度避免共享业务重复构建、资源连接瓶颈等问题。那么,那些拆分出来的服务是否也需要按照业务功能进行拆分,独立部署,降低业务耦合度,提高容错能力?微服务并不是一种新的思维方式。它更像是一种思想的提炼,一种面向服务思想的最佳实践方向,所以我认为微服务其实是SOA思想下的。它是软件交付链和基础设施逐渐成熟的自然产物。微服务也是一种面向服务的架构模型,只是强调服务的粒度。即服务的职责更单一、更细化。我们也可以把SOA看作是微服务的超集。即多个微服务可以组成一个soa服务。6、微服务和SOA架构的区别经常有同学问,微服务和SOA架构有什么区别。这种差异必须从架构的开发过程中理解。事实上,这两种架构模式本质上应该是在分布式架构时间轴上基于面向服务思想的不断完善和基础设施的逐步成熟而进行的升级。既然存在于时间线的顺序中,说明两种架构模型侧重点不同。SOAMSA(微服务)遵循“尽可能共享”架构方法遵循“尽可能少共享”架构方法重要性在于业务功能重用重要性在于“限界上下文”的概念标准他们专注于人员、协作和其他选择的自由使用企业服务总线(ESB)进行通信简单的消息传递系统他们支持多种消息传递协议使用轻量级协议,例如HTTP/REST,开销更大多线程处理I/O通常单线程使用事件循环特性进行非锁定I/O处理最大化应用服务的可重用性重点是解耦传统关系数据库更常用现代关系数据库更常用一个系统的变化需要整体的修改。一个系统性的改变是创建一个新的服务。DevOps/持续交付正在变得流行,但还不是主流。非常关注DevOps/持续交付。第二章SpringCloud上一章讲了架构的演进,其实不管是什么架构,都需要通过合适的框架技术来实现,从最初的spring框架,到后来的springboot,再到现在现在的springcloud,那为什么还需要springcloud?为什么spring不能工作?如果我们要从整体上理解这些问题,那么我们先搞清楚几个概念,在脑海中形成一个系统:spring在开发过程中存在哪些问题?springboot的出现解决了什么?springboot和springcloud有什么关系?什么是春云?包含什么内容1.spring的问题其实spring的出现就是为了简化开发。大部分同学都能说出spring的核心概念,无外乎三个,IoC,DI,AOP,我稍微解释一下这三个兄弟是干什么的。IoC其实就是一个容器,用来存放Bean对象;回到最基本的层面,我们的java开发就是通过new不断的创建对象,拿到对象之后再去调用对象中的方法。OK,在实际的开发过程中,如果所有的对象都需要手动创建,那将是一个非常繁琐的过程。可能你有10000个类,然后这10000个类需要在各个地方创建对象。这假设你使用了A类的一个对象,然后你在B类中新建了一个对象,如果你想在C、D、E等类中使用这个对象,那就很麻烦了。这只是一种情况。这种类似的现象在开发中随处可见,所以spring为了解决这个过程,设计了一个IoC功能,你理解为一个中央容器,用来容纳几乎所有需要用到的Bean对象该项目。IoC的概念理解了,那么你就想这时候,对象创建了,但是对象中可能还有一些其他的成员属性,而这些成员属性是其他对象,比如A对象中有一个成员该属性是一个B对象,所以这时候需要做一个引用关联。这一步也是非常麻烦和繁琐的。我应该怎么办?Spring的DI已经帮你搞定了。在新建A对象的过程中,spring会去中央容器中查找是否有B对象,如果有则将B对象赋值给A对象的属性。AOP的概念其实更容易理解。它基于动态代理。您需要明确的指导。代理是为了增强。你是什??么意思?假设有一个对象,其业务功能是创建订单,OK,那我不想直接调用这个对象的创建订单的函数,我想在创建订单前后做点别的,比如打印日志,此时我使用到代理。OK,基于这三兄弟,spring确实简化了很多开发流程。但是在spring最初注入IoC对象的过程中,是基于XML的。这个逻辑很容易理解,就是你需要在容器中放什么对象,只需要在XML文件中配置即可。然而,也正因为如此,spring变得异常繁琐。想一想,一个项目用了多少个对象,每个对象都需要配置,就完了。编写无数的XML文件。spring已经开始努力优化和引入注解,但是没有用。如果您的项目想要集成其他组件怎么办?比如redis,比如mybatis。即便是要在一个微服务项目中引入和集成各种组件,那更是崩溃。其实归根结底,spring还是没有解决IoC注入的复杂过程和外部配置的统一管理。2.springboot看过springboot源码的同学都知道,springboot底层其实会走spring进程。即springboot依赖于spring,它也在spring的基础上做了一些工作。具体做了什么其实就是解决了IoC的自动注入和配置的统一管理,让这个工作不再需要程序员来做,框架自己来做。如何解决具体参考前面的内容。3.Springcloud生态首先,什么是springcloud?网上说啊,springcloud是做微服务的,是一个生态等等。让我们谈谈我们不明白的事情。那我用最简单的语言解释一下:springcloud是springboot集成的各种starter组件的集合。springcloud的底层核心框架是springboot,springboot在集成不同的组件时,程序员不需要编写XML文件和配置。文件没有了,但是有好心人,他们根据springboot自动组装的原理写了starter组件,然后我们给这些starter组件和springboot整体取了一个名字叫springcloud。明白了,知道了springcloud是什么之后,我们再来看看这个生态包含了什么,我知道springboot,起步组件有哪些?这个不用死记硬背,我们整体按照数据流向串成一个字符串即可。当你理解了字符串,那么你就离架构师不远了。(1)GatewayGateway组件我们知道springcloud可以用来开发微服务,但是真正了解springcloud是什么的同学应该很少。官方的解释是:springcloud提供了一些工具可以让开发者快速构建分布式应用,而这些服务可以很好的工作在任何分布式环境中。既然我们提供了一些快速构建微服务应用的工具,那我们就需要了解微服务开发过程中需要解决哪些问题?微服务实现后,每个服务的拆分粒度很小。对于客户端来说,做一个操作可能会涉及调用后端的多个服务组件,这意味着需要频繁发起多次访问来进行数据聚合实现用户功能。如果我们在所有的微服务之前加一个网关,客户端需要做哪些功能操作可以直接调用网关告诉网关做什么,网关会根据请求处理多个后端服务的数据functionAggregation聚合以减少客户端调用的频率。而且,由于网关的聚合,我们也可以在网关层对请求进行统一的鉴权和鉴权;包括限流、统一记录请求日志、灰度发布等。(2)远程通信Openfeign和Dubbo服务拆分后,会涉及到服务的远程通信,比如http协议或者rpc协议。(3)服务发现Eureka和Nacos在满足基础通信的基础上,如何实现服务的统一管理和服务的动态感知,需要服务的注册中心实现服务注册和发现的功能。(4)负载均衡Ribbon和Dubbo假设服务商为了扩大吞吐量,采用10台机器的集群部署。这时,客户端从注册中心获取服务后,应该调用哪台机器呢?因此,必须有一种负载均衡机制来实现客户端请求的分配。(5)熔断、限流、降级Hystrix和Sentinel在分布式架构中,每个服务节点都必须满足高可用,所以对于服务本身,一方面要在有准备的前提下做好充分的扩容。另一方面,服务需要具备熔断、限流、降级的能力。一个服务调用另一个服务时,可能会因为网络原因或者连接池已满而频繁出错。需要熔断机制来防止整个应用因为请求的堆积而雪崩。当发现整个系统的负载确实过高时,可以选择降级某些功能或某些调用,以保证最重要的交易流程的通过,将最重要的资源全部用于保证核心流程.设置好熔断和降级策略后,还有一种保护系统的方法,就是限流算法。通过全链路压测我们可以知道整个系统的吞吐量,但是实际的流量可能会超出我们的预期值,比如恶意攻击或者突然的流量高峰。在这种情况下,可以通过限流来保护系统不至于崩溃,但是对于一些用户来说,限流会带来不好的体验。(6)配置中心Config和Nacos服务拆分后,服务数量非常大。如果所有的配置都以配置文件的形式放在应用程序本地,管理起来会非常困难。可想而知,当有成百上千个进程时,如果出现配置问题,是很难发现的。因此,需要一个统一的配置中心来管理所有的配置,统一下发配置。在微服务中,配置往往分为几类,一类是几乎不变的配置,可以直接在容器镜像中敲入,二是启动时会确定的配置,而这种配置往往是通过环境变量来传递的在容器启动时传入。第三类是统一配置,需要通过配置中心下发。比如在大促的情况下,需要降级一些功能。可以在配置文件中统一配置。(7)分布式事务Seata对数据库的垂直拆分,对服务的拆分,单个数据库事务根本不能满足需求。这时候就需要第三方的协同工具来实现统一管理事务的提交和回滚等操作,这时候Seata出现了。4、服务带来的问题(1)业务团队的痛点对于业务开发团队来说,技术是最强的吗?当然不是,最强的业务团队一定是对业务的理解和熟悉。业务应用的核心价值是实现业务场景,而不是写微服务。微服务只是实现业务的一种手段。除了关心业务,业务团队面临的最大挑战是如何保证系统的稳定性和可扩展性,以及如何设计安全的开放api。如果服务拆分,如何保证跨数据库的数据一致性。和遗留系统的改造。在公司层面,业务团队的压力也来自于时间和人力的投入,我们习惯了被各种deadline赶走。所以作为业务程序员,如果在这个deadline之前需要花更多的时间在springcloud等工具的学习上,无疑会让事情变得更糟。公司对业务团队的考核,永远只看成绩!(2)跨语言带来的问题微服务有一个很重要的特点,就是不同的微服务可以使用自己最擅长的语言来编写程序。这个特性在企业实施的时候会带来一些问题。比如公司内部会开发一些公共的类库或者框架,或者使用第三方的类库或者框架来实现某些功能。但是因为公司的微服务使用了多种语言,也就意味着这些类库需要针对不同的语言开发兼容的版本。如果是主流语言还好,但如果是一些小众语言,对于这些基础组件的开发者来说无疑是晴天霹雳。(3)总结从这些痛点我们可以发现,我们所做的所有非业务的事情,都是为了保证请求发送到正确的地方,并且能够及时或者得到正确的结果。那么对于业务开发者来说,有必要关心这些吗?回到我们一开始提到的例子,开发者在进行计算机网络通信时,是否有必要关心网络通信的细节?我们在使用http协议进行数据传输的时候,有没有关心过底层使用的是TCP还是udp?数据是如何传输的?既然我们不需要关心这些,为什么业务开发人员要关心微服务架构中的这些问题的服务通信呢?