Spring Cloud Netflix项目进入到维护模式,SpringCloud和Alibaba整合了,来代替之前的Netflix。
所用到的项目,请参考这里
.
spring-cloud-alibaba 版本说明
Nacos
Nacos 源码分析:Nacos 源码解读
spring-cloud-alibaba-nacos服务注册和配置中心
2020-05-26 13:50:51
Nacos简介
1)、为什么叫Nacos?
Nameing Configuration Service
2)、是什么?
一个更易于构建原生应用的动态服务发现、配置管理和服务管理平台
Nacos就是注册中心,配置中心的组合:Nacos = Eureka + Config + Bus
3)、能干嘛?
、替代Eureka做服务注册中心
、替代Config做服务配置中心
4)、相关文档
https://nacos.io/zh-cn/
https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html
https://github.com/alibaba/Nacos
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery
5)、各种注册中心对比
安装并运行Nacos
这里使用Docker安装Nacos单机版
服务注册中心演示
Nacos作为服务注册中心演示
1)、提供者9001
注意:父POM也要引入对应的spring-cloud-alibaba-dependencies
依赖
2)、copy配置,在9011端口启动项目。
3)、提供者9002
为了后面的演示使用。
建立同9001,只是端口号配置不同。
4)、消费者83
默认集成Ribbon
5)、测试
启动9001,9002,83,访问http://localhost:83/consumer/payment/nacos/1
服务注册中心对比
》》》生态图
》》》Nacos和CAP
》》》Nacos支持AP和CP模式的切换
服务配置中心演示
Nacos作为服务配置中心演示
1)、基础配置
》》》3377,读取配置中心内容
》》》分析
配置中心的名称Data Id
的后缀名要和bootstrap.yml的file-extension属性对应
如果Data Id
的后缀名和bootstrap.yml的file-extension属性可以同时为yml,或yaml,但不可以一个是yml,一个是yaml
》》》修改发布,自动更新
2)、分类配置
》》》group
默认:DEFAULT_GROUP
》》》namespace
默认:空 , 找的是对应public,因为public命名空间ID为空
3)、小总结
1 | 项目配置文件 》》》 Nacos配置文件 |
Nacos集群,持久化
2020-05-28 15:38:27 这个折腾了好久,终于完成了。
docker启动的Nginx与docker-compose启动的nacos集群进行负载均衡配置
1)、首先你要启动三个nacos集群。
使用Docker安装Nacos集群,MySQL
2)、这时候,你可以使用docker network ls
来查看哪些网络
使用下面两种方式之一来查看对应nacos容器的端口
1 | # 查看网络example_default下的所有已启动容器的IP地址 |
3)、关于Nginx的配置,参考Dcoker 启动Nginx
但是你不要启动,如果启动了,可以使用docker rm -f 容器名称
进行删除容器
4)、修改nginx的配置文件
1 | # upstream名称 |
5)、启动Nginx
你可以使用下面来启迪,指定网络 example_default
这样可以保证nginx与nacos集群处于同一网段。此时就可以ping通。
1 | docker run --name nginx01 -p 80:80 \ |
6)、访问192.168.1.1/nacos
即可,80端口可以省略
注意:后面要加上 /nacos
7)、测试
8)、坑:
如果向上面正常配置,但还是不能访问。
、可能是因为你的docker-compose启动的容器问题,可以尝试,先docker rm -f 容器名称
删除启动的四个容器
、可能是你的Nginx配置错误,可以尝试先配置一个,看看能不能正常访问proxy_pass http://172.18.0.4:8848
Sentinel
spring-cloud-alibaba-sentinel熔断与限流
2020-05-29 08:08:53
Sentinel简介
1)、官网
https://github.com/alibaba/Sentinel
2)、是什么?
一句话解释就是我们之前讲过的hystrix
3)、能干嘛?
4)、怎么玩?
、服务雪崩
、服务降级
、服务熔断
、服务限流
安装并运行Sentinel
参考Docker 安装 sentinel-dashboard
初始化演示功能
1)、搭建8401
2)、测试8401
多访问几次http://localhost:8401/testA
http://localhost:8401/testB
查看实时监控
,簇点链路
注意:只有你访问之后,簇点链路的列表中才会出现对应的资源。你不访问的路径,也就不会在簇点链路中出现。
流控规则
1)、基本介绍
2)、流控模式
》》》直接(默认)
、QPS配置及说明
、快速点击访问http://localhost:8401/testA
结果 Blocked by Sentinel(flow limiting)
、线程数
此时线程数1,如果JMeter持续1线程在调用,浏览器再访问就会报默认异常。
解释:如果线程数改为2,如果JMeter持续1线程调用,浏览器再访问也正常。但是JMeter持续2线程调用,浏览器再访问就失败了。
因为JMeter线程数2,加上你浏览器的线程数1,总共3线程了,大于流控模式的2了。
、QPS 与 线程数 区别?
QPS是挡在外面的,线程数在挡在里面的。
QPS=3,一个医生办公室只能进3个病人。多余的人在外面等待(异常)。
线程数=1,一个医生办公室进多少人都可以,但里面只有一个医生。不能再有医生进入这个办公室(异常)。
》》》关联
、是什么?
当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流自己
B惹事,A挂了
、配置A
、JMeter测试
》》》链路
省略。。。
3)、流控效果
》》》快速失败
、默认的流控处理,直接失败,抛出异常Blocked by Sentinel(flow limiting)
、源码com.alibaba.csp.sentinel.slots.block.controller.DefaultController
》》》Warm Up
、公式:阈值除以coldFactor(默认值为3),经过预热时长后才会达到阈值
、官网,限流 冷启动https://github.com/alibaba/Sentinel/wiki/限流---冷启动
、默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值
、应用场景:如:秒杀系统在开启瞬间,会有很多流量上来,很可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。
、案例配置
》》》排队等待
、匀速排队,阈值必须设置为QPS
、源码:com.ailibaba.csp.sentinel.slots.block.controller.RateLimiterController
、一间医生办公室,只能一秒处理一个病人。多余的病人在门口等待,最多病人等待2秒就受不了了,不等了(异常)。
降级规则
https://github.com/alibaba/Sentinel/wiki/熔断降级
1)、RT(平均响应时间)
2)、异常比例
3)、异常数
热点规则
官网:https://github.com/alibaba/Sentinel/wiki/热点参数限流
代码:com.alibaba.csp.sentinel.slots.block.BlockException
1)、有位置0的参数,并且QPS>1,就熔断。
2)、当p1=5时,QPS>200才会熔断。
3)、blockHandler兜底方法只针对配置的热点规则生效,对方法内的异常是不进行处理的。
系统规则
官网:https://github.com/alibaba/Sentinel/wiki/系统自适应限流
@SentinelResource
、官网:https://github.com/alibaba/Sentinel/wiki/注解支持
、官网截图
1)、指定流控兜底方法
如果资源名称添加的是@GetMapping中的/byResource,那么就会使用默认的兜底方法 Blocked by Sentinel (flow limiting)
如果资源名称添加的是@SentinelResource的value值byResource,那么就会使用它的blockHandler所指定的方法。
注意:此时关闭服务8401,会发现Sentinel的流控规则消失了。
重启之后,之前的那条流控规则也不会存在,后面我们会讲持久化。
2)、测试无兜底方法
如果不指定blockHandler兜底方法,那么控制台会报出 This application has no explicit mapping for /error, so you are seeing this as a fallback.
3)、自定义限流
服务熔断功能
1)、环境搭建 提供者9003,9004
新建提供者9003,再复制一份提供者9004,只是端口不同。下面只给出9003的截图。
2)、环境搭建 消费者84
3)、测试访问http://localhost:84/consumer/fallback/1
,默认负载均衡:轮询
5)、不指定fallback,也不指定blockHandler
这个是上面84默认的。
6)、只指定fallback(异常)
注意:
、这里修改了@SentinelResource之后,devtools会不生效,需要重启项目。
、但是,我们没有配置持久化,也就是说,停止服务之后,在Sentinel配置的规则会消失,启动之后也不会再出现。
、这个是Sentinel的持久化问题,在后面我们再讨论,下面每修改一次@SentinelResource,都需要重启项目,重新配置流控规则。
7)、只指定blockHandler(监控)
8)、指定fallback(异常),指定blockHandler(监控)
9)、指定异常,不进行fallback处理
10)、OpenFeign整合Sentinel
关闭9003,9004之后,会发现服务进行降级。
规则持久化
1)、是什么?
一旦我们重启应用,Sentinel规则消失,生产环境需要将配置规则进行持久化。
2)、怎么玩?
将限流规则持久进Nacos保存,只要刷新8401某个rest地址,Sentinel控制台的流控规则就能看得到,只要Nacos里面的配置不删除,针对8401上的流控规则持续有效。
3)、配置,测试【重启之后,规则恢复】
Seata
spring-cloud-alibaba-seata处理分布式事务
简介
0)、问题引入
分布式事务问题:一次业务操作需要垮多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题
案例:用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:
、仓储服务:对给定的商品扣除仓储数量。
、订单服务:根据采购需求创建订单。
、帐户服务:从用户帐户中扣除余额。
1)、是什么?
官网地址:http://seata.io/zh-cn/
Seata是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务
2)、能干嘛?
一个典型的分布式事务过程:
》》》ID + 三组件
Transaction ID(XID):全局唯一的事务id
TC - 事务协调者(Transaction Coordinator)
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM - 事务管理器(Transaction Manager)
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM - 资源管理器(Resource Manager)
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
》》》处理过程
- TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID;
、班主任向讲师申请问:可不可以开班?可以的话,我们就建立班级网课直播间XID - XID在微服务调用链路的上下文中传播;
、班主任把XID在微信群里面上下文传播,只要加进来,具备XID的就是这次网课的同班同学 - RM向TC注册分支事务,将其纳入XID对应全局事务的管辖;
、所有同学往直播间刷1,这时候,注册进来的学生就是讲师的管辖范围,可能会叫你回答问题。不要被逮到玩手机,可能把你踢出去。 - TM向TC发起针对XID的全局提交或回滚决议;
、班主任说:所有同学进行签到,看一下人都到齐了吧,好,到齐了,告诉讲师:你可以上课了 - TC调度XID下管辖的全部分支事务完成提交或回滚请求。
、在这节课的50分钟,全班同学都可以听到。如果结课了,我们再提交,那么就下课了,我们就上到这。
3)、去哪儿下?
当前2020-06-01 13:32:33,下载-GA版本。v1.0.0-GA
https://github.com/seata/seata/releases
4)、怎么玩?
、本地:@Transactional
、全局:@GlobalTransactional
Seata-Server安装
数据库准备
1)、分布式事务业务说明
2)、SQL准备
》》》数据库
、seata_order:订单
、seata_storage:库存
、seata_account:账户
》》》按照上述3库分别建立对应业务表
、seata_order库下新建t_order表
、seata_storage库下新建t_storage表
、seata_account库下新建t_account表
》》》按照上述3库分别建立对应的回滚日志表
、订单-库存-账户3个库下都需要建undo_log各自独立的回滚日志表
3库6表 SQL
1 | create database if not exists seata_order character set utf8; |
3)、创建好之后,注意:account和storage里面都已经存在了一条记录。
微服务准备
1)、业务需求
下订单->减库存->扣余额->改(订单)状态
2)、新建订单Order-Module
3)、新建账户,库存模块。就不截图了。
4)、声明一下
》》》我是使用Docker安装的MySQL,Nacos,Seata。
》》》Seata的容器的配置文件file.conf,registry.conf 与 模块下的Resource下的file.conf,registry.conf是不同的。
注意:我蓝色的三个地方,就是在这里我碰到的坑。
》》》还有如果你也和我一样Docker启动的Seata的话,需要配置一下Windows的路由,参考Windows访问Linux虚拟机里面的Docker容器
测试
》》》不加Seata的@GlobalTransactional注解http://localhost:2001/order/create?userId=1&productId=1&count=10&money=100
结果:(失败)账户内扣钱了,但是订单的状态却没有改变。
》》》加上@GlobalTransactional注解http://localhost:2001/order/create?userId=1&productId=1&count=10&money=100
结果:(成功)碰到了调用超时之后,全部回滚。
》》》关于@GlobalTransactional注解
补充
1)、再看TC/TM/RM三个组件
1 | 分布式事务的执行流程 |
2)、AT模式如何做到对业务的无侵入
》》》是什么?
》》》一阶段加载
》》》二阶段提交
》》》二阶段回滚
3)、Debug
4)、补充
5)、done…
2020-06-05 16:16:21 以此纪念