springboot分布式框架搭建

article/2025/9/11 17:33:37

搭建框架需要工具默认基于 maven 的分布式工程,我们知道在一个项目中,多个微服务是属于同一个工程,只不过是提供不同的服务而已,因此使用 maven 分布式工程来搭建微服务架构。搭建基于 maven 分布式的 Spring Cloud 微服务工程架构。这个是目前比较流行的搭建方式,其实我们可以这样想,服务从原始的RPC开始,至今spring cloud和web service,再到最后soa服务治理。服务的调用拙见完善,目前市场上出现的服务框架dubbo和spring cloud比较流行。

1.dubbo架构

 

 

 

2.spring cloud内部组成:

 

实际上,Spring Cloud是一个全家桶式的技术栈,包含了很多组件。本文先从其最核心的几个组件入手,来剖析一下其底层的工作原理。也就是Eureka、Ribbon、Feign、Hystrix、Zuul这几个组件。

一、业务场景介绍

先来给大家说一个业务场景,假设咱们现在开发一个跨境电商网站,要实现支付订单的功能,基本流程如下:

  • 创建一个订单后,如果用户立刻支付了这个订单,我们需要将订单状态更新为“已支付”
  • 扣减相应的商品库存
  • 通知仓储中心,进行发货
  • 给用户的这次购物增加相应的积分

以上业务流程我们需要有订单服务(order)、库存服务(sku)、仓储服务(erp)、积分服务(point)。整个流程的思路如下: 即使没有用户登录我们然后可以这样操作,只是到添加购物车的时候,我们需要提示用户去登录或者去注册。也是购物车的实现原理

  • 用户针对一个订单完成支付之后,就会去找订单服务,更新订单状态 或者(没有用户登录的情况,我们生产预订单支付提示用户登录或者注册)
  • 订单服务调用库存服务,完成库存的进销存功能
  • 订单服务调用仓储服务,完成物流配送功能
  • 订单服务调用积分服务,完成积分服务功能

至此,整个支付订单的业务流程结束

 

下图随便找张支付流程图,清晰表明了各服务间的调用过程:

重点一:这里最重要的是我们分布式事务管理。针对springboot搭建的项目我们选择 lcn分布式框架进行事务管理。

重点二:针对系统而言我们可能有推送服务,我们建议使用 rabbitmq消息队列进行推送服务和消息通知。

重点三:里面的服务调用通用异步机制,

BATJ面试必问:剖析Spring Cloud底层的工作原理

 

下面我们就开始讲解Spring Cloud微服务架构,在项目中这几个组件如何相互协作,各自发挥的作用以及其背后的原理。

二、Spring Cloud核心组件:Eureka(服务注册和发现)

eureka解决的问题服务如何调用,就上面 订单服务想要调用库存服务、仓储服务,或者积分服务,怎么调用呢?

第一个问题:订单服务压根不知道库存服务在哪台机器上,发起一个请求,都不知道发送给谁。

问题解决方案:Spring Cloud Eureka完美解决问题。Eureka是微服务架构中的注册中心,专门负责服务的注册与发现。

下面就是eureka工作的整个流程:

BATJ面试必问:剖析Spring Cloud底层的工作原理

重要一:库存服务、仓储服务、积分服务中都有一个Eureka Client组件

这个组件专门负责将这个服务的信息注册到Eureka Server中。说白了,就是告诉Eureka Server,自己在哪台机器上,监听着哪个端口。而Eureka Server是一个注册中心,里面有一个注册表,保存了各服务所在的机器和端口号

订单服务里也有一个Eureka Client组件,这个Eureka Client组件会找Eureka Server问一下:库存服务在哪台机器啊?监听着哪个端口啊?仓储服务呢?积分服务呢?然后就可以把这些相关信息从Eureka Server的注册表中拉取到自己本地缓存起来。

这时如果订单服务想要调用库存服务,不就可以找自己本地的Eureka Client问一下库存服务在哪台机器?监听哪个端口吗?收到响应后,紧接着就可以发送一个请求过去,调用库存服务扣减库存的那个接口!同理,如果订单服务要调用仓储服务、积分服务,也是如法炮制。

总结:

  • Eureka Client:负责将这个服务的信息注册到Eureka Server中
  • Eureka Server:注册中心,里面有一个注册表,保存了各个服务所在的机器和端口号

三、Spring Cloud核心组件:Feign(相比http)

服务各自知道对方的端口和ip后。我们就需要去请求,调用这些服务,这里如果不用feign也可以自定义一个http协议封装一下。

问题一:各个服务之间如何建立网络连接呢?

例如:

BATJ面试必问:剖析Spring Cloud底层的工作原理

解决办法:Feign提供了优雅的解决方案。

例如:订单服务调用库存服务的代码

BATJ面试必问:剖析Spring Cloud底层的工作原理

 

feign为我们省去了底层的建立连接、构造请求、解析响应的代码,直接就是用注解定义一个 FeignClient接口,然后调用那个接口就可以了。Feign Client会在底层根据自定义的注解,跟指定的服务建立连接、构造请求、发起靕求、获取响应、解析响应。

Feign实现原理:Feign的一个关键机制就是使用了动态代理

如下

  • 首先,如果你对某个接口定义了@FeignClient注解,Feign就会针对这个接口创建一个动态代理
  • 接着你要是调用那个接口,本质就是会调用 Feign创建的动态代理,这是核心中的核心
  • Feign的动态代理会根据你在接口上的@RequestMapping等注解,来动态构造出你要请求的服务的地址
  • 最后针对这个地址,发起请求、解析响应

BATJ面试必问:剖析Spring Cloud底层的工作原理

下面重点解决分布式服务的解决方案:

 

四、Spring Cloud核心组件:Ribbon(负载均衡)

上面我们解决了,

1.服务各个之间的发现和注册,

2.以及各个服务之间网络通信问题。

下面我们看看分布式各个服务之间如何发现的。

如果库存服务部署在了5台机器上,端口一致,如下所示:

  • 192.168.169:9000
  • 192.168.170:9000
  • 192.168.171:9000
  • 192.168.172:9000
  • 192.168.173:9000

Feign怎么知道该请求哪台机器呢?

我们可以使用 Spring Cloud Ribbon,它的作用是负载均衡,会帮我们在每次请求时选择一台机器,均匀的把请求分发到各个机器上

Ribbon特点:

  • Ribbon的负载均衡默认使用的Round Robin轮询算法。这是啥?简单来说,就是如果订单服务对库存服务发起10次请求,那就先让你请求第1台机器、然后是第2台机器、第3台机器、第4台机器、第5台机器,接着再来—个循环,第1台机器、第2台机器。。。以此类推。

总结三者工作调用流程:Ribbon是和Feign以及Eureka紧密协作,完成工作的,具体流程如下:

  • 首先Ribbon会从 Eureka Client里获取到对应的服务注册表,这样就知道了所有的服务都部署在了哪些机器上,及端口号。
  • 然后Ribbon就可以使用默认的Round Robin算法,从中选择一台机器
  • Feign就会针对这台机器,构造并发起请求。

如下图:

BATJ面试必问:剖析Spring Cloud底层的工作原理

五、Spring Cloud核心组件:Hystrix(容错机制)

在微服务架构里,一个系统会有很多的服务。如果其中一个服务挂掉,不能影响其他服务的正常调用。就此案例来说:订单服务如果调用三个服务。现在假设订单服务自己最多只有50个线程可以处理请求。在这其中,积分服务如果挂了,每次订单服务调用积分服务的时候,都会卡住一段时间等候处理,然后抛出—个超时异常。浪费时间。

  1. 如果系统处于高并发的场景下,大量请求涌过来的时候,订单服务的50个线程都会卡在请求积分服务这块。导致订单服务没有一个线程可以处理请求
  2. 然后就会导致别人请求订单服务的时候,发现订单服务也挂了,不响应任何请求了,这个地方我们需要用消息队列机制处理,

上面这个,就是微服务架构中恐怖的服务雪崩问题,如下图所示:

BATJ面试必问:剖析Spring Cloud底层的工作原理

一般而言,我们各个服务都应该设置成异步多线程调用的。

如上图,如果其中多服务互相调用,要是不做任何保护的话,某一个服务挂了,就会引起连锁反应,导致别的服务也挂。比如积分服务挂了,会导致订单服务的线程全部卡在请求积分服务这里,没有一个线程可以工作,瞬间导致订单服务也挂了,别人请求订单服务全部会卡住,无法响应。

这就是里面没有加入消息队列机制处理。如果加入消息队列机制,我们就会发现服务之间出现异常互不影响。这里面还没有我们说的,缓存机制。也可以加进去。

就单单业务来看:支付订单的时候,只要把库存扣减了,然后通知仓库发货就算功能实现了

  • 如果积分服务挂了,大不了等他恢复之后,慢慢人肉手工恢复数据!为啥一定要因为一个积分服务挂了,就直接导致订单服务也挂了呢?不可以接受!

解决方案:

一,加入消息队列机制。异步执行。

二。使用Hystrix。因为Hystrix是隔离、熔断以及降级的一个框架。

Hystrix实现原理:

Hystrix会搞很多个小小的线程池,比如订单服务请求库存服务是一个线程池,请求仓储服务是一个线程池,请求积分服务是一个线程池。每个线程池里的线程就仅仅用于请求那个服务。

打个比方:现在很不幸,积分服务挂了,会咋样?

当然会导致订单服务里那个用来调用积分服务的线程都卡死不能工作了啊!但由于订单服务调用库存服务、仓储服务的这两个线程池都是正常工作的,所以这两个服务不会受到任何影响。

这个时候如果别人请求订单服务,订单服务还是可以正常调用库存服务扣减库存,调用仓储服务通知发货。只不过调用积分服务的时候,每次都会报错。但是如果积分服务都挂了,每次调用都要去卡住几秒钟干啥呢?有意义吗?当然没有!所以我们直接对积分服务熔断不就得了,比如在5分钟内请求积分服务直接就返回了,不要去走网络请求卡住几秒钟,这个过程,就是所谓的熔断!

如果积分服务挂了你就熔断,道理说不通,不能直接就返回!,还需要降级:每次调用积分服务,你就在数据库里记录一条消息,说给某某用户增加了多少积分,因为积分服务挂了,导致没增加成功!这样等积分服务恢复了,你可以根据这些记录手工加一下积分。这个过程,就是所谓的降级。

梳理一下Hystrix隔离、熔断和降级的全流程:

BATJ面试必问:剖析Spring Cloud底层的工作原理

这个处理方案就比如我们soa治理差不多,只不过,那是dubbo经常用的框架,我们这是springcloud用的框架。

处理机制都差不多。

六、Spring Cloud核心组件:Zuul(网络路由分片)

上面我们几乎把管理搭建springcloud分布式常用的框架说完了,下面我们看看网络分片问题。

Zuul概念:Zuul,就是微服务网关。这个组件是负责网络路由的。

zuul工作流程:

问题一;

假设我们后台部署了上百个服务,如果我们系统是前后端分离。那么前端开发人员如何调用我们这几百个服务呢?

比如:前端开发人员要请求一下库存服务,我们不可能让人家记着这服务的名字叫做inventory-service?部署在5台机器上?就算人家肯记住这一个,你后台可有几百个服务的名称和地址呢?难不成人家请求一个,就得记住一个?

解决方案:

一般微服务架构中都必然会设计一个网关在里面,像android、ios、pc前端、微信小程序、H5等等,不用去关心后端有几百个服务,就知道有一个网关,所有请求都往网关走,网关会根据请求中的一些特征,将请求转发给后端的各个服务。而且有一个网关之后,还有很多好处,比如可以做统一的降级、限流、认证授权、安全,等等。

七、总结:

总结,上述几个Spring Cloud核心组件,在微服务架构中,分别扮演的角色:

  • Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里
  • Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台
  • Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
  • Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题
  • Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务

以上就是我们通过一个电商业务场景,阐述了Spring Cloud微服务架构几个核心组件的在现实项目中的实现原理。

Spring Cloud的5个核心组件通过一张图串联起来,包括底层的架构原理:

BATJ面试必问:剖析Spring Cloud底层的工作原理

 

 

 


http://chatgpt.dhexx.cn/article/N9jvqFMt.shtml

相关文章

分布式事务及分布式框架Seata

分布式事务 分布式事务是什么? 》本地事务是一个单元的sql,分布式事务也是一个单元的sql,他们区别在于,分布式事务的sql分布在了不同服务上,这里的服务指微服务和数据库服务 ?为什么强调服务是微服务和数…

分布式计算框架Map/reduce

简介: MapReduce是一个基于集群的高性能并行计算平台,MapReduce是一个并行计算与运行的软件框架,MapReduce是一个并行程序设计模型与方法.特点: ①分布可靠,对数据集的操作分发给集群中的多个节点实现可靠性,每个节点周期性返回它完成的任务和最新的状态 ②封装了实现细节&a…

什么是分布式架构

一、分布式架构定义 什么是分布式架构 分布式系统(distributed system) 是建立在网络之上的软件系统。 内聚性:是指每一个数据库分布节点高度自治,有本地的数据库管理系统。 透明性:是指每一个数据库分布节点对用户…

分布式架构图解

一、分布式架构图解 1)传统servletjsp模式 2)分布式架构  需要按照功能点把系统拆分,拆分成独立的功能。单独为某一个节点添加服务器。需要系统之间配合才能完成整个业务逻辑。叫做分布式。  分布式架构:多个子系统相互协作…

分布式框架

应用架构 单一应用架构ORM 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。 适用于小型网站,小型管理系统,将所有…

juicer.js @each中的index 索引+1操作

问题描述:想在index1的值显示出来而不是做字符串拼接,如我做的楼号, 想显示2楼,3楼,4楼 解决方法:在index前加一个加号即可。 !{index1}楼 效果: 简单介绍juicer模板: Juicer 是…

Jmetercookie管理器

Jmeter中cookie自动存储 1,新建一个测试计划,然后添加一个"HTTP Cookie 管理器"(用来存储cookie) 2,新建一个线程组,添加一个Sampler-->“HTTP 请求”(用来登录用的),添加一个Samp…

利用3D-DNA流程组装基因组

利用3D-DNA流程组装基因组 使用二代数据或三代数据得到contig后,下一步就是将contig提升到染色体水平。有很多策略可以做到这一点,比如说遗传图谱,BioNano(看运气), HiC, 参考近源物种。 如果利用HiC进行准染色体水平,那么目前常见…

Hic-pro的结果文件转化为.hic文件,在juicebox中实现可视化

hic数据经过Hic-pro处理后,会生成allvalidpairs文件,这是所有有效配对的文件。一般想要可视化的话,比较复杂。这时我们就可以把它转化为.hic文件,放到juicebox中就很好的可视化。 juicer中的pre命令是用来做这个事情的。只要你的…

Java-juc

1. 进程和线程 进程: 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个基本单位。例如:打开一个 .exe文件就是一个进程、打开360安全软件就是一个进程 线程 线程是进程的一个实体,是进…

Junit

Junit单元测试 简介:本文主要讲解,如何使用Eclipse,进行单元测试。 1.准备工作:搭建实验环境(EclipseJunitAnt) Eclipse:http://www.eclipse.org/ JUnit:http://www.junit.org/ Ant&#x…

juicer使用案例

代码结构&#xff1a; 编写main.html&#xff1a;引入方式可从bootcdn直接copy script标签 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge&…

juicer

UPDATE: juicer-0.3.1-dev published github.com. 让我们从一段代码说起&#xff0c;假设有一段这样的JSON数据&#xff1a; var json{name:"流火",blog:"ued.taobao.org" };我们需要根据这段JSON生成这样的HTML代码&#xff1a; 流火 (blog: ued.taoba…

Juicer软件的安装详解

欢迎关注”生信修炼手册”! 软件安装是生物信息实战中最基础的技能之一&#xff0c;只有确保软件安装无误&#xff0c;后续使用起来才会得心应手&#xff0c;不会有很多的bug。juicer软件提供了Hi-C数据一键化分析的pipeline, 这样高度的封装使得用户操作起来更加简便&#xff…

Juicer实战详解

欢迎关注”生信修炼手册”! Juicer软件的运行是非常简单的&#xff0c;只需要设置几个参数就可以了&#xff0c;本文利用官网的小的测试测试数据集来展示该软件的基本用法。 1. 下载测试数据 从以下链接下载测试数据集 https://github.com/aidenlab/juicer/wiki/Running-Juicer…

Juicer: 辅助基因组组装

Juicer: 辅助基因组组装 Juicer 导读 本文主要对处理HiC数据的Juicer程序进行一个简短的介绍&#xff0c;并展示如何利用Juicer进行基因组组装中染色体挂载的第一步。 1. 介绍 算法介绍 Juicer[1] 是一款能够提供一键式分析Loop-Resolution的程序。 特点 只需一次单击&#xff…

如何同步数据库数据

第一步 打开mysql的客户端 这里使用navicat&#xff0c;连接数据库&#xff0c;等到navicat主页面&#xff0c;双击需要操作的数据库连接 第二步 登录到数据库主页面后&#xff0c;点击左侧的数据库链接&#xff0c;打开数据库&#xff0c;可以看到可以操作的所有数据库 第三…

Logstash数据同步

Logstash 是 Elastic 技术栈中的一个技术&#xff0c;它是一个数据采集引擎&#xff0c;可以从数据库采集数据到 ES 中。可以通过设置 自增 ID 主键 或 更新时间 来控制数据的自动同步&#xff1a; 自增 ID 主键&#xff1a;Logstatsh 会有定时任务&#xff0c;如果发现有主键…

数据同步-数据库间的双向同步

当业务侧需要MongoDB降配、活动数据迁移时都需要应用切换数据库实例进行发版&#xff0c;发版过程中需最大程度保证新旧数据库数据一致&#xff0c;这就涉及到了一种同步技术-数据双向同步。在同步过程中遇到了一些可能会产生问题或引发思考的点&#xff0c;希望利用这篇文档进…

什么是数据实时同步,为什么数据实时同步很重要

随着云成为前所未有的数据供应渠道&#xff0c;数据准确性、一致性和隐私性的重要性与日俱增。看似轻微的数据错误或故障可能会产生重大负面影响。但是&#xff0c;​对数据进行排序并将其与现有​&#xff0c;然后定期解析数据实时同步&#xff0c;同时保持数据完整性&#xf…