SpringCloud知识结构图
2022-05-07 15:24:13 0 举报
AI智能生成
学习了解springcloud知识图
作者其他创作
大纲/内容
零基础小白,2020.1春节期间预习过第一季的,理解微服务概念的可以不看
理论介绍见
别再用了
回顾2018年第一季SpringCloud版本
1.微服务架构零基础理论入门(小白必看)
SpringBoot2.X版和SpringCloud H版
上篇
SpringCloud Alibaba
下篇
大纲
本次的SpringCloud第二季分为上半场和下半场
https://github.com/spring-projects/spring-boot/releases/
git源码地址:
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes
SpringBoot2.0新特性:
通过上面官网发现,Boot官方强烈建议你升级到2.X以上版本
springboot(截至2019.10.26)
springboot(截至2020.2.15)
官网看Boot版本
Springboot版本选择
https://github.com/spring-projects/spring-cloud/wiki
git源码地址
https://spring.io/projects/spring-cloud
官网:
Cloud命名规则
springcloud(截至2019.10.26)
官网看Cloud版本
SpringCloud版本选择
https://spring.io/projects/spring-cloud#overview
依赖
结果
https://start.spring.io/actuator/info
查看json串返回结果
更详细的版本对应查看方法
SpringCloud和Springboot之间的依赖关系如何看
Hoxton.SR1
cloud
2.2.2.RELEASE
boot
2.1.0.RELEASE
cloud Alibaba
JAVA8
java
3.5及以上
maven
5.7及以上
mysql
不许捣蛋,上述全部版本必须和阳哥一致
分支主题
只用boot,直接用最新
同时用boot和cloud,需要照顾cloud,由cloud决定boot版本
SpringCloud和SpringBoot版本对应关系
boot版已经到2.2.4为最新,为什么选2.2.2?
2.X版本常用的组件pom
题外话
SpringCloud第二季定稿版(截止2020.2.15)
2.从2.2.x和H版开始说起
被动修复bugs
不再接受合并请求
不再发布新版本
停更不停用
停课不停学
补充,哈哈
以前
now2020
明细条目
由停更引发的“升级惨案”
https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
Spring Cloud中文文档
Spring Cloud
https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/
Spring Boot
参考资料见官网
3.关于Cloud各种组件的停更/升级/替换
约定 配置 编码
1.New Project
2.聚合总工程名字
3.Maven选版本
4.工程名字
5.字符编码
6.注解生效激活
7.java编译版本选8
8.File Type过滤
父工程步骤
微服务cloud整体聚合父工程Project
父工程POM
https://blog.csdn.net/HeyWeCome/article/details/104543411
解决maven下载不了jar的问题请复制这个链接到浏览器自行解决:
Maven中的dependencyManagement和dependencies
maven中跳过单元测试
Maven工程落地细节复习
父工程创建完成执行mvn:install将父工程发布到仓库方便子工程继承
IDEA新建project工作空间
创建完成后请回到父工程查看pom文件变化
建cloud-provider-payment8001
改POM文件
写YML
主启动
1.建表SQL
主实体Payment
Json封装体CommonResult
2.entitles
接口PaymentDao
src\\main\esources\\mapper\\PaymentMapper.xml
文件头
路径
PaymentMapper.xml
mybatis的映射文件PaymentMapper.xml
3.dao
接口PaymentService
实现类
4.service
5.controller
业务类
http://localhost:8001/payment/get/31
postman模拟post
通过修改idea的workpace.xml的方式来快速打开Run DashBoard窗口
开启Run DashBoard
部分同学可能由于idea版本不同,需要关闭重启
运行
测试
1.建module
2.改POM
3.写YML
4.主启动
5.业务类
小总结
1.cloud-provider-payment8001微服务提供者支付Module模块
1.Adding devtools to your project
2.Adding plugin to your pom.xml
3.Enabling automatic build
4.Update the value of
5.重启IDEA
2.热部署Devtools
建cloud-consumer-order80
改POM
创建entities(将cloud-provider-payment8001工程下的entities包下的两个实体类复制过来)
是什么
官网及使用
首说RestTemplate
ApplicationContextConfig
config配置类
创建controller
先启动cloud-provider-payment8001
再启动cloud-consumer-order80
http://localhost/consumer/payment/get/32
不要忘记@RequestBody注解
3.cloud-consumer-order80微服务消费者订单Module模块
系统中有重复部分,重构
观察问题
cloud-api-commons
新建
POM
Payment实体
CommonResult通用封装类
entities
maven命令clean install
删除各自的原先有过的entities文件夹
80
8001
各自黏贴POM内容
订单80和支付8001分别改造
4.工程重构
构建步骤
目前工程样图
Rest微服务工程构建
4.微服务架构编码构建
什么是服务治理
什么是服务注册
Eureka两组件
Eureka基础知识
cloud-eureka-server7001
建Module
1.X和2.X的对比说明
@EnableEurekaServer
http://localhost:7001/
结果页面
IDEA生成eurekaServer端服务注册中心类似物业公司
cloud-provider-payment8001
@EnableEurekaClient
先要启动EurekaServer
微服务注册名配置说明
自我保护机制
EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,类似尚硅谷学校对外提供授课服务
cloud-consumer-order80
先要启动EurekaServer,7001服务
再要启动服务提供者provider,8001服务
eureka服务器
http://localhost/consumer/payment/get/31
bug
单机Eureka构建步骤
Eureka集群原理说明
参考cloud-eureka-server7001
新建cloud-eureka-server7002
找到C:\\Windows\\System32\\drivers\\etc路径下的hosts文件
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
修改映射配置添加进hosts文件
修改映射配置
7001
7002
写YML(以前单机)
主启动(复制cloud-eureka-server7001的主启动类到7002即可)
EurekaServer集群环境构建步骤
YML
将支付服务8001微服务发布到上面2台Eureka集群配置中
将订单服务80微服务发布到上面2台Eureka集群配置中
先要启动EurekaServer,7001/7002服务
再要启动消费者,80
测试01
参考cloud-provider-payment8001
新建cloud-provider-payment8002
主启动类
8002
修改8001/8002的Controller
支付服务提供者8001集群环境构建
订单服务访问地址不能写死
使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
提前说一下Ribbon的负载均衡功能
ApplicationContextBean
负载均衡
再要启动服务提供者provider,8001/8002服务
负载均衡效果达到
8001/8002端口交替出现
Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,且该服务还有负载功能了
测试02
集群Eureka构建步骤
当前问题
修改部分
完整部分
修改cloud-provider-payment8001
修改之后
主机名称:服务名称修改
没有ip提示
完整内容
访问信息有ip信息提示
actuator微服务信息完善
对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息
修改cloud-provider-payment8001的Controller
@EnableDiscoveryClient
8001主启动类
再启动8001主启动类,需要稍等一会
http://localhost:8001/payment/discovery
自测
服务发现Discovery
故障现象
一句话:某时刻某一个微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存
属于CAP里面的AP分支
导致原因
eureka.server.enable-self-preservation = true
出厂默认,自我保护机制是开启的
使用eureka.server.enable-self-preservation = false可以禁用自我保护模式
关闭效果
在eurekaServer端7001处设置关闭自我保护机制
注册中心eureakeServer端7001
单位为秒(默认是30秒)
eureka.instance.lease-renewal-interval-in-seconds=30
单位为秒(默认是90秒)
eureka.instance.lease-expiration-duration-in-seconds=90
默认
配置
7001和8001都配置完成
先启动7001再启动8001
马上被删除了
先关闭8001
生产者客户端eureakeClient端8001
怎么禁止自我保护(一般生产环境中不会禁止自我保护)
Eureka自我保护
5.Eureka服务注册与发现
https://github.com/Netflix/eureka/wiki
Eureka停止更新了你怎么办
zookeeper是一个分布式协调工具,可以实现注册中心功能
关闭Linux服务器防火墙后启动zookeeper服务器
zookeeper服务器取代Eureka服务器,zk作为服务注册中心
注册中心Zookeeper
新建cloud-provider-payment8004
Controller
启动后问题
解决zookeeper版本jar包冲突问题
排出zk冲突后的新POM
why
启动8004注册进zookeeper
http://localhost:8004/payment/zk
验证测试
获得json串后用在线工具查看试试
验证测试2
服务节点是临时节点还是持久节点
思考
服务提供者
新建cloud-consumerzk-order80
配置Bean
http://localhost/consumer/payment/zk
访问测试地址
服务消费者
SpringCloud整合Zookeeper代替Eureka
6.Zookeeper服务注册与发现
https://www.consul.io/intro/index.html
提供HTTP和DNS两种发现方式
服务发现
支持多种协议,HTTP、TCP、Docker、Shell脚本定制化
健康监测
KV存储
Consul支持多数据中心
多数据中心
可视化Web界面
能干嘛
https://www.consul.io/downloads.html
去哪下
https://www.springcloud.cc/spring-cloud-consul.html
怎么玩
Consul简介
https://learn.hashicorp.com/consul/getting-started/install.html
官网安装说明
下载完成后只有一个consul.exe文件,硬盘路径下双击运行,查看版本信息
consul agent -dev
通过以下地址可以访问Consul的首页:http;//localhost:8500
使用开发模式启动
安装并运行Consul
cloud-providerconsul-payment8006
新建Module支付服务provider8006
业务类Controller
http://localhost:8006/payment/consul
cloud-consumerconsul-order80
新建Module消费服务order8006
http://localhost/consumer/payment/consul
C:Consistency(强一致性)
A:Availability(可用性)
P:Partition tolerance(分区容错)
CAP理论关注粒度是数据,而不是整体系统设计的策略
CAP
AP(Eureka)
CP(Zookeeper/Consul)
经典CAP图
三个注册中心异同点
7.Consul服务注册与发现
https://github.com/Netflix/ribbon/wiki/Getting-Started
未来替换方案
Ribbon目前也进入维护模式
官网资料
集中式LB
进程内LB
LB(负载均衡)
前面我们讲解过了80通过轮询负载访问8001/8002
负载均衡+RestTemplate调用
一句话
概述
总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。
架构说明
官网
getForObject方法/getForEntity方法
postForObject/postForEntity
GET请求方法
POST请求方法
二说RestTemplate的使用
Ribbon负载均衡演示
轮询
com.netflix.loadbalancer.RoundRobinRule
随机
com.netflix.loadbalancer.RandomRule
先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试
com.netflix.loadbalancer.RetryRule
对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择
WeightedResponseTimeRule
会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
BestAvailableRule
先过滤掉故障实例,再选择并发较小的实例
AvailabilityFilteringRule
默认规则,复合判断server所在区域的性能和server的可用性选择服务器
ZoneAvoidanceRule
IRule:根据特定算法从服务列表中选取一个要访问的服务
修改cloud-consumer-order80
注意配置细节
com.atguigu.myrule
新建package
上面包下新建MySelfRule规则类
主启动类添加@RibbonClient
如何替换
Ribbon核心组件IRule
原理
RoundRobinRule源码
7001/7002集群启动
controller
8001/8002微服务改造
1.ApplicationContextBean去掉@LoadBalanced
2.LoadBalancer接口
3.MyLB
4.OrderController
http://localhost/consumer/payment/lb
5.测试
80订单微服务改造
自己试着写一个本地负载均衡器试试
手写
Ribbon负载均衡算法
8.Ribbon负载均衡服务调用
Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
https://github.com/spring-cloud/spring-cloud-openfeign
GitHub
OpenFeign是什么
Feign和OpenFeign两者区别
微服务调用接口+@FeignClient
接口+注解
Feign在消费端使用
新建cloud-consumer-feign-order80
@EnableFeignClients
业务逻辑接口+@FeignClient配置调用provider服务
新建PaymentFeignService接口并新增注解@FeignClient
控制层Controller
先启动2个eureka集群7001/7002
再启动2个微服务8001/8002
启动OpenFeign启动
Feign自带负载均衡配置项
OpenFeign使用步骤
服务提供方8001故意写暂停程序
服务消费方80添加超时方法PaymentFeignService
服务消费方80添加超时方法OrderFeignController
http://localhost/consumer/payment/feign/timeout
错误页面
超时设置,故意设置超时演示出错情况
OpenFeign默认等待一秒钟,超过后报错
OpenFeign默认支持Ribbon
YML文件里需要开启OpenFeign客户端超时控制
OpenFeign超时控制
日志打印功能
日志级别
配置日志bean
YML文件里需要开启日志的Feign客户端
后台日志查看
OpenFeign日志打印功能
9.OpenFeign服务接口调用
分布式系统面临的问题
服务降级
服务熔断
接近实时的监控
。。。。。
https://github.com/Netflix/Hystrix/wiki/How-To-Use
https://github.com/Netflix/Hystrix
Hystrix官宣,停更进维
服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示,fallback
程序运行异常
超时
服务熔断触发服务降级
线程池/信号量打满也会导致服务降级
哪些情况会触发降级
类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
服务的降级-进而熔断-恢复调用链路
就是保险丝
秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行
服务限流
Hystrix重要概念
新建cloud-provider-hystrix-payment8001
service
启动eureka7001
启动cloud-provider-hystrix-payment8001
http://localhost:8001/payment/hystrix/ok/31
访问
http://localhost:8001/payment/hystrix/timeout/31
每次调用耗费5秒钟
以上述为根基平台,从正确-错误-降级熔断-恢复
上述module均OK
正常测试
构建
上述在非高并发情形下,还能勉强满足 but.....
开启Jmeter,来20000个并发压死8001,20000个请求都去访问paymentInfo_TimeOut服务
再来一个访问
两个都在自己转圈圈
为什么会被卡死
看演示结果
Jmeter压测测试
上面还是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死
Jmeter压测结论
cloud-consumer-feign-hystrix-order80
PaymentHystrixService
OrderHystrixController
http://localhost/consumer/payment/hystrix/ok/31
2W个线程压8001
消费端80微服务再去访问正常的OK微服务8001地址
http://localhost/consumer/payment/hystrix/timeout/31
要么转圈圈等待
要么消费端报超时错误
消费者80,呜呜呜
高并发测试
看热闹不嫌弃事大,80新建加入
8001同一层次的其他接口服务被困死,因为tomcat线程里面的工作线程已经被挤占完毕
80此时调用8001,客户端访问响应缓慢,转圈圈
故障现象和导致原因
正因为有上述故障或不佳表现,才有我们的降级/容错/限流等技术诞生
上诉结论
超时不再等待
超时导致服务器变慢(转圈)
出错要有兜底
出错(宕机或程序运行出错)
对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)down机了,调用者(80)不能一直卡死等待,必须有服务降级
对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级
解决
如何解决?解决的要求
@HystrixCommand
降低配置
设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback
8001先从自身找问题
一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
图示
@HystrixCommand报异常后如何处理
业务类启用
添加新注解@EnableCircuitBreaker
主启动类激活
8001fallback
80订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护
我们自己配置过的热部署方式对java代码的改动明显,但对@HystrixCommand内属性的修改建议重启微服务
题外话,切记
@EnableHystrix
80fallback
每个业务方法对应一个兜底的方法,代码膨胀
统一和自定义的分开
目前问题
feign接口系列
说明
@DefaultProperties(defaultFallback = \"\")
controller配置
每个方法配置一个???膨胀
服务降级,客户端去调用服务端,碰上服务端宕机或关闭
本次案例服务降级处理是在客户端80实现完成的,与服务端8001没有关系,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦
宕机
未来我们要面对的异常
再看我们的业务类PaymentController
修改cloud-consumer-feign-hystrix-order80
根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理
PaymentFallbackService类实现PaymentFeignClientService接口
PaymentFeignClientService接口
单个eureka先启动7001
PaymentHystrixMain8001启动
正常访问测试
故意关闭微服务8001
此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器
客户端自己调用提升
和业务逻辑混一起???混乱
解决问题
一句话就是家里保险丝
断路器
https://martinfowler.com/bliki/CircuitBreaker.html
大神论文
熔断是什么
修改cloud-provider-hystrix-payment8001
why配置这些参数
PaymentService
PaymentController
自测cloud-provider-hystrix-payment8001
http://localhost:8001/payment/circuit/31
正确
http://localhost:8001/payment/circuit/-31
错误
一次正确一次错误trytry
重点测试
实操
大神结论
请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入熔断状态
熔断打开
熔断关闭不会对服务进行熔断
熔断关闭
部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常,关闭熔断
熔断半开
熔断类型
官网步骤
断路器在什么情况下开始起作用
当满足一定阀值的时候(默认10秒内超过20个请求次数)
当失败率达到一定的时候(默认10秒内超过50%请求失败)
到达以上阀值,断路器将会开启
当开启的时候,所有请求都不会进行转发
一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5
断路器开启或者关闭的条件
断路器打开之后
All配置
官网断路器流程图
原理(小总结)
后面高级篇讲解alibaba的Sentinel说明
hystrix案例
https://github.com/Netflix/Hystrix/wiki/How-it-Works
官网图例
步骤说明
hystrix工作流程
新建cloud-consumer-hystrix-dashboard9001
HystrixDashboardMain9001+新注解@EnableHystrixDashboard
所有Provider微服务提供类(8001/8002/8003)都需要监控依赖配置
http://localhost:9001/hystrix
启动cloud-consumer-hystrix-dashboard9001该微服务后续将监控微服务8001
仪表盘9001
注意:新版本Hystrix需要在主启动类MainAppHystrix8001中指定监控路径
Unable to connect to Command Metric Stream
404
启动1个eureka或者3个eureka集群均可
填写监控地址
http://localhost:8001/hystrix.stream
9001监控8001
ok
上述测试通过
监控结果,成功
监控结果,失败
先访问正确地址,再访问错误地址,再正确地址,会发现图示断路器都是慢慢放开的
测试地址
7色
1圈
1线
整图说明
整图说明2
如何看
搞懂一个才能看懂复杂的
观察监控窗口
监控测试
断路器演示
服务监控hystrixDashboard
10.Hystrix断路器
11.zuul路由网关(没讲)
https://github.com/Netflix/zuul/wiki
上一代zuul 1.X
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
当前gateway
Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
源码架构
反向代理
鉴权
流量控制
熔断
日志监控
。。。。。。
微服务架构中网关在哪里
2.SpringCloud Gateway具有如下特性
3.SpringCloud Gateway与Zuul的区别
我们为什么选择Gatway?
Zuul1.x模型
WebFlux是什么?
GateWay模型
有了Zuul了怎么又出来了gateway
概述简介
路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由
Route(路由)
参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Predicate(断言)
指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
Filter(过滤)
总体
三大核心概念
官网总结
路由转发+执行过滤器链
核心逻辑
Gateway工作流程
cloud-gateway-gateway9527
无
get
lb
cloud-provider-payment8001看看controller的访问地址
我们目前不想暴露8001端口,希望在8001外面套一层9527
9527网关如何做路由映射那???
YML新增网关配置
启动7001
启动8001
启动9527网关
添加网关前
http://localhost:9527/payment/get/31
添加网关后
访问说明
见前面步骤
在配置文件yml中配置
官网案例
http://news.baidu.com/guoji
百度国内新闻网址,需要外网
百度新闻
通过9527网关访问到外网的百度新闻网址
业务需求
config
实现业务
编码
自己写一个
代码中注入RouteLocator的Bean
Gateway网关路由有两种配置方式
YML配置说明
新建Module
入门配置
默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
一个eureka7001+两个服务提供者8001/8002
启动
需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。
lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri
8001/8002两个端口切换
http://localhost:9527/payment/lb
通过微服务名实现动态路由
启动我们的gatewat9527
Route Predicate Factories这个是什么东东?
1.After Route Predicate
2.Before Route Predicate
3.Between Route Predicate
不带cookies访问
加入curl返回中文乱码
带上cookies访问
4. Cookie Route Predicate
5. Header Route Predicate
6.Host Route Predicate
7.Method Route Predicate
8.Path Route Predicate
9. Query Route Predicate
All
说白了,Predicate就是为了实现一组匹配规则,让请求过来找到对应的Route进行处理
10.小总结
常用的Route Predicate
Predicate的使用
在业务逻辑之前
pre
在业务逻辑之后
post
生命周期,Only Two
单一
GatewayFilter
全局
GlobalFilter
种类,Only Two
Spring Cloud Gateway的Filter
AddRequestParameter
省略
常用的GatewayFilter
impiemerts GlobalFilter ,Ordered
两个主要接口介绍
全局日志记录
统一网关鉴权
案例代码
http://localhost:9527/payment/lb?uname=z3
自定义全局GlobalFilter
自定义过滤器
Filter的使用
12.Gateway新一代网关
分布式系统面临的配置问题
集中管理配置文件
不同环境不同配置,动态化的配置更新,分环境部署比如dev/test/prod/beta/release
运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
当配置发生变动时,服务不需要重启即可感知到配置的变化并应用新的配置
post、curl访问刷新均可....
将配置信息以REST接口的形式暴露
由于SpringCloud Config默认使用Git来存储配置文件(也有其它方式,比如支持svn和本地文件,但最推荐的还是Git,而且使用的是http/https访问的形式)
与Github整合配置
https://cloud.spring.io/spring-cloud-static/spring-cloud-config/2.2.1.RELEASE/reference/html/
用你自己的账号在Github上新建一个名为sprincloud-config的新Repository
写你自己的仓库地址
由上一步获得刚新建的git地址
本地地址:D:\\44\\SpringCloud2020
git clone xxx
git命令
本地硬盘上新建git仓库并clone
表示多个环境的配置文件
保存格式必须为UTF-8
git add
git commit -m \"init yml\"
git push origin master
如果需要修改,此处模拟运维人员操作git和github
此时在本地D盘符下D:\\44\\SpringCloud2020\\springcloud-config
新建Module模块cloud-config-center-3344它既为Cloud的配置中心模块cloudConfig Center
@EnableConfigServer
ConfigCenterMain3344
127.0.0.1 config-3344.com
windows下修改hosts文件,增加映射
启动微服务3344
http://config-3344.com:3344/master/config-dev.yml
测试通过Config微服务是否可以从Github上获取配置内容
http://config-3344.com:3344/master/config-test.yml
http://config-3344.com:3344/master/config-prod.yml
master分支
http://config-3344.com:3344/dev/config-dev.yml
http://config-3344.com:3344/dev/config-test.yml
http://config-3344.com:3344/dev/config-prod.yml
dev分支
/{label}/{application}-{profile}.yml(最推荐使用这种方式)
http://config-3344.com:3344/config-dev.yml
http://config-3344.com:3344/config-test.yml
http://config-3344.com:3344/config-prod.yml
http://config-3344.com:3344/config-xxxx.yml(不存在的配置)
/{application}-{profile}.yml
http://config-3344.com:3344/config/dev/master
http://config-3344.com:3344/config/test/master
http://config-3344.com:3344/config/prod/master
/{application}-{profile}[/{label}]
重要配置细节总结
配置读取规则
成功实现了用SpringCloud Config 通过GitHub获取配置信息
Config服务端配置与测试
新建cloud-config-client-3355
内容
bootstap.yml
修改config-dev.yml配置并提交到GitHub中,比如加个变量age或者版本号version
类ConfigClientMain3355
启动Config配置中心3344微服务并自测
http://localhost:3355/configInfo
启动3355作为Client准备访问
成功实现了客户端3355访问SpringCloud Config3344通过GitHub获取配置信息
Linux运维修改GitHub上的配置文件内容做调整
刷新3344,发现ConfigServer配置中心立刻响应
刷新3355,发现ConfigServer客户端没有任何响应
3355没有变化除非自己重启或者重新加载
难道每次运维修改配置文件,客户端都需要重启??噩梦
问题随时而来,分布式配置的动态刷新
Config客户端配置与测试
避免每次更新配置都要重启客户端微服务3355
修改3355模块
POM引入actuator监控
修改YML,暴露监控端口
@RefreshScope业务类Controller修改
没有改变,(┬_┬)
3355改变了没有???
此时修改github--- 3344 --- 3355
必须是Post请求
curl -X POST \"http://localhost:3355/actuator/refresh\"
需要运维人员发送Post请求刷新3355
How
OK
避免了服务的重启
成功实现了客户端3355刷新到最新配置内容
再次
步骤
动态刷新
假如有多个微服务客户端3355/3366/3377。。。。
每个微服务都要执行一次post请求,手动刷新?
可否广播,一次通知,处处生效?
我们想大范围的自动刷新,求方法
想想还有什么问题?
Config客户端之动态刷新
13.SpringCloud config分布式配置中心
分布式自动刷新配置功能
Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新
上一讲解的加深和扩充,一言以蔽之
Bus支持两种消息代理:RabbitMQ和Kafka
为何被称为总线
http://erlang.org/download/otp_win64_21.3.exe
安装Erlang,下载地址:
https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe
安装RabbitMQ,下载地址
D:\\scmq\abbitmq_server-3.7.14\\sbin
如例我自己本机
进入RabbitMQ安装目录下的sbin目录
rabbitmq-plugins enable rabbitmq_management
可视化插件
输入以下命令启动管理功能
http://localhost:15672/
访问地址查看是否安装成功
输入账号密码并登录: guest guest
RabbitMQ环境配置
必须先具备良好的RabbitMQ环境先
cloud-config-client-3366
演示广播效果,增加复杂度,再以3355为模板再制作一个3366
打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新职责
破坏了微服务各节点的对等性
有一定的局限性。例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新,那就会增加更多的修改
图二的架构显然更加合适,图一不适合的原因如下
设计思想
给cloud-config-center-3344配置中心服务端添加消息总线支持
给cloud-config-center-3355客户端添加消息总线支持
给cloud-config-center-3366客户端添加消息总线支持
修改Github上配置文件增加版本号
curl -X POST \"http://localhost:3344/actuator/bus-refresh\"
一次发送,处处生效
发送Post请求
运维工程师
http://config-3344.com/config-dev.yml
配置中心
http://localhost:3366/configInfo
获取配置信息,发现都已经刷新了
客户端
一次修改,广播通知,处处生效
SpringCloud Bus动态刷新全局广播
只通知3355
不通知3366
不想全部通知,只想定点通知
指定具体某一个实例生效而不是全部
公式:http://localhost:配置中心的端口号/actuator/bus-refresh/{destination}
/bus/refresh请求不再发送到具体的服务实例上,而是发给config server并通过destination参数类指定需要更新配置的服务或实例
简单一句话
我们这里以刷新运行在3355端口上的config-client为例
curl -X POST \"http://localhost:3344/actuator/bus-refresh/config-client:3355\"
案例
通知总结All
SpringCloud Bus动态刷新定点通知
14.SpringCloud Bus 消息总线
屏蔽底层消息中间件的差异,降低切换版本,统一消息的编程模型
https://spring.io/projects/spring-cloud-stream#overview
https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.1.RELEASE/reference/html/
https://m.wang1314.com/doc/webapp/topic/20971999.html
Spring Cloud Stream中文指导手册
Message
生产者/消费者之间靠消息媒介传递信息内容
消息通道MessageChannel
消息必须走特定的通道
消息通道里的消息如何被消费呢,谁负责收发处理
标准MQ
stream凭什么可以统一底层差异
INPUT对应于消费者
OUTPUT对应于生产者
Binder
为什么用Cloud Stream
在RabbitMQ就是Exchange
在kafka中就是Topic
Topic主题进行广播
Stream中的消息通信方式遵循了发布-订阅模式
很方便的连接中间件,屏蔽差异
通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过对Channel对队列进行配置
Channel
简单的可理解为参照对象是Spring Cloud Stream自身,从Stream发布消息就是输出,接受消息就是输入
Source和Sink
Spring Cloud Stream标准流程套路
编码API和常用注解
消息驱动概述
RabbitMQ环境已经OK
工程中新建三个子模块
案例说明
cloud-stream-rabbitmq-provider8801
主启动类StreamMQMain8801
发送消息接口
发送消息接口实现类
启动7001eureka
启动rabbitmq
启动8801
http://localhost:8801/sendMessage
消息驱动之生产者
cloud-stream-rabbitmq-consumer8802
主启动类StreamMQMain8802
测试8801发送8802接收消息
消息驱动之消费者
cloud-stream-rabbitmq-consumer8803
依照8802,clone出来一份运行8803
RabbitMQ
服务注册
消息生产
8801
消息消费
8802
8803
有重复消费问题
消息持久化问题
运行后两个问题
重要
分组和持久化属性group
如何解决
生产实际案例
目前是8802/8803同时都收到了,存在重复消费问题
消费
微服务应用放置于同一个group中,就能够保证消息只会被其中一个应用消费一次。不同的组是可以消费的,同一个组内会发生竞争关系,只有其中一个可以消费。
group: atguiguA、atguiguB
8802修改YML
8803修改YML
我们自己配置
还是重复消费
结论
8802/8803都变成不同组,group两个不同
8802/8803实现了轮询分组,每次只有一个消费者 8801模块的发的消息只能被8802或8803其中一个接收到,这样避免了重复消费
group: atguiguA
同一个组的多个微服务实例,每次只会有一个拿到
8802/8803都变成相同组,group两个相同
分组
通过上述,解决了重复消费问题,再看看持久化
8803的分组group:atguiguA没有去掉
停止8802/8803并去除掉8802的分组group:atguiguA
8801先发送4条信息到rabbitmq
先启动8802,无分组属性配置,后台没有打出来消息
先启动8803,有分组属性配置,后台打出来了MQ上的消息
持久化
分组消费与持久化
15.SpringCloud Stream消息驱动
问题
为什么会出现这个技术?需要解决哪些问题?
https://github.com/spring-cloud/spring-cloud-sleuth
Spring Cloud Sleuth提供了一套完整的服务跟踪的解决方案
在分布式系统中提供追踪解决方案并且兼容支持了zipkin
SpringCloud从F版起已不需要自己构建Zipkin server了,只需要调用jar包即可
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/
zipkin-server-2.12.9.exec.jar
下载
运行jar
http://localhost:9411/zipkin/
完整的调用链路
上图what
Trace:类似于树结构的Span集合,表示一条调用链路,存在唯一标识
span:表示调用链路来源,通俗的理解span就是一次请求信息
名词解释
术语
运行控制台
1.zipkin
业务类PaymentController
2.服务提供者
3.服务消费者(调用方)
80调用8001几次测试下
4.依次启动eureka7001/8001/80
查看
会出现以下界面
查看依赖关系
5.打开浏览器访问:http:localhost:9411
搭建链路监控步骤
16.SpringCloud Sleuth分布式请求链路追踪
https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now
Spring Cloud Netflix项目进入维护模式
什么是维护模式
进入维护模式意味着什么呢?
SpringCloud NetFlix Projects Entering Maintenance Mode
why会出现SpringCloud alibaba
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
SpringCloud alibaba带来了什么?
https://spring.io/projects/spring-cloud-alibaba#overview
https://github.com/alibaba/spring-cloud-alibaba
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
英文
中文
SpringCloud alibaba学习资料获取
17.SpringCloud Alibaba入门简介
前四个字母分别为Naming和Configuration的前两个字母,最后的s为Service
为什么叫Nacos
一个更易于构建云原生应用的动态服务发现,配置管理和服务管理中心
Nacos:Dynamic Naming and Configuration Service
Nacos = Eureka+Config+Bus
等价于
Nacos就是注册中心+配置中心的组合
替代Eureka做服务注册中心
替代Config做服务配置中心
https://github.com/alibaba/Nacos
https://nacos.io/zh-cn/index.html
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery
官网文档
各种注册中心比较
Nacos简介
本地Java8+Maven环境已经OK
https://github.com/alibaba/nacos/releases/tag/1.1.4
先从官网下载Nacos
解压安装包,直接运行bin目录下的startup.cmd
默认账号密码都是nacos
命令运行成功后直接访问http://localhost:8848/nacos
安装并运行Nacos
cloudalibaba-provider-payment9001
父POM
本模块POM
http://lcoalhost:9001/payment/nacos/1
nacos控制台
nacos服务注册中心+服务提供者9001都ok了
新建cloudalibaba-provider-payment9002
9002其他步骤你懂的
或者取巧不想新建重复体力劳动,直接拷贝虚拟端口映射
为了下一章节演示nacos的负载均衡,参照9001新建9002
基于Nacos的服务提供者
cloudalibaba-consumer-nacos-order83
为什么nacos支持负载均衡
OrderNacosController
83访问9001/9002,轮询负载OK
http://localhost:83/consumer/payment/nacos/13
基于Nacos的服务消费者
Nacos全景图所示
Nacos和CAP
Nacos支持AP和CP模式的切换
切换
各种注册中心对比
服务注册中心对比
Nacos作为服务注册中心演示
cloudalibaba-config-nacos-client3377
why配置两个
bootstrap
application
ConfigClientController
@RefreshScope
Nacos中的dataid的组成格式与SpringBoot配置文件中的匹配规则
理论
配置新增
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
公式
prefix默认为spring.application.name的值
file-exetension为配置内容的数据格式,可以通过配置项spring.cloud.nacos.config.file-extension配置
小总结说明
设置DataId
Nacos界面配置对应
历史配置
Nacos中的匹配规则
在Nacos中添加配置信息
启动前需要在nacos客户端-配置管理-配置管理栏目下有没有对应的yaml配置文件
运行cloud-config-nacos-client3377的主启动类
http://localhost:3377/config/info
调用接口查看配置信息
修改下Nacos中的yaml配置文件,再次调用查看配置的接口,就会发现配置已经刷新
自带动态刷新
Nacos作为配置中心-基础配置
多环境多项目管理
配置管理
命名空间
Nacos的图形化管理界面
Namespace+Group+Data ID三者关系?为什么这么设计?
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
新建dev配置DataID
新建test配置DataID
默认空间+默认分组+新建dev和test两个DataID
通过spring.profile.active属性就能进行多环境下配置文件的读取
test
配置是什么就加载什么
DataID方案
新建Group
通过Group实现环境区分
在nacos图形界面控制台上面新建配置文件DataID
在config下增加一条group的配置即可。可配置为DEV_GROUP或TEST_GROUP
bootstrap+application
Group方案
新建dev/test的Namespace
回到服务管理-服务列表查看
按照域名配置填写
Namespace方案
Case
Nacos作为配置中心-分类配置
Nacos作为服务配置中心演示
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
官网架构图(写的(┬_┬))
上图官网翻译,真实情况
按照上述,我们需要mysql数据库
https://nacos.io/zh-cn/docs/deployment.html
重点说明
官网说明
https://github.com/alibaba/nacos/blob/develop/config/pom.xml
Nacos默认自带的是嵌入式数据库derby
nacos-mysql.sql
执行脚本
nacos-server-1.1.4\acos\\conf目录下找到sql脚本
nacos-server-1.1.4\acos\\conf目录下找到application.properties
derby到mysql切换配置步骤
启动nacos,可以看到是个全新的空记录界面,以前是记录进derby
Nacos持久化配置解释
预计需要,1个nginx+3个nacos注册中心+1个mysql
nacos-server-1.1.4.tar.gz
解压后安装
Nacos下载linux版本
SQL脚本在哪里
sql语句源文件
执行后结果
自己Linux机器上的Mysql数据库黏贴
1.Linux服务器上mysql数据库配置
位置
2.application.properties配置
梳理出3台nacos机器的不同服务端口号
复制出cluster.conf
3.Linux服务器上nacos的集群配置cluster.conf
/mynacos/nacos/bin目录下有startup.sh
在什么地方,修改什么,怎么修改
修改内容
执行方式
4.编辑Nacos的启动脚本startup.sh,使它能够接受不同的启动端
修改nginx的配置文件
nginx.conf
按照指定启动
5.Nginx的配置,由它作为负载均衡器
https://写你自己虚拟机的ip:1111/nacos/#/login
测试通过nginx访问nacos
新建一个配置测试
linux服务器的mysql插入一条记录
6.截止到此处,1个Nginx+3个nacos注册中心+1个mysql
集群配置步骤(重点)
yml
微服务cloudalibaba-provider-payment9002启动注册进nacos集群
高可用小总结
Linux版Nacos+MySQL生产环境配置
Nacos集群和持久化配置(重要)
18.SpringCloud Alibaba Nacos服务注册和配置中心
https://github.com/alibaba/Sentinel
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
一句话解释,之前我们讲解过的Hystrix
https://github.com/alibaba/Sentinel/releases
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_sentinel
服务雪崩
服务使用中的各种问题
Sentinel
后台
前台8080
sentinel组件由2部分组成
下载到本地sentinel-dashboard-1.7.0.jar
java8环境OK
8080端口不能被占用
前提
java -jar sentinel-dashboard-1.7.0.jar
命令
运行命令
http://localhost:8080
登录账号密码均为sentinel
访问sentinel管理界面
安装步骤
安装Sentinel控制台
http://localhost:8848/nacos/#/login
启动Nacos8848成功
cloudalibaba-sentinel-service8401
业务类FlowLimitController
Module
java -jar sentinel-dashboard-1.7.0
启动Sentinel8080
启动微服务8401
空空如也,啥都没有
http://localhost:8401/testA
http://localhost:8401/testB
执行一次访问即可
效果
Sentinel采用的懒加载说明
sentinel8080正在监控微服务8401
启动8401微服务后查看sentienl控制台
初始化演示工程
进一步解释说明
基本介绍
系统默认
直接-快速失败
配置及说明
快速点击访问http://localhost:8401/testA
Blocked by Sentinel (flow limiting)
类似有一个fallback的兜底方法?
直接调用默认报错信息,技术方面OK but,是否应该有我们自己的后续处理?
思考???
直接(默认)
当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流自己
B惹事,A挂了
是什么?
配置A
访问testB成功
postman里新建多线程集合组
将访问地址添加进新线程组
大批量线程高并发访问B,导致A失效了
Run
postman模拟并发密集访问testB
点击访问http://localhost:8401/testA
运行后发现testA挂了
关联
多个请求调用了同一个微服务
家庭作业试试
链路
流控模式
直接失败,抛出异常
com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
源码
直接-快速失败(默认的流控处理)
公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。
https://github.com/alibaba/Sentinel/wiki/%E9%99%90%E6%B5%81---%E5%86%B7%E5%90%AF%E5%8A%A8
限流 冷启动
com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
Warmup配置
刚开始不行,后续慢慢OK
多次点击http://localhost:8401/testB
应用场景
预热
匀速排队,阈值必须设置为QPS
com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
排队等待
流控效果
流控规则
进一步说明
半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考Hystrix
复习Hystrix
Sentinel的断路器是没有半开状态的
代码
jmeter压测
RT
jmeter
异常比例
异常数是按照分钟统计的
异常数
降级策略实战
降级规则
https://github.com/alibaba/Sentinel/wiki/热点参数限流
@SentinelResource
承上启下复习start
com.alibaba.csp.sentinel.slots.block.BlockException
@SentinelResource(value = \"testHotKey\")
异常打到了前台用户界面看不到,不友好
1
@SentinelResource(value = \"testHotKey\
方法testHostKey里面第一个参数只要QPS超过每秒1次,马上降级处理
用了我们自己定义的
2
http://localhost:8401/testHotKey?p1=abc
error
http://localhost:8401/testHotKey?p1=abc&p2=33
http://localhost:8401/testHotKey?p2=abc
right
超过1秒钟一个后,达到阈值1后马上被限流
普通
我们期望p1参数当它是某个特殊值时,它的限流值和平时不一样
假如当p1的值等于5时,它的阈值可以达到200
特例
特殊情况
添加按钮不能忘
http://localhost:8401/testHotKey?p1=5
http://localhost:8401/testHotKey?p1=3
当p1等于5的时候,阈值变为200
当p1不等于5的时候,阈值就是平常的1
热点参数的注意点,参数必须是基本类型或者String
前提条件
参数例外项
后面讲
手贱添加异常看看....
其他
热点key限流
https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81
各项配置参数说明
配置全局QPS
系统规则
启动Nacos成功
启动Sentinel成功
业务类RateLimitController
配置步骤
图形配置和代码关系
表示1秒钟内查询次数大于1,就跑到我们自定义的处流,限流
配置流控规则
1秒钟点击1下,OK
超过上述问题,疯狂点击,返回了自己定义的限流处理信息,限流发送
此时关闭微服务8401看看
临时/持久?
Sentinel控制台,流控规则消失了?????
额外问题
按资源名称限流+后续处理
通过访问的URL来限流,会返回Sentinel自带默认的限流处理信息
访问一次
Sentinel控制台配置
疯狂点击http://localhost:8401/rateLimit/byUrl
按照Url地址限流+后续处理
上面兜底方法面临的问题
创建customerBlockHandler类用于自定义限流处理逻辑
CustomerBlockHandler
自定义限流处理类
RateLimitController
http://localhost:8401/rateLimit/customerBlockHandler
启动微服务后先调用一次
测试后我们自定义的出来了
客户自定义限流处理逻辑
多说一句
SphU定义资源
Tracer定义统计
ContextUtil定义了上下文
Sentinel主要有三个核心API
更多注解属性说明
sentinel整合ribbon+openFeign+fallback
启动nacos和sentinel
新建cloudalibaba-provider-payment9003/9004
记得修改不同的端口号
http://localhost:9003/paymentSQL/1
提供者9003/9004
新建cloudalibaba-consumer-nacos-order84
热部署对java代码级生效及时
对@SentinelResource注解内属性,有时效果不好
修改后请重启微服务
fallback管运行异常
blockHandler管配置违规
目的
http://localhost:84/consumer/fallback/1
给客户error页面,不友好
没有任何配置
编码(那个业务类下面的CircleBreakerController的全部源码)
只配置fallback
只配置blockHandler
fallback和blockHandler都配置
图说
忽略属性...
CircleBreakerController的全部源码
消费者84
Ribbon系列
修改84模块
带@FeignClient注解的业务接口
fallback = PaymentFallbackService.class
PaymentFallbackService实现类
添加@EnableFeignClients启动Feign的功能
http://lcoalhost:84/consumer/openfeign/1
http://lcoalhost:84/consumer/paymentSQL/1
测试84调用9003,此时故意关闭9003微服务提供者,看84消费侧自动降级,不会被耗死
Feign系列
熔断框架比较
服务熔断功能
一旦我们重启应用,Sentinel规则将消失,生产环境需要将配置规则进行持久化
将限流配置规则持久化进Nacos保存,只要刷新8401某个rest地址,sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对8401上Sentinel上的流控规则持续有效
修改cloudalibaba-sentinel-service8401
添加Nacos数据源配置
内容解析
添加Nacos业务规则配置
启动8401后刷新sentinel发现业务规则有了
http://localhost:8401/rateLimit/byUrl
快速访问测试接口
停止8401再看sentinel
扎一看还是没有,稍等一会儿
多次调用
重新配置出现了,持久化验证通过
重新启动8401再看sentinel
规则持久化
19.SpringCloud Alibaba Sentinel实现熔断与限流
单机单库没这个问题
从1:1 - 1:N - N: N
分布式前
分布式之后
一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题
分布式事务问题
Seata是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务
http://seata.io/zh-cn/
官网地址
全局唯一的事务ID
Transaction ID XID
事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚;
Transaction Coordinator(TC)
控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议;
Transaction Manager(TM)
控制分支事务,负责分支注册,状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚;
Resource Manager(RM)
3组件概念
分布式事务处理过程的-ID+三组件模型
处理过程
一个典型的分布式事务过程
发布说明:https://github.com/seata/seata/releases
本地@Transactional
SEATA的分布式交易解决方案
全局@GlobalTransactional
Seata简介
1.官网地址
2.下载版本
先备份原始file.conf文件
主要修改:自定义事务组名称+事务日志存储模式为db+数据库连接信息
service模块
store模块
file.conf
3.seata-server-0.9.0.zip解压到指定目录并修改conf目录下的file.conf配置文件
4.mysql5.7数据库新建库seata
db_store.sql
建表db_store.sql在\\seata-server-0.9.0\\seata\\conf目录里面
SQL
5.在seata库里建表
6.修改seata-server-0.9.0\\seata\\conf目录下的registry.conf配置文件
7.先启动Nacos端口号8848
seata-server.bat
softs\\seata-server-0.9.0\\seata\\bin
8.再启动seata-server
Seata-Server安装
Seata没启动报错no available server to connect
以下演示都需要先启动Nacos后启动Seata,保证两个都OK
业务说明
下订单--扣库存--减账户(余额)
分布式事务业务说明
seata_order: 存储订单的数据库
seata_storage:存储库存的数据库
seata_account: 存储账户信息的数据库
建表SQL
创建业务数据库
seata_order库下建t_order表
seata_storage库下建t_storage表
seata_account库下建t_account表
按照上述3库分别建对应业务表
订单-库存-账户3个库下都需要建各自的回滚日志表
\\seata-server-0.9.0\\seata\\conf目录下的db_undo_log.sql
按照上述3库分别建对应的回滚日志表
最终效果
订单/库存/账户业务数据库准备
下订单-减库存-扣余额-改(订单)状态
1.seata-order-service2001
2.POM
3.YML
4.file.conf
5.registry.conf
CommonResult
Order
6.domain
OrderDao
OrderMapper.xml
resources文件夹下新建mapper文件夹后添加
7.Dao接口及实现
OrderServiceImpl
OrderService
StorageService
AccountService
8.Service接口及实现
9.Controller
MyBatisConfig
DataSourceProxyConfig
10.Config配置
11.主启动
新建订单Order-Module
1.seata-order-service2002
Storage
StorageDao
StorageMapper.xml
StorageServiceImpl
新建库存Storage-Module
1.seata-order-service2003
Account
AccountDao
AccountMapper.xml
AccountServiceImpl
新建账户Account-Module
订单/库存/账户业务微服务准备
数据库初始情况
http://localhost:2001/order/create?userid=1&producrid=1&counr=10&money=100
数据库情况
正常下单
AccountServiceImpl添加超时
当库存和账户余额扣减后,订单状态并没有设置为已经完成,没有从零改为1
而且由于feign的重试机制,账户余额还有可能被多次扣减
故障情况
超时异常,没加@GlobalTransactional
OrderServiceImpl@GlobalTransactional
记录都添加不进来
下单后数据库数据并没有任何改变
超时异常,添加@GlobalTransactional
Test
2019年1月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案
2020起初,参加工作后用1.0以后的版本
Seata
TM开启分布式事务(TM向TC注册全局事务记录)
换业务场景,编排数据库,服务等事务内资源(RM向TC汇报资源准备状态)
TM结束分布式事务,事务一阶段结束(TM通知TC提交/回滚分布式事务)
TC汇总事务信息,决定分布式事务是提交还是回滚
TC通知所有RM提交/回滚资源,事务二阶段结束。
分布式事务的执行流程
再看TC/TM/RM三大组件
一阶段加载
二阶段提交
二阶段回滚
AT模式如何做到对业务的无侵入
debug
补充
Seata之原理简介
20.SpringCloud Alibaba Seata处理分布式事务
SpringCloud知识图
0 条评论
回复 删除
下一页