“Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式环境中运行良好,包括开发人员自己的笔记本电脑,裸机数据中心,以及Cloud Foundry等托管平台。”
Dubbo、Spring Cloud、Spring Cloud和Spring Cloud Alibaba都是用于构建分布式系统的开源框架。对比如下:
Dubbo是一个高性能的分布式服务框架,由阿里巴巴开发。它基于传统的服务治理理念,提供了服务注册、发现、路由、负载均衡、容错等功能。Dubbo的核心特点是高性能和低延迟的RPC调用,适用于大规模的微服务架构。Dubbo提供了对多种协议(如Dubbo协议、REST
协议)和注册中心(如ZooKeeper、Consul)的支持。
Spring Cloud是一个由Pivotal开发的微服务框架,构建在Spring Framework之上,使得构建分布式系统更加便捷。它提供了一系列的组件和模块,用于实现服务注册与发现、负载均衡、断路器、配置管理、消息总线等功能。Spring Cloud采用了Spring Boot作为底层的开发框架,提供了更简洁、快速搭建分布式系统的解决方案。
Spring Cloud Alibaba是Spring Cloud与Alibaba开放平台合作的结果,提供了一些在云原生应用开发中常用的解决方案。它主要基于Spring Cloud框架,结合了一些Alibaba技术栈,如Nacos(服务注册与发现)、Sentinel(流量控制和熔断降级)、RocketMQ(消息驱动)等。Spring Cloud Alibaba旨在提供云原生应用开发的全栈解决方案。
com.ruoyi
├── ruoyi-ui // 前端框架 [80]
├── ruoyi-gateway // 网关模块 [8080]
├── ruoyi-auth // 认证中心 [9200]
├── ruoyi-api // 接口模块
│ └── ruoyi-api-system // 系统接口
├── ruoyi-common // 通用模块
│ └── ruoyi-common-core // 核心模块
│ └── ruoyi-common-datascope // 权限范围
│ └── ruoyi-common-datasource // 多数据源
│ └── ruoyi-common-log // 日志记录
│ └── ruoyi-common-redis // 缓存服务
│ └── ruoyi-common-security // 安全模块
│ └── ruoyi-common-swagger // 系统接口
├── ruoyi-modules // 业务模块
│ └── ruoyi-system // 系统模块 [9201]
│ └── ruoyi-gen // 代码生成 [9202]
│ └── ruoyi-job // 定时任务 [9203]
│ └── ruoyi-file // 文件服务 [9300]
├── ruoyi-visual // 图形化管理模块
│ └── ruoyi-visual-monitor // 监控中心 [9100]
├──pom.xml // 公共依赖
├── build // 构建相关
├── bin // 执行脚本
├── public // 公共文件
│ ├── favicon.ico // favicon图标
│ └── index.html // html模板
├── src // 源代码
│ ├── api // 所有请求
│ ├── assets // 主题字体等静态资源
│ ├── components // 全局公用组件
│ ├── directive // 全局指令
│ ├── layout // 布局
│ ├── router // 路由
│ ├── store // 全局 store管理
│ ├── utils // 全局公用方法
│ ├── views // view
│ ├── App.vue // 入口页面
│ ├── main.js // 入口 加载组件 初始化等
│ ├── permission.js // 权限管理
│ └── settings.js // 系统配置
├── .editorconfig // 编码格式
├── .env.development // 开发环境配置
├── .env.production // 生产环境配置
├── .env.staging // 测试环境配置
├── .eslintignore // 忽略语法检查
├── .eslintrc.js // eslint 配置项
├── .gitignore // git 忽略项
├── babel.config.js // babel.config.js
├── package.json // package.json
└── vue.config.js // vue.config.js
- 业务场景案例:
实现支付订单功能的业务流程:
1.创建一个订单后,如果用户立刻支付了这个订单,我们需要将这个订单状态更新为【已经支付】
2.扣减相对应的商品库
3.通知仓储中心,进行发货
4.给用户这次购物怎加相对应的积分
- 组件协同
- 订单服务要调用库存服务,仓储服务,或积分服务,怎么查询服务地址” />订单服务里面有一个Eureka Client组件组件,Eureka Client组件会问一下:库存在那台服务器上,监听的端口号是哪个,仓储服务呢?积分服务呢?然后就可以把这些相关信息从Eureka Server的注册表中拉取到自己本地缓存起来。
- 如果订单服务想要调用库存服务,就可以找自己本地Eureka Client下的库存服务在那台机器上,监听对应端口,收到响应后,紧接着就可以发送一个请求过去,调用库存服务扣减库存的对应接口。
- 订单服务查询地址后,如何调用库存等服务?
- 不需要调用端写HttpClient的硬编程,没有底层的建立连接、构造请求、解析响应的代码,直接就是用注解定义一个 FeignClient接口,然后调用那个接口就可以了。Feign Client会在底层根据注解,指定的服务建立连接、构造请求、发起靕求、获取响应、解析响应,等等。
- Feign的一个机制就是使用了动态代理,首先,如果你对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理,如果调用那个接口,本质就是会调用 Feign创建的动态代理, Feign的动态代理会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址。最后,针对这个地址,发起请求、解析响应。
- 如何调用库存服务的具体哪个机器(库存集群服务)?
- 库存服务上面部署了多台机器,那Feign怎么知道请求那台服务器呢? Ribbon服务就是解决这个问题的,作用是负载均衡,帮在每一次请求的时候选择一台机器,均匀的把请求发送到各个机器上 ,Ribbon的负载均衡默认的使用Round Robin轮询算法,什么是轮询算法? 如果订单服务对库存发起十次请求,那就先让你请求第一台机器,然后是第二台机器,第三台机器,接着循环到第十台机器。
- Ribbon是和Feign以及Eureka紧密协作,完成工作的,具体如下:
首先Ribbon会从 Eureka Client里面获取到对应的服务注册表,也就知道了所有的服务都部署在了那台机器上,在监听哪些端口,然后Ribbon就可以使用默认的Round Robin算法,从中选择一台机器, Feigin就会针对这些机器构造并发送请求。
- 高并发情况下,一个服务挂起,导致调用它的服务全部挂掉,造成雪崩效应怎么办?
- 如果系统在高并发的情况下,大量请求涌过来的时候,订单服务的100个线程会卡在积分服务这块,导致订单服务没有一个线程可以处理请求,然后会导致别的请求订单服务的时候,发现订单服务挂掉,不响应任何请求了,这种问题就是微服务架构中棘手的服务器雪崩问题。多个服务互相调用,如果不做任何保护的话,某一个服务挂掉会引起连锁反应,导致别的服务挂掉,比如:积分服务挂了,会导致订单服务的线程全部卡在请求,瞬间导致订单服务也挂了,其他请求订单服务全部会卡住,无法响应。
- 假设订单服务调用库存服务、仓储服务的这两个线程池都是正常工作的,所以这两个服务不会受到任何影响。这个时候如果别人请求订单服务,订单服务还是可以正常调用订进行库存服务扣减,并调用仓储服务通知发货。积分服务挂了,所以我们直接对积分服务熔断,比如在5分钟内请求积分服务直接就返回了,不要去走网络请求卡住几秒钟,这个过程,就是熔断!
- 熔断Hystix是Netflflix开源的一个延迟和容错库,用于隔离访问远程服务,防止出现级联失败。服务器支持的线程和并发数有限,请求一直阻塞,会导致服务器资源耗尽,从而导致所有其它服务都不可用,形成雪崩效应。Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超时,则会进行降级处理。
- 每次调用积分服务,你就在数据库里记录一条消息,某用户增加了多少积分,因为积分服务挂了,导致没增加成功!这样等积分服务恢复了,你可以根据这些记录手工加一下积分。这个过程,就是降级。
- 网络中几百个服务,如何调用正确的服务?
- 一般微服务架构中都必然会设计一个网关在里面,像android、ios、pc前端、微信小程序、H5等等,不用去关心后端有几百个服务,就知道有一个网关,所有请求都往网关走,网关会根据请求中的一些特征,将请求转发给后端的各个服务。
- 网关做统一的降级、限流、认证授权、安全,等等。
- 网络中几百个服务,如何统一配置并查询?
- Config作用是提供的一个分布式配置管理工具,它的作用是集中管理微服务系统的配置文件,为微服务系统提供外部化的配置支持。主要功能:
- 集中管理配置文件:Spring Cloud Config 可以将各个微服务系统的配置文件集中管理,实现配置文件的统一管理,便于维护和更新。
- 配置文件的版本控制:Spring Cloud Config 支持 Git、SVN、本地文件系统等多种配置存储方式,可以轻松实现配置文件的版本控制。
- 动态刷新配置:Spring Cloud Config 支持动态刷新配置,即在不重启应用的情况下,实时更新配置文件,保证配置文件的实时性和一致性。
- 安全性管理:Spring Cloud Config 提供了多种安全认证方式,如基于用户名和密码的认证、基于公钥和密钥的认证等,保证配置文件的安全性。
- 高可用性和可扩展性:Spring Cloud Config 支持多节点部署,通过服务注册和发现机制实现负载均衡和故障转移,保证了配置中心的高可用性和可扩展性。
总结,SpringCloud是一个基于SpringBoot实现的微服务架构开发工具。它为微服务架构中涉及的配置管理、服务治理、断路器、智能路由、微代理、控制总线、全局锁、决策竞选、分布式会话和集群状态管理等操作提供了一种简单的开发方式。
- 什么是服务治理?
Spring Cloud 封装了Netflix公司开发的Eureka模块来实现服务治理 在传统的rpc远程调用框架中,管理每个服务与服务之间依赖关系比较复杂,管理比较复杂,所以需要使用服务治理,管理服务于服务之间依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册。
- 什么是服务注册与发现
服务注册就是将服务信息注册到注册中心,然后由注册中心来监控系统中微服务的状态。服务发现就是从注册中心上获取服务的信息。通常在管理分布式环境下的各个Spring Boot微服务时,必然存在服务的注册问题。既然是注册,必然有个管理注册中心的服务器,各个在Spring Cloud管理下的Spring Boot应用就是需要注册的client。
Spring Cloud使用erureka server, 所有需要访问配置文件的应用都作为一个erureka client注册上去。eureka是一个高可用的组件,它没有后端缓存,每一个实例注册之后需要向注册中心发送心跳,在默认情况下erureka server也是一个eureka client ,必须要指定一个 server。Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。而系统中的其他微服务,使用Eureka的客户端连接到 Eureka Sever并维持心跳连接。维护人员就可以通过Eureka Server来监控系统中各个微服务是否正常运行。在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息比如服务地址通讯地址等以剧名方式注册到注册中心上。另一方(消费者服务提供者),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后再实现本地RPC调用。RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。在任何rpc远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址)。
目前由于Eureka已停止维护,Nacos成为了更为活跃和推荐的选择。Nacos不仅提供了服务注册与发现的功能,还提供了更多的服务治理和配置管理能力,是一个功能更为丰富和全面的服务治理平台。Nacos是阿里开源的,Nacos支持基于DNS和基于RPC的服务发现。在Spring Cloud中使用Nacos,只需要先下载Nacos并启动Nacos server,Nacos只需要简单的配置就可以完成服务的注册发现。Nacos动态配置服务可以以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置。动态配置消除了配置变更时重新部署应用和服务的需要,让配置管理变得更加高效和敏捷。配置中心化管理让实现无状态服务变得更简单,让服务按需弹性扩展变得更容易。
总之,Nacos相当于实现了 Spring Cloud注册中心 和 Spring Cloud配置中心。
- Hystrix 是什么?
在分布式系统中,每个服务都可能会调用很多其他服务,被调用的那些服务就是依赖服务,有的时候某些依赖服务出现故障也是很正常的。
Hystrix 可以让我们在分布式系统中对服务间的调用进行控制,加入一些调用延迟或者依赖故障的容错机制。
Hystrix 通过将依赖服务进行资源隔离,进而阻止某个依赖服务出现故障时在整个系统所有的依赖服务调用中进行蔓延;同时 Hystrix 还提供故障时的 fallback 降级机制。
总而言之,Hystrix 通过这些方法帮助我们提升分布式系统的可用性和稳定性。
- Ribbon是什么?
负载均衡在系统架构中是一个非常重要的内容,因为负载均衡是对系统的高可用、网络的压力的缓冲和处理能力扩容的重要手段之一,我们通常说的负载均衡都是指的是服务端的负载均衡,其中分为硬件负载均衡和软件负载均衡。Ribbon是一个基于HTTP和TCP的客户端负载均衡器,当使用Ribbon对服务进行访问的时候,他会扩展Eureka客户端的服务发现功能,实现从Eureka注册中心获取服务端列表,并通过Eureka客户端来确定服务端是否已经启动。Ribbon在Eureka客户端服务发现的基础上,实现对服务实例的选择策略,从而实现对服务的负载均衡消费。
- 硬件负载均衡:主要通过服务器节点之间安装专门用于负载均衡的设备,比如F5,深信服,Array等。硬件负载均衡的设备或是软件负载均衡的软件模块都会维护一个可用的服务端清单,通过心跳检测来剔除故障的服务端节点保证清单中都是可以正常访问的服务端节点。当客户端发送请求到负载均衡的设备时候,该设备按某种算法(比如线性轮询、按权重负载、按流量负载等)从维护的可用服务端清单中取出一台服务端地址,然后进行转发。
- 软件负载均衡:则是通过服务器上安装一些具有负载功能或模块的软件来完成请求分发工作,比如Nginx、LVS、HAProxy等。Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,是一个基于HTTP和TCP的客户端负载均衡工具。SpringCloud对Ribbon做了二次封装,可以让我们使用 RestTemplate的服务请求,自动转换成客户端负载均衡的服务调用。Ribbon支持多种负载均衡算法,还支持自定义的负载均衡算法。Ribbon只是一个工具类框架,比较小巧, SpringCloud对它封装后使用也非常方便,它不像服务注册中心、配置中心、API网关那样需要独立部署, Ribbon 只需要在代码直接使用即可。
- Ribbon与 Nginx的区别:
- 都是软负载
- Ribbon是客户端负载均衡
- Nginx是服务器段负载均衡
- 服务端的负载均衡是提前配置好的:Nginx
- 客户端的负载均衡是从注册中心找的:Ribbon
- 网关是什么?
分布式架构中,服务节点数量较多,而对于客户端而言,多个服务节点暴露出来的API应该是统一的,否则每个节点地址不同,客户端就需要维护所有服务节点地址然后再选择一个访问,很明显客户端的维护成本就很高。
此时就需要有一个暴露统一API的网关服务将多服务节点封装,客户端访问网关,网关再将客户端的请求分发给被封装的服务节点,这样就避免了客户端和服务端的直接交互。
另外网关除了可以实现动态路由功能外,还可以实现参数校验、鉴权、日志、缓存、负载均衡、监控、限流等多种功能。总之对于非业务需求的统一功能都可以交给网关来实现,设计思想有点类似于Spring的面向切面编程。
- Zuul是什么
Zuul是Netfilx开源的微服务系统的网关组件。
Zuul的作用如下几个方面:
- 配合Ribbon、Eureka可以实现智能动态路由和负载均衡功能,将请求按策略分发到集群中合适的服务实例;
- 将服务和客户端之间进行解耦,客户端访问的是网关暴露出来的统一API,客户端不需要关系服务的运行情况;
- 统一鉴权,监控,日志,缓存,限流,参数校验等功能;
- 通过流量监控,可以根据流量进行服务降级;
- Feign是什么?
Feign是Netflix公司开源的轻量级rest客户端,使用Feign可以非常方便的实现Http 客户端。Spring Cloud引入Feign并且集成了Ribbon实现客户端负载均衡调用。
Feign工作原理如下:
1、 启动类添加@EnableFeignClients注解,Spring会扫描标记了@FeignClient注解的接口,并生成此接口的代理对象
2、 @FeignClient(value = “XC_SERVICE_MANAGE_CMS”)即指定了cms的服务名称,Feign会从注册中心获取cms服务列表,并通过负载均衡算法进行服务调用。
3、在接口方法 中使用注解@GetMapping(“/cms/page/get/{id}”),指定调用的url,Feign将根据url进行远程调用。
主程序入口添加了@EnableFeignClients注解开启对FeignClient扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClient注解。
当程序启动时,进行包扫描,扫描所有@FeignClients的注解的类,并且讲这些信息注入Spring IOC容器中,当定义的的Feign接口中的方法呗调用时,通过JDK的代理方式,来生成具体的RequestTemplate.当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,改对象封装可HTTP请求需要的全部信息,如请求参数名,请求方法等信息都是在这个过程中确定的。
然后RequestTemplate生成Request,然后把Request交给Client去处理,这里指的时Client可以时JDK原生的URLConnection,Apache的HttpClient,也可以时OKhttp,最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发器服务之间的调用。
- Spring Cloud Config:配置管理工具,支持使用Git存储配置内容,可以使用它实现应用配置的外部化存储,并支持客户段配置信息刷新、加密/解密配置内容等。
- Spring Cloud Netflix:核心组件,对多个Netflix OSS开源套件进行整合。Spring Cloud集成了许多Netflix(美国奈飞公司)开发的优秀组件,这些组件提供了服务注册与发现、配置中心、负载均衡、断路器、智能路由等功能。Eureka:服务治理组件,包含服务注册中心、服务注册与发现机制的实现。
- Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力。
- Ribbon:客户端负载均衡的服务调用组件。
- Feign:基于Ribbon和Hystrix的声明式服务调用组件。
- Zuul:网关组键,提供智能路由、访问过滤等功能。
- Archaius:外部化配置组件。
- SpringCloud Bus: 事件、消息总线,用于传播集群中的状态变化或事件,以触发后续的处理,比如用来动态刷新配置等。
- Spring Cloud Cluster:针对Zookeeper、Redis、Hazelcase、Consul的选举算法和通用状态模式的实现。
- Spring Cloud Cloudfoundry:与Pivotal Cloudfoundry的整合支持。
- Spring Cloud Consul:服务发现与配置管理工具。
- Spring Cloud Stream:通过Redis、Rabbit或者Kafka实现消费微服务,可以通过简单的声明式模型来发送和接受消息。
- Spring Cloud AWS:用来简化整合Amazon Web Service 的组件。
- Spring Cloud Security: 安全工具包,提供在Zuul代理中对 OAuth2客户端请求的中继器。
- Spring Cloud Sleuth:Spring Cloud 应用的分布式跟踪实现,可以完美整合Zipkin。
- Spring Cloud ZooKeeper:基于Zookeeper的服务发现与配置管理组件。
- Spring Cloud Starters: Spring Cloud的基础组件,它是基于Spring Boot风格项目的基础依赖模块。
- Spring Cloud CLI:用于在Groovy中快速创建Spring Cloud应用的Spring Boot CLI插件。