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