Spring Cloud Alibaba学习笔记
2024-02-21 18:10:10 0 举报
AI智能生成
登录查看完整内容
Spring Cloud Alibaba学习笔记
作者其他创作
大纲/内容
屏蔽消息中间件的差异,降低切换恒本,统一的消息编程模型
一句话
https://github.com/spring-cloud/spring-cloud-stream
https://cloud.spring.io/spring-cloud-static/spring-cloud-stream/3.0.3.RELEASE/reference/html/
https://m.wang1314.com/doc/webapp/topic/20971999.html
中文资料
官网
是什么
Message
生产者/消费者之间靠消息媒介传递内容
消息通道 MessageChannel
消息必须走特定的通道
消息通道中的消息如何被消费, 谁来负责收发处理
标准 MQ
Stream 为什么可以统一底层的差异
INPUT 对应于消费者
OUTPUT 对应于生产者
Binder
为什么用 Cloud Stream
在RabbitMQ 就是 Exchange
在Kafka中就是 Topic
Topic 主题进行广播
Stream 中的消息通讯方式遵循了发布-订阅模式
设计思想
很方便的连接中间件,屏蔽差异
通道,是队列 Queue 的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过channel 队列进行配置
Channel
简单的理解为参照对象 Spring Cloud Stream 自身,从 Steam 发布消息就是输出,接受消息就是输入
Source 和 Sink
Spring Cloud Stream 标准流程
中间件,目前只支持 RabbitMQ 和 Kafka
Meddleware
注解标识输入通道,通过该输入通道接收到的消息进入应用程序
@Input
注解标识输入通道,发布的消息将通过通道离开应用程序
@Output
监听队列,用于消费者的队列的消息接受
@StramListener
指信道 channel 和 exchange 绑定在一起。
@EnableBinding
编码API 和 常用注解
消息驱动概述
RbbitMQ 环境OK
stream-provider
stream-consumer
工程模块
案例说明
POM
YML
主启动类
发送消息接口
发送下次接口实现类
Controller
业务类
启动 Eureka
启动 RabbitMQ
启动 RabbitMQ-Provider
访问
测试
消息驱动-生产者
curl http://127.0.0.1:8701/rabbit/send
消息发送端:=======> serial: b63ca8ce81ec4c2bb4429c5b9bff8bf8
消息驱动-消费者
创建多个消费者服务
RabbtMQ
Eureka 服务注册
消息生产者
消息消费者-1
消息消费者-2
启动
有重复消费问题
消息持久化问题
运行后的2个问题
重要
分组和持久化属性 group
如何解决
生产实际问题
目前消费者-1、消费者-2都同时受到了,存在重复消费的问题
消费
故障现象是重复消费
导致现象是默认分组是不同的,组流水号不同,可以消费
自定义配置分组, 自定义配置分为同一个组,解决
重复消费问题
现状描述
微服务应用放置于同一个group 中, 就能保证消息只会被其中一个应用消费一次不停的小组是可以消费的,同一个组内会发生竞争关系,只有其中一个可以消费
原理
消费者-1 修改 YML
消费者-2 修改 YML
自己的配置
结论
消费者-1,消费者-2 都变成了不同组,group 两个不同
消费者-1,消费者-2 实现了轮询分组,每次只有一个消费者发布者 模块发出的消息只能被 消费者-1,消费者-2 其中一个接收到,这样避免了重复消费的问题
group: atcqvie-01
消费者-1,消费者-2 都变成了相同组,group 两个相同
分组
通过上述,解决了重复消费问题,在看看持久化
消费者-1 的 group: atcqvie-01 没有去掉
停止 消费者-1,消费者-2, 并去掉 消费者-2 的 group
发布者先发布消息到 rabbitmq
启动消费者-2,无分组属性配置,后台没有打印出来消息
在启动消费者-1,有分组属性配置,后台打印出来了MQ上的消息
持久化
分组消费与持久化
Spring Cloud Stream消息驱动
问题
为什么会出现这个技术?需要解决那些问题?
https://github.com/spring-cloud/spring-cloud-sleuth
Spring Cloud Sleuth 提供了一套完整的服务跟踪的解决方案。
在分布式系统中提供链路追踪解决方案并兼容支持了zipkin
是什么
解决
概述
Spring Cloud 从 F 版本过后已经不需要自己构建 Zipkin Server 了,只需要调用jar 即可
https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/
zipkin-server-2.12.9-exec.jar
下载
java -jar zipkin-server-2.12.9-exec.jar
运行 jar
访问控制台:http://localhost:9411/zipkin/
子主题
完整的调用链路
一条链路Trace ID 唯一标识, Span 标识发起的请求信息,各个 Span 通过 parent id 关联起来
理解调用链路设计
Trace : 类似于树结构的Span集合, 标识一条链路,存在唯一标识
Span: 标识调用链路来源,通俗的理解 span 就是一个请求信息
名词解释
术语
运行控制台
1,zipkin
启动类
2. 服务提供者
3. 服务消费者(调用方)
4. 依次启动 eureka/ 8001 /8101
5. 打开浏览器访问:http://localhost:9411
搭建链路监控步骤
SpringCloud Sleuth链路追踪
说明
超链接
Spring Cloud Netflix 项目进入维护模式
什么是维护模式
进入维护模式意味着什么呢
Spring Cloud Netflix Projects Entering Maintenance Mode
why 会出现 SpringCloud alibaba
能干什么
https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md
去哪里下
https://github.com/alibaba/spring-cloud-alibaba
https://github.com/alibaba/spring-cloud-alibaba/tree/greenwich
英文
中文
怎么使用
SpringCloud alibaba 带来了什么
SpringCloud alibaba 学习资料获取
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/en-us/
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html
官方文档
去哪里下载
各个注册中心比较
简介
下载地址:https://github.com/alibaba/nacos/releases
nacos-server-1.2.0.zip
创建数据库 nacos
导入数据: config/nacos-mysql.sql
创建数据库和导入SQL
mysql 连接字符串(application.yml)
修改配置
启动: ./bin/startup.sh -m standalone
结果
访问地址:http://127.0.0.1:8848/nacos
运行 Nacos
注册到 nacos
curl http://127.0.0.1:9002/payment/nacos/2
基于 Nacos 的服务提供者
启动 nacos
启动 payment-service、order-service
curl http://127.0.0.1:9101/consumer/payment/nacos/1
基于 Nacos 的服务消费者
nacos 整体架构图
Nacos 全景图所示
Nacos 和 CAP
Nacos 支持 AP 和 CP模式的切换
切换
各种注册中心的对比
服务注册中心对比
作为服务中心演示
bootstrap.yml
application.yml
cos 中的dataid 有的组成结构与 Spring boot 配置文件中的匹配规则
理论
新增配置
${spring.application.name}-${spring.profile.active}.${spring.cloud.nacos.config.file-extension}
公式
prefix 默认为 spring.application.name 的值,也可以通过配置项 spring.cloud.nacos.config.prefix来配置。
spring.profile.active 即为当前环境对应的 profile,详情可以参考 Spring Boot文档。 注意:当 spring.profile.active 为空时,对应的连接符 - 也将不存在,dataId 的拼接格式变成 ${prefix}.${file-extension}
file-exetension 为配置内容的数据格式,可以通过配置项 spring.cloud.nacos.config.file-extension 来配置。目前只支持 properties 和 yaml 类型。
小总结
设置DataId
Nacos 界面配置对应
历史配置
实际操作
Nacos 中的匹配规则
在 Nacos 中添加配置信息
curl http://127.0.0.1:9001/config/info
启动配置信息
修改下 Nacos 中的yaml 配置文件,再次调用查看配置的接口,就会发现配置已经刷新
自带动态刷新
Nacos 作为配置中心 - 基础配置
多环境多项目管理
配置空间
命名空间
Nacos 的图形化管理界面
Namespace + Group + Data ID 三者之间的关系?为什么这样设计?
指定 spring.profile.active 和配置文件的 DataID 来使不同环境读取不同的配置
新建 dev DataID
新建 test DataID
默认空间+ 默认分组 + 新建 dev 和 test 两个 dataID
通过 spring.profile.cative 属性就能惊醒多环境下配置文件的读取
http://127.0.0.1:9001/config/info
test
配置环境是什么就加载什么
DataID 方案
新建 Group
通过 Group 实现环境区分
在 Nacos 图形界面控制台上面新建配置文件 DataID
在 config 下增加一条 group 的配置即可。可配置为 DEV_GROUP 或 TEST_GROUP
bootstrap + application
Group 方案
新建 dev/test 的Namespace
回到服务管理-服务列表查看
按照域名配置填写
Namespace 方案
三种方案加载配合
Case
Nacos 作为配置中心 - 分类配置
作为服务配置中心演示
https://nacos.io/zh-cn/docs/cluster-mode-quick-start.html
官网架构图
上图翻译真实情况
按照上述,我们需要mysql 数据库
官网说明
https://github.com/alibaba/nacos/blob/develop/config/pom.xml
Nacos 默认自带的是嵌入式数据库 derby 。
nacos-mysql.sql
执行脚本
nacos-server-version\acos\\conf 目录下找到 sql 脚本
nacos-server-version\acos\\conf 目录下找到 application.properties
derby 到 mysql 切换配置步骤
Nacos 持久化配置解释
预计需要, 1 个 Nginx + 3个nacos 注册中心 + 1个 mysql
https://github.com/alibaba/nacos/releases/tag/1.2.0
nacos-server-1.2.0.tar.gz
解压后安装
Nacos 下载 liunx 版本
SQL 脚本在哪里
SQL 语句源文件
执行结果
自己 Linunx 机器上的 MySQL 数据库
1. Linunx 服务器上 mysql 数据库配置
config/application.properties
位置
内容
2. apolication.properties 配置
梳理出3台 nacos 集群积极的不同服务器端口号
复制出cluster.conf
这个IP不能写 127.0.0.1. 必须是 Linux 命令 hostname -i 能够识别的 IP
3. Linux 服务器上 nacos 集群配置 cluster.conf
/nacos/bin 目录下有一个 startup.sh
在什么地方,修改什么,怎么修改
思考
修改内容
./startup.sh -p 3333
执行方式
修改 Nginx 的配置文件
nginx.config
ps -ef | grep nacos-server | grep -v grep| wc -l
查看启动 nacos 服务数量
./nginx -c ../conf/nginx.conf
启动 niginx
按照指定启动
5. Nginx 的配置,由它作为负载均衡器
http://192.168.1.3:1111/nacos
记得开放端口,或者云服务器的安全组,如果使用阿里云服务器学生机或者 试用机,可能出现启动不了那么多台nacos 服务,此处我启动三台nacos, 但是实际只启动了2台,
测试通过 nginx 访问 nacos
新建一个配置测试
如图:可见config配置 已经持久化到mysql中
6. 截止到此处, 1 个 Nginx + 3个nacos 注册中心 + 1个 mysql
集群配置步骤(重点)
微服务 启动注册进入 nacos 集群
查看服务注册情况
实现服务之间的相互调用
高可用小总结
Linux 版 Nacos + MySQL 生产环境配置
集群和持久化配置
SpringCloud AlibbaNacos 服务注册中心
https://github.com/alibaba/Sentinel
https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
一句话解释, 之前我们讲过的Hystrix
https://github.com/alibaba/Sentinel/releases
去哪下
主要特征
怎么玩
Sentinel
后台
前台8080
sentinel 组件由2部分组成
下载到本地: sentinel-dashboard-1.7.1.jar
jdk 1.8
8080 端口不能被占用
前提
java -jar 下载到本地: sentinel-dashboard-1.7.1.jar
命令
运行命令
http://127.0.0.1:8080
登录账号密码均为: sentinel
界面
访问 sentinel 管理页面
安装步骤
安装 Sentinel
启动 Nacos 8848
项目工程
java -jar sentinel-dashboard-1.7.1.jar
启动 Sentinel 8080
启动微服务 9301
空空的什么东西都没有
curl "http://127.0.0.1:9001/testA"
curl "http://127.0.0.1:9001/testB"
服务访问
效果
sentienl 采用的是懒加载说明
启动微服务 9301 微服务后查询看 sentienl 控制台
初始化演示
流控规则
进一步说明
基本介绍
系统默认
直接 -> 快速失败
配置说明
快速调用 : http://127.0.0.1:9001/testA
Blocked by Sentinel (flow limiting)
累屎有个 fallback 的兜底方法
直接调用默认报错信息,技术方面 OK但是,是否应该有我们自己的后续处理?
思考???
直接(默认)
当关联的资源达到阈值,时就限流自己
当A关联的资源B到达阈值后,就吸纳流自己
B热事情了,A挂了
关联是什么
配置界面
配置 A
postman 模式并发密集访问 testB
运行后发现testA 挂了
关联
多个请求调用同一个微服务
自己试试
链路
流控模式
直接失败,抛出异常
com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
源码
直接 -> 快速失败(默认流控处理)
公式:阈值除以 coldFactor (默认值3), 经过预热时常后才会到达阈值
https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
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:9001/testB
应用场景
预热
设置
设置效果
https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6-%E5%8C%80%E9%80%9F%E6%8E%92%E9%98%9F%E6%A8%A1%E5%BC%8F
com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
排队等待
流控效果
https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7
配置图示
半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用。具体可以参考 Hystrix
复习 Hystrix
Sentinel 的断路器是没有半开状态的
jemter 压测
RT
jemter 测试
总结
异常比例
异常数是按照分钟统计的
jemeter
异常数
降级策略实战
降级规则
https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
承上启下
com.alibab.csp.sentinel.slots.block.BlockException
sentinel 配置
curl http://127.0.0.1:9001/testHotKey\\?p1\\=1
➜ Downloads curl http://127.0.0.1:9001/testHotKey\\?p1\\=1----- testHotKey% ➜ Downloads curl http://127.0.0.1:9001/testHotKey\\?p1\\=1----- testHotKey% ➜ Downloads curl http://127.0.0.1:9001/testHotKey\\?p1\\=1----- testHotKey% ➜ Downloads curl http://127.0.0.1:9001/testHotKey\\?p1\\=1----- deal_testHotKey% ➜ Downloads curl http://127.0.0.1:9001/testHotKey\\?p1\\=1----- testHotKey%
@SentinelResource(value = "testHotKey"
异常达到了前台用户解决看到,不友好
1
方法 testHotKey 里面第一个参数只要 QPS 超过每秒1次, 马上降级处理
我们自定义的
2
http://127.0.0.1:9001/testHotKey?p1=1
error
http://127.0.0.1:9001/testHotKey?p1=1&p2=2
http://127.0.0.1:9001/testHotKey?p2=2
right
超过1秒钟一个后,达到阈值1后马上被限流了。
普通
我们期望P1参数当它是某个特殊值时, 他的限流值和平时不一样
加入当p1 的值等于5时,它的阈值可以达到 200
特例
特殊情况
http://127.0.0.1:9001/testHotKey\\?p1\\=5
前提条件
参数例外项
其他
热点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
各个参数的配置
curl http://127.0.0.1:9001/testA
是系统级别的限制,一揽子看姐
系统规则
启动 Nacos 成功
启动 Sentinel 成功
业务 RateLimitController
项目配置
配置步骤
图形配置和代码关系
表示1秒钟内查询次数大于1 ,就跑到我们自定义的限流
配置流控规则
1秒钟点击1下,OK
超过上述,疯狂点击,返回了自定义的限流信息,限流发生
关闭服务试试
Sentinel 控制台,流控规则消失了???
额外问题
按资源名称 + 后续处理
通过访问的URL 来限流, 会返回Sentinel 自带默认的限流处理信息
业务类 RateLimitController
http://127.0.0.1:9001/byResource
访问一次
Sentinel 控制台配置
按 URL 地址限流 + 后续处理
上面兜底方法面料的问题
创建 CustomerBlockHandler 类用于自定义限流处理逻辑
CustomerBlockHandler
自定义限流处理类
RateLimitController
http://127.0.0.1:9001/rateLimit/customerBlockHandler
启动微服务后先调用一次
Seninel 控制台配置
测试我们自定义的出来了
进一步的说明
客户自定义限流处理逻辑
多说一句
SphU 自定义资源
Tracer 定义统计
ContextUtil 定义了上下文
Snetinel 主要又三个核心 API
更多注解属性说明
@SentinelResource
sentinel 整合 ribbon + openfeign + fallback
启动 Nacos 和 sentinel
测试地址
提供者 9001/9002
POM
AppConfig
修改后重启微服务
fallback 管运行异常
blockHander 管配置违规
目的
http://127.0.0.1:9101/consumer/fallback/1
给客户error页面不友好
没有任何配置
只有 fallback
只配置 blockHandler
编码
fallback 和 blockHandler 都配置
exceptionsToIgnore
程序异常打印到了前台了,对用户不友好
忽略属性 。。。。
CircleBreakerController
消费者 9101
ribbon 系列
消费侧提供者 9001/9002
Feign 组件一般是消费侧
修改消费侧
带 @FeignClient 注解的业务接口
fallback = PaymentFallbackService.class
http://127.0.0.1:9101/paymentSQL/1
测试 9101 调用 9001 , 此时 故意关闭 9001 微服务提供者,看看消费侧自动降级
处理参考
处理方案
??? 遇到问题:com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidateMetadata
Feign 系列
对比
熔断框架比较
服务熔断功能
一旦我们重启应用,sentinel 规则将消失,生产环境需要将配置规则进行持久化
将想留配置规则持久化经Nacos 保存, 只需要刷新 服务提供者的一个rest地址, sentinel 控制台的流控规则就能看到, 只要Nacos 里面的配置不删除,针对服务提供者的 sentinel 上的控流规则
添加Nacos 数据源配置
内容解析
添加Nacos业务规则配置
启动 9101 后刷新 sentinel 发现业务规则有了
快速访问测试接口
停止9101 再看 sentinel
默认无法加载流控规则
http://127.0.0.1:9101/rateLimit/byUrl
多次调用
重新配置出现,持久化验证通过
重启 9101 再看 sentinel
步骤
规则持久化
SpringCloud AlibabaSentinel 实现熔断与限流
单机没有问题
从 1:1 => 1:N => N:N
分布式前
分布式之后
一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务
分布式事务问题
Seata 是一款开源的分布式事务解决方案,致力于在微服务的分布式事务处理
https://seata.io/zh-cn
全局唯一的事务ID
Transaction ID XID
Transaction Coordinator(TC)
Transaction Manager (TM)
Resource Manager (RM)
3组件概念
分布式事务处理过程的一个ID + 三个组件模型
一个典型的分布式事务过程
处理过程
https://seata.io/zh-cn/blog/download.html
本地 @Transactional
SEATA 的分布式交易解决方案
全局 @GlobalTransactional
怎么玩?
Steate 简介
1. 官网地址
2. 下载版本
先备份
主要修改:自定义事务组名称 + 事务日志存储模式为db + 数据库链接信息
service 模块
store 模块
完整文件
file.conf
mkdir -p logs
创建GC日志目录
3. seata-server-1.0.0.zip 解压到指定目录并修改conf 目录下的 file.conf 配置文件
4. mysql5.7 新建数据库 seata
SQL 1.1.0 版本下载包中没有在此备份
5. 在seate 库中创建表
6. 修改 seata-server-1.0.0\\seata\\conf 目录下的 registry.conf 配置文件
7. 先启动 Nacos 端口号 8848
8. 再启动 seata-server
Seata-Server 安装
Nacos
Seata
以一下的演示都需要 先启动 Nacos 后启动 Seata 确保两个都 OK
分布式事务说明
seata_order; 存储订单的数据库
seata_storage; 存储库存的数据库
seata_account; 存储账户信息的数据库
建库SQL
创建业务数据库
seata_order 库下创建 t_order 表
seata_storage 库下创建 t_storage 表
seata_account 库下创建 t_account 表
在上述的三个库创建对应的业务表
订单-库存-账户3个库下都需要创建各自的回滚日志表
\\seata\\conf 目录下的 db_undo_log.sql (1.0.0 还是没有)
建表SQL
三个库的回滚日志表
最终结果
订单/库存/账户业务数据库准备
下订单 -> 减库存 -> 库余额 -> 改 (订单)状态
业务需求
1. seata-order-service
2. POM
Nacos配置
3. YML
4. file.conf
5. registry.conf
6. domain
OrderDao
resources 文件夹下面 创建文件夹 mapper
7. Dao 接口以及实现
OrderService
AccountService
StorageService
8. Service 接口以及实现
9. Controller
10. Config 配置
11. 主启动类
新建订单 Order
参考订单
新建库存 Storage
新建账户 Account
订单/库存/账户业务微服务准备
数据库初始情况
下单 -> 减库存 -> 扣余额 -> 改(订单)状态
http://127.0.0.1:2001/order/create?userId=1&productId=1&count=1&money=10
数据库情况
正常下单
AccountServiceImpl 添加超时
当库存和账户金额扣减后,订单状态并没有设置为已经完成,没有从零改为1
而且由于feign 的重试机制,账户余额还有可能被多次扣减
故障情况
超时异常,没加 @GlobalTransactional
OrderServiceImpl @GlobalTransactional
下单后没有任何变化
超时异常,添加 @GlobalTransactional
Test
2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的一个分布式事务解决方案
Simple Extensible Autonomous Transaction Architecture ,简单刻拓展自治事务框架
2020开始,可以使用 1.0 以后版本
seata
TC ==> Seata 服务
TM => @GlobalTransactional 事务的发起方
RM 事务的参与方(数据库)
在看 TC/TM/RM 三大组件
TM 开启分布式事务 (TM 向 TC注册全局事务记录)
按业务场景,编排数据库,服务等事务内资源(RM 让TC 回报资源)
TM 结束分布式事务,事务一阶段结束(TM 同志 TC 提交/回滚分布式事务)
TC 汇总事务信息,决定分布式事务是提交还是回滚
TC 通知所有 RM 提交/回滚资源, 事务二阶段结束
执行流程
https://seata.io/zh-cn/docs/overview/what-is-seata.html
一阶段加锁
二阶段提交
二阶段回滚
AT 模式如何做到对业务的无侵入
DEBUG
补充
补充部分
SpringCloud Alibaba Seata 分布式事务
http://dubbo.apache.org/zh-cn/index.html
Apache Dubbo是一个高性能、基于Java的开源RPC框架
是什么 ?
《分布式系统管理与规范》定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”,分布式系统(distributed system)是建立在网络上的软件系统
随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已经无法应对,分布式服务架构以及流动计算架构势在必行,需一个治理系统确保架构有一条不絮的演进。
演变过程
发展演变
分布式系统理论
RPC 基本原理
RPC
提供高性能的基于代理的远程调用能力,服务以接口为粒度,为开发者屏蔽远程调用底层细节。
1. 面向接口代理的高性能 RPC 调用
内置多种负载均衡策略,智能感知下游节点健康状况,显著减少调用延迟,提高系统吞吐量。
2. 智能负载均衡
支持多种注册中心服务,服务实例上下线实时感知。
3. 服务注册与发现
遵循微内核+插件的设计原则,所有核心能力如Protocol、Transport、Serialization被设计为扩展点,平等对待内置实现和第三方实现。
4. 高度可拓展能力
内置条件、脚本等路由策略,通过配置不同的路由规则,轻松实现灰度发布,同机房优先等功能。
5. 运行期流量调度
提供丰富服务治理、运维工具:随时查询服务元数据、服务健康状态及调用统计,实时下发路由策略、调整配置参数。
6. 可视化服务治理和韵味
设计架构
技术架构
Zookeeper 是 Apacahe Hadoop 的子项目,是一个树型的目录服务,支持变更推送,适合作为 Dubbo 服务的注册中心,工业强度较高,可用于生产环境,并推荐使用。
http://zookeeper.apache.org/
下载地址
tar -zxvf apache-zookeeper-3.6.0-bin.tar.gz
解压
cd conf && cp zoo_sample.cfg zoo.cfg
创建配置文件
./bin/zkServer.sh start
运行
安装
1. zookeeper 注册中心
https://github.com/apache/dubbo-admin
mvn clean install
打包
java -Dserver.port=8081 -jar dubbo-admin-server-0.2.0.jar
运行
http://127.0.0.1:8081
访问地址
2. dubbo-admin
环境搭建
服务提供类
1. 服务提供者(dubbo-provider)
启动类/服务调用类
2. 服务调用者(dubbo-consumer)
1. 启动 Zookeeper
2. 启动 dubbo-admin
准备工作
启动服务发布端(dubbo-provider)
1. 服务发布
启动服务消费者(dubbo-consumer)
2. 服务消费
查看服务生产者/消费者
3. 服务消费方调用服务提供者的服务
4. 测试
http://dubbo.apache.org/zh-cn/docs/user/best-practice.html
1. 服务最佳化实践
服务注册与发现
-Ddubbo.registry.address=zookeeper://127.0.0.1:2181
1. System Properties
dubbo.registry.address=zookeeper://127.0.0.1:2181
2. Externalized Configuration
RegistryConfig.setAddress("zookeeper://127.0.0.1:2181")
3. Spring/API
4. Local File
1. dubbo配置优先级
dubbo.reference.com.foo.BarService.check=falsedubbo.reference.check=false
关闭某个服务的启动时检查 (没有提供者时报错):
dubbo.consumer.check=false
关闭所有服务的启动时检查 (没有提供者时报错):
dubbo.registry.check=false
关闭注册中心启动时检查 (注册订阅失败时报错):
2. 启动时检查
timeout = 1000ms
3. 超时配置
retries = 3
查询/修改/删除,不管查询多少次都是幂等的。
幂等操作
数据库新增,比如超时了,就不能是幂等的。
非幂等操作
4. 重试次数
声明服务 1.0.0
声明服务 2.0.0
服务提供者
服务消费者
5. 多版本(灰度发布)
本地存根实现
6. 本地存根
Dubbo 配置
@EnableDubbo
dubbo.scan.base-packages=cn.edu.cqvie
开启 Dubbo 注解功能
@org.apache.dubbo.config.annotation.Service(version = "1.0.0")public class UserServiceImpl implements UserService { // other code}
声明服务
@Reference(version = "1.0.0") private UserService userService;
调用服务
YML 文件中配置
1. 导入 dubbo-spring-boot-starter
provider.xml 示例
consumer.xml 示例
服务调用者
2. 保留 dubbo xml 配置文件
@Service 申明配置
配置文件
指定Spring扫描路径
增加共享配置
3. 使用注解的方式
4. 基于 API 的方式
Dubbo 整合 Spring-Boot 的三种方式
现象: zookeeper 注册中心宕机,还可以消费 dubbo 暴露的服务
健壮性
监控中心宕机不影响使用,只是丢失部分采样数据
数据库宕机后,注册中心仍然能通过缓冲提供服务列表查询,但不能注册新服务
注册中心对等集群,任意一台宕机后,将自动切换到另一台
注册中心全部宕机后,服务提供者和服务消费者仍能通过本地缓存通讯
服务提供者无状态,任意一台宕掉后,不影响使用
服务提供者全部宕掉, 服务消费者应用将无法使用,并无限次重连等待服务提供者恢复
原因:
高可用,通过设计,减少系统不能提供服务的时间。
直联方法
1 zookeeper 宕机与dubbo 直连
随机:Random LoadBalance
轮询:RoundRobin LoadBalance
最少活跃调用数:LeastActive LoadBalance
一致性 Hash: ConsistentHash LoadBalance
2. 负载均衡策略
当服务器压力剧增的情况下,根据实际业务情况以及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作。
什么是服务降级?
可以通过服务降级功能 [1] 临时屏蔽某个出错的非关键服务,并定义降级后的返回策略。向注册中心写入动态配置覆盖规则:RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&dynamic=false&application=foo&mock=force:return+null"));其中:mock=force:return+null 表示消费方对该服务的方法调用都直接返回 null 值,不发起远程调用。用来屏蔽不重要服务不可用时对调用方的影响。还可以改为 mock=fail:return+null 表示消费方对该服务的方法调用在失败后,再返回 null 值,不抛异常。用来容忍不重要服务不稳定时对调用方的影响。
服务降级配置
3. 服务降级
失败自动切换,当出现失败,重试其它服务器 [1]。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。
Failover Cluster
快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。
Failfast Cluster
失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。
Failsafe Cluster
失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
Failback Cluster
并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
Forking Cluster
广播调用所有提供者,逐个调用,任意一台报错则报错 [2]。通常用于通知所有提供者更新缓存或日志等本地资源信息。
Broadcast Cluster
集群容错模式
整合 Hystrix
4. 服务容错 & Hystrix
RPC 图解
RPC 通讯过程
RPC 原理
Netty 是一个一步事件驱动的网络应用程序框架, 用于快速开发可维护的高性能协议服务其和客户端,它极大的简化了 TCP 和 UDP 套戒指服务其等网络编程
BIO (Blocking IO)
NIO (Non-Blocking IO)
Netty 原理
RPC & Netty 原理
框架设计
标签解析
服务暴露流程
服务引用流程
服务调用流程
5. Dubbo 原理
学海无涯,保持持续的学习状态
6. 总结
Dubbo 的高可用场景
Apache Doubbo服务注册中心
版本选择 2.2.5.RELEASE + Hoxton.SR3
IDEA File Type 过滤
Eureka 原理
服务端(Server)环境配置
客户端环境配置
BUG
Eureka 基本搭建
vim /etc/hosts
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
修改配置文件
修改系统配置
YML 修改
启动参数
Eureka 集群环境搭建
YML 注册
RestTemplate Bean 声明添加 @LoadBalanced
代码实例
原始地址:http://localhost:8001
修改后地址:http://PAYMENT-SERVCIE
修改请求地址
@LoadBalanced 默认采用轮询算法
服务的负载均衡
服务注册到 Eureka集群
YML 配置
显示主机名称
IP 配置
actuator 微服务信息完善
获取注册信息
服务发现 Discovery
自我保护的理论
某一时刻,不会自动删除服务
Eureka Server YML 配置
Eureka Client YML 配置
禁用自我保护
Eureka 自我保护
Eureka 停止更新
Eureka (目前停止更新)
docker 命令
安装zk
添加 POM
注意:zk-discovery 中带的 zk 驱动版本和服务器上的 zk 版本是否一致
注册中心内容(基本信息)
持久节点
临时节点
zk 节点的划分
Zookeeper
提供HTTP 和 DNS 两种方式
服务发现
支持多种方式,HTTP,TCP,Docker。 Shell 脚本定制化
健康检查
Key、Value 存储方式
KV 存储
Consul 支持多数据中心
多数据中心
可视化WEB管理
安装步骤 :https://learn.hashicorp.com/consul/getting-started/install
与 spring-cloud 整合
Consul 简介
安装并运行 Consul
业务代码
服务消费者(同服务提供者类似)
Eureka(java、AP、健康检查支持、HTTP、 集成Spring Cloud)
Consul(Go、CP、健康检查支持、HTTP/DNS 、集成Spring Cloud)
Zookeeper(java、CP、健康检查支持、客户端、集成 Spring Cloud)
三个注册中心的异同
Consul
C: Consistency(强一致性)
A: Availability (可用性)
P:Partitiontolerance(分区容错性)
CAP 理论关注细粒度是数据,而不是整体系统设计的
AP(Eureka)
CP (Consul/Zeekeeper)
CAP
SpringCloud 服务注册中心
替代方案 [Spring Cloud Loadbalancer]
停止维护
集中式 LB
进程内 LB
配置轮询(默认轮询)
Ribbon + RestTemplate
LB(负载均衡)
功能
架构说明
(java doc)https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html
getForObject 方法/ getForEntity 方法
postForObject / postForEntity
GET 请求
POST 请求
RestTemplate
Ribbon 负载均衡演示
注意事项
cn.edu.cqvie.myrule
创建包
添加自定义规则配置
启动类上添加 @RibbonClient
如何替换
Ribbon 核心组件 IRule
轮询
com.netflix.loadbalancer.RoundRobinRule
随机
com.netflix.loadbalancer.RandomRule
先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会惊醒冲你是,获取可用的服务
com.netflix.loadbalancer.RetryRule
对RoundRobinRule 的拓展,响应速度越快的实例选择权重越大,越容易被选择
WeightedResponseTimeRule
会先过滤掉由于多次访问故障而处断路器跳闸状态的服务,然后选择一个并发量最小的服务
BestAvailableRule
先过滤掉故障实例,在选择并发较小的实例
AvailabilityFilteringRule
默认规则,符合判断Server 所在区域的性能和 Server 的可用性选择服务器
ZoneAvoidanceRule
IRule: 根据特定算法中从服务列表中选取一个要访问的服务
RoundRobinRule 源码
自定义实现
Ribbon 负载均衡算法
Spring Cloud Ribbon负载均衡
feign 是一个声明式的Web服务客户端,让编写Web服务客户端变得非常容易,只需要创建一个接口并正在接口上添加注解即可。
https://github.com/spring-cloud/spring-cloud-openfeign
GitHub
fegin 能做什么
fegin 和 openfegin 区别
微服务调用接口 + @FeignClient
接口 + 注解
@EnableFeignClients
业务逻辑接口 + @FeignClient 配置调用 Provider 服务
@FeignClient
新建 PaymentFeignServer 接口 并新增注解 @FeignClient
控制层 Controller
微服务调用接口
OpenFeign 使用步骤
OpenFeign 超时控制
日志级别
申明代码
YML 申明
OpenFeign 日志打印
SpringCloud OpenFeign服务调用
Hystrix(目前停止更新)
服务超时(前台显示转圈)
出错(宕机或者程序运行出错)
对方服务超时了,调用者不能一直死等,必须有服务降级
对方服务器 down 机了,调用者不能卡死等待,必须有服务降级
对方服务OK, 调用者自己出现故障(自己等待时间小于服务的超时时间,自己要求服务降级)
解决场景
对方法添加降级
Hystrix 基本搭建
调用方法实例
Hystrix 调用侧使用
配置方法代码
FeigClient
Hystrix 统一的全局配置
服务降级
https://martinfowler.com/bliki/CircuitBreaker.html
大神理论
简单搭建
大神结论
熔断核心参数
当满足一定的阈值的到时候(默认10秒内超过20次请求)
当失败率到达一定的时候,默认10秒内超过50%的请求失败
到达以上阈值,断路器将会开启
当开启的时候,所有的请求都不会进行转发
一段时间之后,(默认5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会挂壁,若失败,继续开始重复 4,5
断路器关闭的条件
断路器打开之后
服务熔断
服务限流在 (Alibaba - Sentiel 学习 )
http://127.0.0.1:8001/hystrix
访问端口
注意依赖
注意新版本 Hystrix 需要在启动类 中指定监控路径
Unable to connect to Command Metric Stream
404
监控配置地址:http://127.0.0.1:8001/hystrix.stream
异常访问:http://127.0.0.1:8001/payment/payInfo/1
正常访问:
监控使用
服务监控
SpringCloud Hystrix服务降级/熔断/隔离
SpringCloud Gateway 使用的 Webflux 中的 reactor-netty 响应式比亲车给你组件,底层采用了netty 通讯框架
源码架构
网关是在微服务访问的入口,对外是负载均衡 Nginx
网关在架构中的位置
1. netflix 不靠谱,zuul2.0 一直跳票,迟迟不发布
2. springcloud gateway 具有如下特征
3. springcloud gateway 和 zuul 的区别
我们为什选择 gateway
zuul1.0 模型
webflux
gateway 模型
zuul 和 gateway
概述简介
路由是构建网关的基本模块, 它由ID, 目标 URI , 一系列的断言和过滤器组成,如果断言为true 则匹配该路由
Route (路由)
参考 Java8 的 java.util.funcation.Predicate开发从人员可以陪陪HTTP 请求中的所有内容(例如请求头或请求参数),如果请求与断言适配类则进行路由
Predicate ( 断言)
指的是Spring框架中的GateFilter 的实例, 使用过滤器, 可以在请求被路由前或者之后进行修改
Filter (过滤)
总体
三大核心概念
匹配路由转发
在执行转发的前后执行过滤链
Gateway 工作流程
路由映射
YML 网关配置
添加网关之前:http://localhost:8501/payment/get/1
添加网关之后:http://localhost:8501/payment/get/1
见前面的步骤
在配置文件YML 中配置
通过网关转发百度新闻网址
config
http://news.baidu.com/guonei
自己实现
代码中注入 RouteLoctor 的 Bean
Gateway 网关路由有两种配置方式
YML 配置说明
入门配置
默认情况下 Gateway 会更具注册中心的服务列表以注册中心上服务名为路径 动态路由进行转发,从而实现动态路由的功能
启动:
通过微服务名实现动态路由
1. After Route Predicate
2. Before Route Predicate
3. Between Route Predicate
4. Cookie Route Predicate
5. Header Route Predicate
6. Host Route Predicate
7. Method Route Predicate
8. Method Route Predicate
9. Query Route Predicate
10. 总结
Predicate 的使用
Spring Cloud Gateway 的Filter
GatewayFilter
GlobalFilter
常用的 GatewayFilter
implements GlobalFilter
两个主要接口介绍
全局日志记录
统一鉴权网关
案例代码
自定义全局过滤器
自定义过滤器
Filter 的使用
Spring Cloud Gateway服务网关
解决了什么问题
集中管理配置文件
运行期间动态调整配置,不再需要在每个服务器部署的机器上编写配置文件,服务会向配置中心统一拉取配置自己的信息
当配置发生变动,服务不需要重启即可感知配置的并发并应用新的配置
将配置信息以REST接口的形式暴露
与GitHub整合配置
ssm-laboratory-config
github 创建仓库
git clone https://github.com/zhengsh/ssm-laboratory-config.git
拉取远程仓库
config-dev.yml
config-test.yml
config-prod.yml
表示多个环境的配置文件
保存格式必须为 UTF-8
git add .
git commit -m 'init yml'
git push
如果需要修改,此处模拟运维人员操作git 和 gitub
添加配置(git)
@EnableConfigServer
127.0.0.1 config3344.com
修改本机 Host 映射
启动 3344
http://127.0.0.1:3344/master/config-dev.yml
测试通过 Config 微服务是否可以从 GitHub 上面读取配置内容
http://127.0.0.1:3344/master/config-test.yml
http://127.0.0.1:3344/master/config-prod.yml
master 分支
http://127.0.0.1:3344/dev/config-dev.yml
dev 分支
/{lable}/{applicaton}-{profile}.yml
http://127.0.0.1:3344/config-dev.yml
http://127.0.0.1:3344/config-test.yml
http://127.0.0.1:3344/config-prod.yml
http://127.0.0.1:3344/config-xx.yml
/{application}-{profile}.yml
http://127.0.0.1:3344/config/dev/master
http://127.0.0.1:3344/config/test/master
http://127.0.0.1:3344/config/prod/master
/{application}/{profile}[/{lable}]
重要配置细节总结
成功实现了通过 SpringCloud Config 从 GItHub 获取配置信息
配置读取规则
Config 服务端配置与测试
POM 配置
YML 解释
curl curl http://127.0.0.1:8001/configInfo
Linux 运维修改了GitHub 上的配置文件内容作出了调整
刷新 Config-Server, 发现 ConfigServer 配置中心立刻响应
Config-Client 没有变化,除非自己重新启动或者重新加载
如果每次修改都需要重启画的 , 那将是一个非常复杂的操作
问题随之而来,分布式分配至的动态刷新问题
Config 客户端配置与测试
避免每次刷新配置都要重启客户端微服务
修改 Server-Client
POM 引入 actuator 监控
@RefeshScope 业务类Controller 修改
curl http://127.0.0.1:8001/configInfo
此时 Config-Client 依然没有生效 ??
此时 修改 GitHub -> Config-Server -> Config-Client
必须是 POST 请求
curl -X POST "http://127.0.0.1:8001/actuator/refresh"
需要发送 POST 请求到 Config-Client
How
避免了服务器的重启
成功将配置更新到 Config-Client
再次
动态刷新
Config 客户端值动态刷新(手动版)
如果有多个微服务客户端 config-client1、config-client2、config-client3
每个微服务都要执行一次 post 请求,手动刷新
是否可以官博,一处通知,处处生效?
我们需要大范围的自动刷新??
思考还有什么问题
SpringCloud Config服务配配置
分布式自动刷新配置功能
可以结合 SpringCloud Config 实现自动刷新配置
解决什么问题?
RabbitMQ
Kafka
Bus 支持两种消息代理
为什么被称作总线
安装:brew install rabbitmq
进入目录: cd /usr/local/Cellar/rabbitmq/3.8.2
启动 :brew services start rabbitmq
http://localhost:15672
访问地址(可视化页面)
输入账号密码:guest guest
RabbitMQ 环境配置(Mac)
必须具备 RabbitMQ 环境
广播效果,需要准备2个接受服务
2)利用消息总线触发一个服务端 ConfigServer 的 bus/refresh 端点,而刷新所有客户端的配置
打破了微服务的职责单一性,因为微服务本省是业务模块,它本不应该承担配置刷新的职责
破坏了微服务各个节点的对等性
第二种方案更加合适,第一种方案不合适的原因
配置中心添加消息支持
如果多个节点,需要对应配置
客户端添加消息支持
修改 GitHub 上的配置
curl -X POST ”http://127.0.0.1:3344/actuator/bus-refresh“
一次发送,处处生效
发送POST 请求
运维工程师
http://127.0.0.1:3344/dev/config-dev.yml
配置中心
http://127.0.0.1:8001/configInfo
客户端
ok
一次修改,广播通知处处生效
SpringCloud Bus 动态刷新全局广播
只通知 payment-8001
不通知 payment-8002
不想全部通知,只想定点通知
指具体某一个实例生效而不是全部
公式:http://127.0.0.1:配置中心端口/actuator/bus-refresh/{destination}
/bus/refresh 请求不在发送到具体的服务实例上,而是发送给config server 通过 destination 参数指定需要更新配置的服务或实例
简单理解
我们这里以刷新 payment-service 为例
curl -X POST "http://127.0.0.1:3344/actuator/bus-refresh/payment-service:8001"
案例
通知总结All
SpringCloud Bus 动态属性定点通知
SpringCloud Bus消息总线
不同环境的不同配置,动态化的配置更新,分环境部署比如:/dev/test/prod/beta/release
Spring Cloud Alibaba
0 条评论
回复 删除
下一页