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

收藏

收藏
0 条评论
下一页