SpringCloud思维导图
2022-05-10 16:09:56 68 举报AI智能生成
基于SpringAlibabaCloud的微Service,包括:服务注册中心、配置中心、Fegin、网关、Docker容器、MQ、Elasticsearch、服务保护、分布式事务、分布式缓存、缓存同步等。 搞不懂,为何服务 是敏感词,所以,你们懂得。后续将持续完善该导图。
MQ
分布式事务
缓存
ElasticSearch
微Service
模版推荐
作者其他创作
大纲/内容
注册中心
Eureka
角色
服务端,注册中心<br>
客户端
服务提供者
服务消费者
Nacos
服务分级存储
1、一级是服务,例如userService
2、二级是集群,例如杭州或上海
3、三级是实例,例如杭州机房的某台部署了userSerice的服务器<br>
负载均衡策略
1、优先选择同集群服务
本地集群找不到提供者,才去<br>
确定了可用实例列表后,再采用随机负载均衡挑选实例<br>
加权负载均衡
Nacos控制台可以设置实例的权重值,0~1之间<br>
统计全内的多个实例,权重越高被访问的几率就越大
权重设置为0,则完全不会被访问
配置管理
配置自动刷新
多环境配置共享
多服务共享配置
配置中心
统一配置管理
配置自动刷新
多环境配置共享
Ribbon负载均衡
Ribbon
自定义IRule
负载均衡策略
RoundRobinRule<br>
AvailabilityFilteringRule
子主题
子主题
子主题
子主题
子主题
加载模式
懒加载(默认)
饥饿加载
Fegin远程调用
底层实现
日志级别
统一网关
网关功能
身份认证和权限校验
服务路由、负载均衡
请求限流
技术实现
Gateway
路由断言工厂
路由过滤器
全局过滤器GlobalFilter
自定义过滤器
实现GlobalFilter接口,添加@Order注解
zuul
Docker
镜像
容器
数据卷
自定义镜像
结构
入口Entrypoint
层Layer
基础镜像BaseImage
Dockerfile
From
ENV
COPY
RUN
EXPOSE
ENTRYPOINT
DockerCompose<br>
镜像推送和拉取
MQ
优势
流量削峰
事件驱动优势
服务解耦
无级联失败问题
概念
queue
channel
exchange
virtual host
消息模型
基本消息队列
角色
publisher:消息发布者,将消息发送到队列queue
queue:消息队列,负责接受并缓存消息
consumer:订阅队列,处理队列中的消息
流程
发送流程
建立connection
创建channel
利用channel声明队列
利用channel向队列发送消息
接收流程
建立connection
创建channel
利用channel声明队列
定义consumer的消费行为handlerDelivery()<br>
利用channer将消费者与队列绑定
工作消息队列
优点:通过prefetch预取机制来提高消息的处理速度,避免队列消息堆积
多个消费者绑定到一个队列,同一条消息只会被一个消费者处理
通过设置prefetch来控制消费者预取的消息数量
广播
应用思路
在consumer服务中,利用代码声明队列和交换机,并将两者绑定<br>
在consumer服务中,编写两个消费方法,分别监听fanout.queue1和fanout.queue2<br>
在publisher中编写测试方法,向itcast.fanout发送消息<br>
Exchange
作用
接收publisher发送的消息
将消息按照规则路由到与之绑定的队列
不能缓存消息,路由失败,消息丢失
FanoutExchange会将消息路由到每一个与之绑定的队列
声明队列、交换机、绑定关系的Bean
Queue
FanoutExchange
Binding
路由
主题
AMQP
名词释义
应用间消息通信的一种协议,与语言和平台无关。<br>
SpringAMQP
基于AMQP协议定义的一套API规范,提供了模板来发送和接收消息。<br>包含两部分,其中spring-amp是基础抽象,spring-rabbit是底层的默认实现。
如何发送消息?
引入amqp的starter依赖
配置RabbitMQ地址
利用RabbitTemplate的converAndSend方法
如何接收消息?
引入amqp的starter依赖
配置RabbitMQ地址
定义类,添加@Component注解
类中声明方法,添加@RabbitListener注解,方法参数就是消息
消息转换器
接收消息的类型是Object,AMQP会帮我们序列化为字节后发送
消息对象的处理
由MessageConverter来处理的,默认实现为:SimpleMessageConverter,<br>基于JDK的ObjectOutputStream完成序列化<br>
修改对象处理,需要定义一个MessageConverter类型的Bean,推荐使用JSON方式序列化
发送方和接收方使用相同的MessageConverter
消息分发器
Elasticsearch
概念对比
名词释义
一个开源的分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能。<br>面向文档存储的,可以是数据中的一条商品数据,一个订单信息。文档数据会被序列化为JSON格式<br>后存储在Elasticsearch中。
什么是elastic stack(ELK)?<br>
是以elasticsearch为核心的技术栈,<br>包括beats、Logstash(日志搜集)、kibana(监控)、ealsticsearch<br>
什么是LUC饿呢?
是Apache的开源搜索引擎类库,提供了搜索引擎的核心API
存储示意图
正向索引和倒排索引
基于文档id创建索引,查询词条时必须先找到文档,而后判断文档中是否包含词条
对文档内容进行分词,对词条创建索引,并记录词条所在的文档的信息。查询时,先根据词条查找到文档id,而后获取到文档。<br>
分词器
作用
创建倒排索引时对文档分词
用户搜索时,对输入的内容分词
IK分词器
模式
ik_smart:最少切分
ik_max_word:最细切分
词库
拓展词库
停用词库
索引库(Index)
mapping属性
type
字符串:text(可分词文本)、<br>keyword(精确值,例如:品牌、国家、ip地址)<br>
数值:long,integer,short,byte,double,float<br>
布尔:boolean
日期:date
对象:object
index:是否创建索引,默认为true
analyzer:使用哪种分词器
properties:该字段的子字段
mapping是对索引中文档的约束
索引库操作
创建索引库:PUT/索引名
查询索引库:GET/索引库名
删除索引库:DELETE/索引名
添加字段:PUT/索引库名/_mapping
文档(Document)
新增文档:POST/索引库名/_doc/文档id
查询文档:GET /索引库名/_doc/文档id
删除文档:DELETE/索引库名/_doc/文档Id
修改文档
全量修改:PUT/索引库名/_doc/文档Id
增量修改:POST /索引库名/_update/文档id
RestClient操作索引库
名词解释
ES官方提供了各种不同语言的客户端,用来操作DSL。<br>本质上就是组装DSL语句,通过Http请求发送给ES.
基本步骤
初始化RestHighLevelClient
创建XxxIndexRequest.Xxx是CREATE、Get、Delete
准备DSL(CREATE时需要)
发送请求。调用RestHighLevelClent#indices().xxx()方法,<br>xxx是creaete、exists、delete
查询语法
全文检索查询
match查询:全文检索查询的一种,会对用户输入的内容进行分词,<br>然后去倒排索引库检索<br>
multi_match:与match查询类似,只不过允许同时查询多个字段
精确查询
term:根据词条精确值查询
range:根据值的范围查询
地理查询
根据经纬度查询
使用场景
携程:搜索我附近的酒店
滴滴:搜索我附近的出租车
微信:搜索 我附件的人
模式
geo_bounding_box:查询geo_point值落在某个矩形方位的所有文档
geo_distance:查询到指定中心点小于某个距离值的所有文档
Function Score Query
使用function score query ,可以修改文档的相关性算分,<br>根据新得到的算分排序,例如:给如家 这个品牌的酒店排名靠前的场景<br>
复合查询 Boolean Query
组合方式
must:必须匹配每个子查询,类似 与
should:选择性匹配子查询,类似 或
must_not:必须不匹配,不参与算分,类似 非
filter:必须匹配,不参与算分
搜索结果处理
排序
分页
高亮
服务保护
初始Sentinel
雪崩问题:微服务之间相互调用,因为调用链中的一个服务故障,引起整个链路都无法访问的情况<br>
雪崩解决方案
超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待
舱壁模式:也叫线程隔离,限定每个业务能使用的线程数,避免耗尽整个tomcat资源
熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求<br>
流量控制:限制业务访问的QPS,避免服务因流量的徒增而故障
流量控制
名词释义
簇点链路:就是项目内的调用链路,链路中被监控的每个接口就是一个资源。<br>默认情况下,sentinel会监控SpringMVC的每个端点(EndPoint),<br>因此SpringMVC的每一个端点(EndPoint)就是调用链路中的一个资源。<br>
流控模式
直接:对当前资源限流。
关联:高优先级资源触发阈值,对低优先级资源限流。
链路:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流。
流控效果
快速失败达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
warm up:预热模式,QPS超过阈值后,拒绝新的请求;<br>QPS阈值是主键提升的,可以避免冷启动时并发导致服务宕机。<br>
排队等待
热点参数限流
分别统计参数值相同的请求,判断是否超过QPS阈值
隔离和降级
模式
线程隔离
实现方式
线程池隔离
优点:支持主动超时、支持异步调用
缺点:线程的额外开销比较大
场景:低扇出
信号量隔离<br>(Sentinel默认采用)<br>
优点:轻量级,无额外开销
缺点:不支持主动超时<br> 不支持异步调用
场景:高频调用、高扇出
熔断降级
由断路器统计服务调用的异常比例、慢请求比例,如果超出阈值,<br>则熔断该服务。即拦截访问该服务的一切请求;<br>而当服务回复时,断路器会放行访问该服务的请求。<br>
调用过程
Fegin整合Sentinel
在application.yml中配置:fegin.sentinel.enable=true<br>
给FeginClent编写FallbackFactory,并注册为Bean
将FallbackFactory配置到FeignClient
授权规则
授权规则
名词释义:对调用方的来源做控制
方式
白名单
黑名单
自定义异常结果
实现BlockExceptionHandler接口
规则持久化
规则管理模式
原始模式:Sentinel的默认模式,将规则保存在内存,重启服务会丢失。
pull模式保存在本地文件或数据库,定时去读取,存在时效性问题,导致服务不一致、数据一致性问题
push模式:保存在nacos,监听变更实时更新。依赖于nacos,并且需要修改Sentinel控制台源码。
分布式事务
事务的ACID原则
原子性:事务中的所有操作,要么全部成功,要命全部失败
一致性:要保证数据库内部完整性约束、声明性约束
持久性:对数据库做的一切修改将永久保存,不管是否出现故障
隔离性:对同一资源操作的事务,不能同时发生
理论基础
CAP定理
指标
Consistency(一致性)
Availability(可用性)
Partition tolerance(分区容错性)
定理内容
分布式系统节点通过网络连接,一定会出现分区问题(P)
当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足
思考内容:elasticsearch集群是CP还是AP?
ES集群出现分区时,故障节点会被剔除,数据分片会重新分配到其他节点,<br>保证数据的一致。<br>因此是,低可用性,高一致性,属于CP。<br>
BASE理论
名词释义:对CAP的一种解决思路
三个思想
Basically Available(<b><font color="#ff0000">基本可用</font></b>):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。
Soft State(<b><font color="#ff0000">软状态</font></b>):在一定时间内,允许出现中间状态,比如临时不一致状态。
Eventually Consistant(<b><font color="#ff0000">最终一致性</font></b>):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。
模式
AP模式:各子事务分别执行和提交,允许出现结果不一致,然后采用弥补措施恢复数据即可,实现<b><font color="#ff0000">最终一致</font></b>。
<span style="font-size: inherit;">CP模式:各个渍食物执行后相互等待,同时提交,同时回滚,达成</span><b style="font-size: inherit;"><font color="#ff0000">强一致</font></b><span style="font-size: inherit;">。但事务等待过程中,处于<b><font color="#ff0000">弱可用</font></b>状态。</span><br>
事务模型和思想
全局事务
分支事务
最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据
强一致思想:各分支事务执行完业务不提交,等待彼此结果。而后统一提交或回滚。
典型的分布式事务过程
名词解释
Transaction Coordinator (TC): 事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚。
Transaction Manager (TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议。
Resource Manager (RM): 控制分支事务,负责分支注册、状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚。
分布式事务过程
TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID;
XID在微服务调用链路的上下文中传播;
RM向TC注册分支事务,并将其纳入XID对应全局事务的管理中;
TM向TC发起针对XID的全局提交或回滚决议;
TC调度XID下管辖的全部分支事务完成提交或回滚请求。
Seata
角色划分
TC(Transaction Coordinator)-事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。
TM(Transaction Manager)-事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
RM(Resource Manager)-资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,<br>并驱动分支事务提交或回滚。<br>
解决方案
XA模式
名词释义
<b><font color="#ff0000">强一致性</font></b>分阶段事务模式,牺牲了一定的可用性,无业务侵入。
调用流程
RM一阶段
注册分支事务到TC(事务协调者)
执行分支业务sql但不提交
报告执行状态到TC(事务协调者)
二阶段
TC(事务协调者)二阶段的工作
TC检测个分支事务的执行状态
如果都成功,通知所有RM提交事务
如果有失败,通知所有RM回滚事务
RM二阶段的工作
接收TC(事务协调者)指令,提交或回滚事务
优点
事务的强一致性,满足ACID原则。
常用数据库都支持,实现简单,并且没有代码侵入。
缺点
因为一阶段需要锁定数据资源,等待二节段结束才释放,性能较差。
依赖关系型数据库实现事务。
AT模式
名词释义
<b><font color="#ff0000">最终一致</font></b>的分阶段事务模式,无业务侵入,也是Seata的<b><font color="#ff0000">默认模式</font></b>。<br>也是分阶段提交的事务模型,不过<b><font color="#ff0000">弥补</font></b>了XA模型中的<b><font color="#ff0000">资源锁定周期过长</font></b>的缺陷。
调用流程
阶段一RM的工作
注册分支事务
记录undo-log(数据快照:before-image、after-image)
执行业务sql并提交
报告事务状态
阶段二提交时RM的工作
删除undo-log即可
阶段二回滚时RM的工作
根据undo-log恢复数据到更新前
优点
一阶段完成直接提交事务,释放数据库资源,<b><font color="#ff0000">性能比较好</font></b>。
利用全局锁实现读写隔离
没有代码侵入,框架自动完成回滚和提交
缺点
两阶段之间属于软状态,属于最终一致
框架的快照功能(保存两份快照:保存之前-before-image、保存之后-after-image)会影响性能,<br>但比XA模式好很多<br>
TCC模式
名词释义
最终一致的分阶段事务模式,有业务侵入。
原理
TCC模式与AT模式非常相似,每阶段都是独立的事务,不同的是TCC通过人工编码来实现数据恢复
实现方法
Try:资源的检测和预留
Confirm:完成资源操作业;要求Try成功Confirm一定要成功
Cancel:预留资源释放,可以理解为try的反向操作。
工作模型图
优点
一阶段完成直接提交事务,释放数据库资源,性能好
相比AT模型,无需生成快照,无需使用全局锁,性能最强。
不依赖<b><font color="#ff0000">数据库事务</font></b>,而是依赖补偿操作,可以用于<b><font color="#ff0000">非事务型数据库</font></b>
缺点
有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
软状态,事务是最终一致
需要考虑Confirm和Cancel的失败情况,做好幂等处理
TCC的空回滚和业务悬挂
空回滚:分支事务的try阶段阻塞时,可能大都只全局事务超时而触发二阶段的cancel操作<br>。在未执行try操作时先执行了cancel操作,这时cancel不能做回滚,就是<b><font color="#ff0000">空回滚</font></b>。
业务悬挂:对于空回滚的业务,如果以后继续执行try,就永远不可能confirm或cancel,者就是<b style="color: rgb(255, 0, 0);">业务悬挂。<br></b><font color="#000000">应当阻止执行空回滚后的try操作,避免悬挂。</font><br>
声明TCC接口
SAGA模式:长事务模式,有业务侵入。
nacos服务名称组成
namespace+group+serviceName+cluster<br>
seata客户端获取tc的cluster名称方式:以tx-group-service的值为key到vgroupMapping中查找<br>
分布式缓存
单点Redis的问题
数据丢失问题
解决方案:实现Redis数据持久化
RDB持久化
RDB也叫Redis数据快照。
RDB方式bgsave
fork主进程得到一个子进程,共享内存空间
子进程读取内存数据并写入新的RDB文件
用信RDB文件替换旧的RDB文件
RDB会在什么时候执行?
默认是服务停止时执行
save 60 1000代表什么含义?
代表60秒内至少执行1000次修改,则触发RDB
缺点
RDB执行间隔时间长,两次RDB之间写入的数据有丢失的风险
fork主进程、压缩、写出RDB文件比较耗时
AOF持久化
名词释义
全称Append Only File(追加文件)。Redis处理的每一个写命令都会记录的AOF文件,<br>可以看做是命令日志文件。<br>
配置
AOF默认是关闭的,需要修改redis.conf来开启:appendonly yes
AOF命令记录的频率通过redis.conf文件配置:
Always
everysec(默认)
no
bgrewriteaof命令:让AOF文件执行重写功能,<br>相同的key只恢复最后一次的写操作。<br>
触发重写AOF配置
AOF文件比上次文件 增长超过多少百分比则触发重写
AOF文件体积最小多大以上才触发重写
并发能力问题
解决方案:搭建主从集群,实现读写分离
主从架构图
如何让B的Redis实例节点成为A的slave节点?
B节点执行命令:slaveof A的IP A的port
数据同步原理
重要概念
Replication Id:简称replId,是数据集标记,id一致,则说明是同一个数据集。<br>每一个master都有唯一的replid,slave则会继承master节点的replid。<br>
offset:偏移量,随着记录在repli_baklong中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。<br>如果slave的offset小于master的offset,说明slave数据落后于master,,需要更新。<br>
主从同步第一次是<b><font color="#ff0000">全量同步</font></b>。
如果slave重启后同步,则是<b><font color="#ff0000">增量同步</font></b>。
原理图
同步流程
slave节点请求(执行replicaof命令)增量同步
master节点判断replid,发现不一致,拒绝增量同步
master将完整内存数据通过bgsave命令生成RDB,发送RDB到slave
slave清空本地数据,加载master的RDB
master将RDB期间的命令记录在repl_baklog,并单独开另一个线程<br>持续将log中的命令发送给slave<br>
salve执行接收到的命令,保持与master之间的同步
baklog导致的offset覆盖风险
示意图
repl_baklog大小有上限,写满后会覆盖最早的数据。如果slave断开太久,导致尚未备份的数据被覆盖,<br>则无法基于log做增量同步,此时只能再次全量同步。<br>
主从集群优化
master节点配置启用无磁盘复制(适用磁盘比较慢,但网络很快的场景),避免全量同步时的磁盘IO.
Redis单节点上的内部占用不要太大,减少RDB导致的过多磁盘IO.
适当提高repl_baklog的大小,发现slave宕机时,尽快实现故障恢复,尽可能避免全量同步。
限制一个master上的slave节点数量,如果实在太多slave,可以采用主-从-从链式结构,减少master压力。
总结
全量同步和增量同步区别?
全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在rep_baklong,<br>逐个发送给slave.<br>
增量同步:slave提交自己的offset到master,master获取repl_baklong中从offset之后的命令给slave.
什么时候执行全量同步?
slave节点第一次连接master节点时
slave断开时间太久,repl_baklog中的offset已经被覆盖时
什么时候执行增量同步?
slave节点断开又恢复,并且在repl_baklog中能找到offset时
故障恢复问题
解决方案:利用Redis哨兵(Sentinel),实现健康监测和自动恢复
结构和作用
<b>监控:</b>Sentinel会不断检查(基于心跳机制)您的master和slave是否按预期工作
基于心跳机制检测服务状态,每隔1秒向集群每隔实例发送ping命令<br>
主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例<b><font color="#ff0000">主观下线</font></b>。
客观下线:若超过指定数量(quornum)的sentinel都认为该实例主观下线,则该实例<font color="#ff0000"><b>客观下线</b>,</font><br>quornum最好超过Sentinel实例数量的一半。<br>
<b>自动故障恢复:</b>如果master故障,Sentinel会将一个slave节点提升为master节点。<br>当故障恢复后也以新的master为主。<br>
<b>通知:</b>Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis客户端。
选举新的master
故障转移步骤
选定一个slave作为新的master,执行slaveof no one,让该节点成为master
sentinel给所有其他节点都执行slaveof 新master的ip 新master的port,开始新的master上同步数据
修改故障节点配置,添加slaveof 新master
配置主从读写分离策略
MASTER:从主节点读取
MASTER_PREFERRED:优先从master节点读取,master不可用才读取replica.
REPLICA:从slave(replica)节点读取
REPLICA_PREFERRED:优先从slave(replica)节点读取,所有的slave都不可用,才读取master
存储能力问题
搭建分片集群,利用插槽机制实现动态扩容
解决问题
海量数据存储问题
高并发写的问题
分片集群特征
集群中有多个master,每个master保存不同数据;
每个master都可以有多个slave节点
master之间通过ping监测彼此健康状态
客户端请求可以访问集群任意节点,最终都会被转发到正确节点
散列插槽
节点映射到插槽(hash slot)上(0~16383)<br>
数据key与插槽绑定
计算插槽值(根据key有效值)
key中包含{},且{}中至少包含一个字符,则{}中的部分就是有效部分
key不包含{},整个key都是有效部分
redis如何判断段某个key<br>应该在哪个实例?<br>
将16384个插槽分配到不同的实例
根据key的有效部分计算hash值,对16384取余
余数作为插槽,寻找插槽所在实例即可
集群伸缩
利用redis-cli --cluster可以操作集群的N多命令,<br>如添加节点:redis-cli --cluster add-node<br>
数据迁移
利用cluster failover命令 可以手动让集群中的某个master宕机,<br>并将数据迁移到执行failover的这个节点<br>
多级缓存<br>
缓存同步<br>
设置有效期<br>
给缓存设置有效期,过期自动删除,再次查询时进行更新<br>
优势:简单、方便<br>
劣势:时效性差,缓存失效之前,可能导致数据不一致<br>
场景:更新频率较低,时效性要求低的业务<br>
同步双写
修改数据库的同时,直接修改缓存<br>
优势:时效性强,缓存与数据库强一致
缺点:有代码入侵,耦合度高
场景:对一致性、时效性要求较高的缓存数据<br>
异步通知
修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据
优势:低耦合,可以同时通知多个缓存服务
缺点:时效性一般,可能存在中间不一致状态
场景:时效性一般,有多个服务需要同步
收藏
立即使用
收藏
立即使用
Collect
Get Started
Collect
Get Started
Collect
Get Started
Collect
Get Started
评论
0 条评论
下一页