阳哥SpringCloud第2季笔记
2021-03-04 17:42:42 2 举报
AI智能生成
https://www.bilibili.com/video/BV1yE411x7Ky
作者其他创作
大纲/内容
SpringCloud第2季 2020.3V1.6
微服务架构零基础理论入门(小白必看)
前言
1 课程内容(SpringCloud+SpringCloud alibaba)
2 技术要求
java8+maven+git、github+Nginx+RabbotMQ+SpringBoot2.0
4 网站观看建议
5 持续学习
理论介绍见
回顾2018年第一季SpringCloud版本
从2.2.x和H版开始说起
阳哥本次的SpringCloud第二季分为上半场和下半场
上篇
SpringBoot2.x版和SpringCloud H版
下篇
SpringCloud Alibaba
大纲
SpringBoot版本选择
git源码地址
https:github.com/spring-projects/spring-boot/releases/
SpringBoot2.0新特性
https:github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Release-Notes
通过上面官网发现 Boot官方强烈建议你升级到2.X以上版本
官网看Boot版本
springboot(截止2019.10.26)
springboot(截止2020.2.15)
SpringCloud版本选择
https:github.com/spring-projects/spring-cloud/releases/
官网
htts://spring.io/projects/spring-cloud
官网看Cloud版本
Cloud命名规则
springcloud(截止2019.10.26)
Springcloud和Springboot之间的依赖关系如何看
https://spring.io/projects/spring-cloud#overview
依赖
更详细的版本对应查看方法
https://start.spring.io/actuator/info
结果
查看json串返回结果
SpringCloud第二季定稿版(截止2020.2.15)
cloud
Hoxton.SR1
boot
2.2.RELEASE
cloud
alibaba 2.1.0.RELEASE
java
Java8
Maven
3.5及以上
5.7及以上
题外话
Spring Boot 2.2.4
SpringCloud和SpringBoot版本对应关系
2.x版本常用软件pom
关于Cloud各种组件的停更/升级/替换
由停更引发的\"升级惨案\"
停更不停用
被动修复bugs
不再接受合并请求
不再发布新版本
补充
听课不停学
明细条目
以前
now2020
服务注册中心
Eureka
重度患者
Zookeeper
Consul
Nacos
推荐
服务调用
Ribbon
轻度患者
LoadBalancer
Feign
OpenFeign
服务降级
Hystrix
resilience4j
国外使用多
alibaba Sentinel
国内使用多
服务网关
Zuul
Zuul2
胎死腹中
gateway
服务配置
Config
apollo
服务主线
Bus
参考资料见官网
Spring Cloud
https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
Spring Cloud中文文档
https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
Spring Boot
https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/
微服务架构编码 构建
约定配置编码
slave会从master读取binlog来进行数据同步
三步骤+原理图
master将改变记录到二进制日志(binary log)。这些记录过程叫做二进制日志事件,binary log events
slave将master的binary log events拷贝到它的中继日志(relay log)
slave重做中继日志中的事件,将改变应用到自己的数据库中。 MySQL复制是异步的且串行化的
IDEA新建project工作空间
微服务cloud整体聚合工程
父工程步骤
1.New Project
2.聚合总父工程名字
3. Maven选版本
4. 工程名字
5. 字符编码
6. 注解生效激活
7. java编译版本选8
8.File Type过滤
父工程POM
Maven工程落地细节复习
Maven中的DependencyManagement和Dependencies
maven中跳过单元测试
父工程创建完成执行mvn:insall将父工程发布到仓库方便子工程继承
Rest微服务工程搭建
构建步骤
1.Cloud-provider-payment8001 微服务提供者Module模块
1 建module
创建完成后回到父工程查看pom文件变化
2 改POM
3 写YML
4 主启动
5 业务类
1.建表sql
2.emtities
主实体Payment
Json封装体CommonResult
3.dao
接口PaymentDao
mybatis的映射文件PaymentMapper.xml
路径
src\\main\esources\\mapper\\PaymentMapper.xml
文件头
PaymentMapper.xml
4.service
接口PaymentService
实现类
5.controller
测试
http://localhost:8001/payment/get/31
postman模拟post
运行
通过修改idea的workspace.xml的方式快速打开Run Dashboard窗口
开启Run DashBoard
小总结
2.热部署Devtools
1.Adding devtools to your project
2.Adding plugin to your pom.xml
3.Enabling automatic build
4. Update the value of
5.重启idea
3.cloud-consumer-order80 微服务消费者订单Module模块
建cloud-consumer-order80
改POM
写YML
主启动
业务类
entites
首说Resttemplate
是什么
官方使用
config配置类
controller
http://localhost/consumer/payment/get/1
不要忘记@RequestBody注解
4. 工程重构
观察问题
新建
cloud-api-common
POM
entties
Payment实体
CommonResult通用封装类
maven命令clean install
订单80和支付8001分别改造
删除各自的原先的entities文件夹
各自粘贴POM内容
80
8081
目前工程样图
Eureka服务注册与发现
Eureka基础知识
什么是服务治理
什么是服务注册
Eureka两组件
单机Eureka构建步骤
IDEA生成EurekaServer端服务注册中心 类似物业公司
建Module
cloud-eureka-server7001
1.x和2.x的对比说明
http://localhost:7001/
结果页面
No application available没有服务被发现 因为没有注册服务进来当前不可能有服务被发现
cloud-provider-payment8001
1x和2.x的对比
@EnableEurekaClient
先启动EurekaServer
微服务注册名配置说明
自我保护机制
bug
集群Eureka构建步骤
Eureka集群原理说明
Eureka集群环境构建步骤
参考cloud-eureka-server7001
新建cloud-eureka-server7002
修改映射配置
找到C:\\Windows\\System32\\drivers\\etc路径下的hosts文件
修改映射配置添加hosts文件
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
刷新hosts文件
ipconfig /flushdns
写YMl(以前单机)
7001
7002
将支付服务8001微服务发布到上面2台Eureka集群配置中
YAML
将订单服务80微服务发布到上面2台Eureka集群配置中
测试01
http://localhost/consumer/payment/get/31
支付服务提供者8001集群环境搭建
参考cloud-provider-payment8001
新建cloud-provider-payment8002
直接从8001粘
修改8001/8002的controller
负载均衡
订单服务访问地址不能写死
使用@LoadBalanced注解赋予RestTemplate负载均衡的能力
ApplicationContextBean
测试02
负载均衡效果达到
8001/8002端口交替出现
actuator微服务信息完善
主机名称:服务名称修改
当前问题
修改cloud-provoder-payment8001
yaml
修改部分
完整内容
效果
修改之后
访问信息有IP信息提示
没有IP提示
效果图
分支主题
服务发现Discovery
修改cloud-provider-payment8001的Controller
8001的启动类
@EnableDiscoveryClient
自测
先要启动EurekaServer
http://localhost:8001/payment/discovery
eureka自我保护
故障现象
导致原因
属于CAP里面的AP分支
怎么禁止自我保护
注册中心eurekaServer端7001
eureka.server.enable-self-preservation=true
使用eureka.server.enable-self-preservation=false 可以禁用自我保护模式
关闭效果
在eurekaServer端7001处设置关闭自我保护机制
生产者客户端eurekaClient端8001
默认
eureka.instance.lease-renewal-interval-in-seconds=30
单位为秒(默认是30秒)
eureka.instance.lease-expiration-duration-in-seconds=90
单位为秒(默认是390秒)
配置
7001和8001都配置成功
先启动7001再启动8001
先关闭8001
马上被删除了
Zookeeper服务注册与发现
https://github.com/Netflix/eureka/wiki
SpringCloud整合Zookeeper替代Eureka
注册中心Zookeeper
关闭Linux服务器防火墙后启动Zookeeper服务器
服务提供者
新建cloud-provider-payment8004
YML
主启动类
Controller
启动8004注册进zookeeper
启动zk
zkServer.sh start
启动后问题
why
解决zookeeper版本jar包冲突问题
排除zk冲突后的新POM
验证测试
http://localhost:8004/payment/zk
验证测试2
获得json串后用在线工具查看试试
思考
服务节点是临时节点还是持久节点
临时节点
服务消费者
新建cloud-consumerzk-order80
配置bean
访问测试地址
http://localhost/consumer/payment/zk
Consul服务注册与发现
Consul简介
https://www.consul.io/intro/index.html
能干嘛
服务发现
提供HTTP/DNS两种发现方式
健康检测
KV存储
Key、Value的存储方式
多数据中心
Consul支持多数据中心
可视化界面
下哪下
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 agent -dev
通过以下地址可以访问Consul的首页: http://localhost:8500
新建Module支付服务provider8006
cloud-providerconsul-payment8006
业务类Controller
http://localhost:8006/payment/consul
新建Module消费服务order80
cloud-consumerconsul-order80
http://localhost/consumer/payment/consul
三个注册中心异同点
CAP
C: Consistency(强一致性)
A: Availability(可用性)
P: Parttition tolerance(分区容错性)
经典CAP图
AP(eureka)
CP(Zookeeper/Consul)
Ribbon负载均衡调用
概述
官网资料
https://github.com/Netflix/ribbon/wiki/Getting-Started
Ribbon目前也进入维护模式
未来替换方案
LB(负载均衡)
集中式LB
进程内LB
前面我们讲解过了80通过轮询负载访问8001/8002
一句话
负载均衡+RestTemplate调用
Ribbon负载均衡演示
架构说明
二说RestTemplate的使用
getForObject方法/getForEntity方法
postForObject/postEntity
GET请求方法
POST请求方法
Ribbon核心组件IRule
IRule:根据特定算法从服务列表中选取一个要访问的服务
com.netflix.loadbalancer.RoundRobinRule
轮询
com.netflix.loadbalancer.RandomRule
随机
com.netflix.loadbalancer.RetryRule
WeightedResponseTimeRule
BestAvailableRule
AvailabilityFilteringRule
ZoneAvoidanceRule
如何替换
修改cloud-consumer-order80
注意配置细节
新建package
com.atguigu.myrule
上面包下新建MySelfRule规则类
主启动类添加@RibbonClient
Ribbon负载均衡算法
原理
源码
手写
自己试着写一个本地负载均衡器试试
7001/7002集群启动
8001/8002集群启动
80订单微服务改造
1.ApplicationContextBean去掉注解@LoadBalanced
2.LoadBalancer接口
3.MyLB
4.OrderController
5.测试
http://localhost/consumer/payment/lb
OpenFeign服务接口调用
OpenFeign是什么
GitHub
https://github.com/spring-cloud/spring-cloud-openfeign
能干嘛
Feign和OpenFeign两者区别
OpenFeign使用步骤
接口+注解
微服务调用接口+@FeignClient
新建cloud-consumer-feign-order80
Feign在消费端使用
@EnableFeignClients
业务逻辑接口+@FeignClient配置调用provider服务
新建PaymentFeignService接口并新增注解@FeignClient
@FeignClient
控制层Controller
先启动2个eureka集群7001/7002
再启动2个微服务8001/8002
启动OpenFeign
Feign自带负载均衡配置项
OpenFeign超时控制
服务提供方8001故意写暂停程序
服务消费方80添加超时方法PaymentFeignService
服务消费方80添加超时方法OrderFeignController
http://localhost/consumer/payment/feign/timeout
错误页面
OpenFeign默认支持Ribbon
YML文件里需要开启OpenFeign客户端超时控制
OpenFeign日志打印功能
日志打印功能
日志级别
配置日志bean
YML文件里需要开启日志的Feign客户端
后台日志查看
Hystrix熔断器
分布式系统面临的问题
服务熔断
接近实时的监控
https://github.com/Netflix/hystrix/wiki
https://github.com/Netflix/hystrix
HyStrix重要概念
哪些情况会发出降级
程序运行异常
超时
服务熔断触发服务降级
线程池/信号量也会导致服务降级
就是保险丝
服务的降级-进而熔断-恢复调用链路
服务限流
hystrix案例
构建
新建cloud-provider-hystrix-payment8001
service
正常测试
启动eureka7001
启动eureka-provider-hystrix-payment8001
访问
success的方法
http://localhost:8001/payment/hystrix/ok/31
每次调用耗费5秒钟
http://localhost:8001/payment/hystrix/timeout/31
上述module均OK
高并发测试
Jmeter压测测试
再来一个访问
看演示结果
两个都在转圈圈
为什么会被卡死
Jmeter压测结论
cloud-consumer-feign-hystrix-order80
PaymentHystrixService
OrderHyrixController
http://localhost/consumer/payment/hystrix/ok/32
2w个线程压8001
消费者80微服务再去访问的OK服务8001地址
要么转圈圈
要么消费端报超时错误
故障和导致现象
上述结论
正因为有上述故障或不佳表现 才有我们的降级/容错/限流等技术诞生
如何解决?解决的要求
超时导致服务器变慢(转圈)
超时不再等待
出错(宕机或程序运行出错)
出错要有兜底
解决
降级配置
@HystrixCommand
8001先从自身找问题
8001fallback
业务类启用
@HystrixCommand报异常后如何处理
图示
主启动类激活
@EnableCircuitBreaker
80fallback
@EnableHystrix
目前问题
统一和自定义的分开
解决办法
每个方法配置一个???膨胀
feign接口系列
@DefaultProperties(defaultFallback=\"\")
说明
controller配置
和业务逻辑混在一起???混乱
未来我们要面对的异常
宕机
再看我们的业务类PaymentController
修改cloud-consumer-feign-hystrix-order80
PaymentFallbackService类实现PaymentFeginService接口
PaymentFeignClientService接口
单个eureka先启动7001
PaymentHystrixMain8001启动
正常访问测试
故意关闭微服务8001
客户端自己调用提示
断路器
一句话就是家里的保险丝
熔断是什么
大神论文
https://martinfowler.com/bliki/CircuitBreaker.html
实操
修改cloud-provider-hystrix-payment8001
PaymentService
why这些参数
PaymentController
自测cloud-provider-hystrix-payment8001
正确
http://localhost:8001/payment/circuit/31
错误
http://localhost:8001/payment/circuit/-31
一次正确一次错误trytry
重点测试
原理/小总结
大神结论
熔断类型
熔断打开
熔断关闭
熔断关闭后不会对服务进行熔断
熔断半开
官网断路器流程图
官网步骤
断路器在什么情况下开始起作用
断路器开启或者关闭的条件
当满足一定的阈值的时候(默认10秒钟超过20个请求次数)
当失败率达到一定的时候(默认10秒内超过50%的请求次数)
断路器打开之后
ALl配置
后面高级篇讲解alibaba的Sentinel说明
hystrix工作流程
https://github.com/Netflix/Hystrix/wiki/How-it-Works
Hystrix工作流程
官网图例
步骤说明
服务监控hystrixDashboard
仪表盘9001
新建cloud-consumer-hystrix-dashboard9001
HystrixDashboardMain9001+新注解@EnableHystrixDashboard
所有Provider微服务提供类(8001/8002/8003)都需要监控依赖部署
启动cloud-consumer-hystrix-dashboard9001该微服务后续将监控微服务8001
http://localhost:9001/hystrix
断路器演示(服务监控hystrixDashboard)
注意:新版本Hystrix需要在主启动MainAppHystrix8001中指定监控路径
Unable to connect to Command Metric Stream.
404
监控测试
启动一个eureka或者3个eureka集群均可
观察监控窗口
9001监控8001
填写监控地址
http://localhost:8001/hystrix.stream
测试地址
上述测试通过
ok
如何看?
7色
1圈
1线
整图说明
整图说明2
搞懂一个才能看懂复杂的
zuul路由网关
概述描述
路由基本配置
路由访问映射规则
查看路由信息
过滤器
Gateway新一代网关
概述简介
上一代zuul 1.x
https://github.com/Netflix/zuul/wiki
当前gateway
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/
一句话:
源码架构
反向代理
鉴权
流量控制
熔断
日志监控
.....
微服务架构中网关在哪里
有Zuull了怎么又出来gateway
我们为什么选择Gateway?
2.SpringCloud Gateway具有如下特性
3.SpringCloud Gateway与Zuul的区别
Zuul1.x模型
Gateway模型
WebFlux是什么
https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webflux
三大核心概念
Route(路由)
Predicate(断言)
Filter(过滤)
总结
Gateway工作流程
官网总结
核心逻辑
路由转发+执行过滤器链
入门配置
新建Module
cloud-gateway-gateway9527
无
9527网关如何做路由映射呢???
cloud-provider-payment8001看看controller的访问地址
get
lb
YML新增网关配置
启动7001
启动8001
启动9527
访问说明
添加网关前
添加网关后
http://localhost:9527/payment/get/31
YML配置说明
Gateway网关路由有两种配置方式:
在配置文件yaml中配置
见前面的步骤
代码中注入RouteLocator的Bean
官网案例
https://news.baidu.com/guonei
自己写一个
百度新闻
业务需求
通过9527网关访问到外网的百度新闻网址
编码
业务实现
config
通过服务名实现动态
启动:
一个eureka7001+两个服务提供者8001/8002
lb://serverName是spring cloud gatway在微服务中自动为我们创建的负载均衡uri
http://localhost:9527/payment/lb
8001/8002两个端口切换
Predicate
启动我们的gateway9527
Route Predicate Factories这个是什么东东
常用的Route Predicate
1.After Route Predicate
2.Before Route Predicate
3.Between Route Predicate
4.Cookie Route Predicate
不带cookies访问
带上cookies访问
加入curl返回中文乱码
https://blog.csdn.net/leedee/article/details/82685636
5.Header Route Predicate
6.Host Route Predicate
7.Method Route Predicate
8.Path Route Predicate
9.Query Route Predicate
YML
10.RemoteAddr Route Predicate
11.Weight Route Predicate
ALL
Filter的使用
Spring Cloud Gateway的filter
pre
post
GatewayFilter
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gatewayfilter-factories
GlobalFilter
https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#global-filters
常用的GatewayFilter
AddRequestParameter
省略
自定义过滤器
自定义全局GlobalFilter
两个主要接口介绍
全局日志记录
统一网关鉴权
案例代码
启动
http://localhost:9527/payment/lb?uname=z3
SpringCloud config分布式配置中心
分布式系统面临的---配置问题
集中管理配置文件
不同环境不同配置,动态化的配置更新,分环境比如dev/test/prod/beta/release
运行期间动态调整配置,不再需要在每个服务部署的机器上编写配置文件,服务会向配置中心同意拉去配置自己的信息
当配置发生改变时,服务不需要重启即可感知到配置的变化并应用新的配置
将配置信息以REST接口的形式暴露
post/crul访问刷新即可...
与GitHub整合配置
由于SpringCloud Config默认使用GIt来存储配置文件(也有其他方式,比如支持SVN和本地文件),但最推荐还是Git,而且使用的是http/https访问的形式
Config服务端配置与测试
用你自己的账号在GitHub上新建一个名为springcloud-config的心Repository
由上一步获得刚新建的git地址
本地硬盘目录上新建git仓库并clone
此时在本地盘符下的文件
表示多个环境的配置文件
保存格式必须为UTF-8
如果需要修改,此处模拟运维人员操作git和github
git add .
git commit -m \"内容\"
git push origin master
新建Module模块cloud-config-center-3344,它即为Cloud的配置中心模块cloudConfig Center
ConfigCenterMain3344
@EnableConfigServer
windows下修改hosts文件,增加映射
127.0.0.1 config-3344.com
测试通过Config微服务是否可以从GitHub是否可以从GitHub上获取配置内容
启动服务3344
http://config-3344.com:3344/master/config-dev.yml
读取配置规则
/{label}/{application}-{profile}.yml
master分支
dev分支
/{application}-{profile}.yml
/{application}/{profile}/{/label}
重点配置细节总结
成功实现了SpringCloudConfig通过Github获取配置信息
Config客户端配置与测试
新建cloud-config-client-3355
bootstrap.yml
修改config-dev.yml配置并提交到GitHub中,比如加个变量age或者版本号version
成功实现了客户端3355访问SpringCloud Config3344通过GitHub获取信息配置
问题随之而来,分布式配置的动态刷新问题
Linux运维修改GitHub上的配置文件内容做调整
刷新3344,发现ConfigServer配置中心立刻响应
刷新3355,发现ConfigClient客户端没有任何响应
3355没有变化除非自己重启或者重新加载
难道每次运维修改配置文件,客户端都需要重启???噩梦OMG
Config客户端之动态刷新
避免每次更新配置都要重启客户端服务3355
动态刷新
步骤
修改3355模块
POM引入actuator监控
修改YML,暴露监控端口
@refreshScope业务类Controller修改
此时修改github3344---3355
How
需要运维发送Post请求刷新3355
必须是POST请求
curl -X POST \"http://localhost:3355/actuator/refresh\"
再次
成功刷新
想想还有什么问题
假如有多个微服务客户端3355,3366,3377.。。。
每个微服务都要执行一次post请求,手动刷新?
可否广播,一次通知,处处生效
我们想大范围的自动刷新求方法
SpringCloud Bus消息总线
上一讲解的加深和扩充,一言以蔽之
分布式自动刷新配置功能
Spring Cloud Bus配合Spring Cloud Config使用可以实现配置的动态刷新
Bus支持两种消息代理:RabbitMQ和Kafka
为什么被称为总线
RabbitMQ环境配置
安装Elang,下载地址
https://www.erlang.org/downloads
安装RabbitMQ,下载地址
https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.8.3/rabbitmq-server-3.8.3.exe
进入RabbitMQ安装目录下的sbin目录
输入以下命令启动管理功能
rabbitmq-plugins enable rabbitmq_management
可视化插件
访问地址看是否成功安装
http://localhost:15672
输入账号并登录 guest guest
SpringCloud Bus动态刷新全局广播
必须具备良好的RabbitMQ环境
演示广播效果,增加复杂度,再以3355位模板制作一个3366
设计思想
1.利用消息总线触发一个客户端/bus/refresh,从而刷新所有客户端配置
2.利用消息总线触发一个服务端ConfigServer的/bus/refresh端点,从而刷新所有客户端配置
图二的架构显然更加合适,图一不合适原因如下
打破了微服务的职责单一性,因为微服务本身是业务模块,它本不应该承担配置刷新的职责
破坏了微服务各节点的对等性
有一定的局限性,例如,微服务在迁移时,它的网络地址常常会发生变化,此时如果想要做到自动刷新那就会增加更多的修改
给cloud-config-center-3344配置中心服务端添加消息总线支持
给cloud-config-center-3355配置中心服务端添加消息总线支持
给cloud-config-center-3366配置中心服务端添加消息总线支持
运维工程师
修改Github上配置文件增加版本号
发送Post请求
curl -X POST \"http://localhost:3344/actuator/bus-refresh\"
一次发送,处处生效
配置中心
http://lconfig-3344.com:3344/config-dev.yml
客户端
http://localhost:3355/configInfo
http://localhost:3366/configInfo
获取配置信息,发现都已经刷新了
一次修改,广播通知,处处生效
SpringCloud Bus动态刷新定点通知
不想全部通知,只想定点通知
只通知3355
不通知3366
简单一句话
指定某一实例生效而不是全部
公式:http://localhost:3344/actutor/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 Stream消息驱动
消息驱动概述
屏蔽底层消息中间件的差异,降低切换成本,统一消息的编程模型
https://spring.io/projects/spring-cloud-stream
Spring Cloud Stream中文指导手册
https://blog.csdn.net/qq_32734365/article/details/81413218#spring-cloud-stream%E4%B8%AD%E6%96%87%E6%8C%87%E5%AF%BC%E6%89%8B%E5%86%8C
标准MQ
生产者/消费者之间靠消息媒介传递信息内容
Message
消息必须走特定的通道
消息通道MessageChannel
消息通道里的消息如何被消费呢,谁负责收发处理
消息通道MessageChannel的子接口SubscribableChannel,由MessageHandler消息处理器所订阅
为什么使用Cloud Stream
stream凭什么可以统一底层差异
Binder
INPUT对应于消费者
OUTPUT对应于生产者
Stream中的消息通信方式遵循了发布-订阅模式
Topic主题进行广播
在RabbitMQ就是Exchange
在Kafka中就是Topic
Spring Cloud Stream标准流程套路
很方便的连接中间件,屏蔽差异
Channel
通道,是队列Queue的一种抽象,在消息通讯系统中就是实现存储和转发的媒介,通过Channel对队列进行配置
Source和Sink
简单的可以理解为参照对象是Spring Cloud Stream 自身,从Stream发布消息就是输出,接受消息就是输入
编码API和常用注解
案例说明
RabbitMQ环境已经OK
工程中新建三个子模块
cloud-stream-rabbitmq-provider8801 ,作为消息试生产者进行发消息模块
cloud-stream-rabbitmq-consumer8802,作为消息接收模块
cloud-stream-rabbitmq-consumer8803,作为消息接收模块
消息驱动之生产者
略了
消息驱动之消费者
分组消费与持久化
依照8802,clone出来一份8803
RabbitMQ
服务注册
8801
消息生产
8802
消息消费
8803
运行后有两个问题
有重复消费问题
消息持久化问题
消费
目前是8802/8803同时收到了,存在重复消费问题
http://localhost:8801/sendMessage
如何解决
分组和持久化属性group
重要
生产实际案例
分组
微服务应用放置于同一个group中,就能够保证消息只会被其中一个应用消费一次。不同的组是可以消费的,同一个组内会发生竞争关系,只有其中一个可以消费
8802/8803都变成不同组,group两个不同
group:atguiguA,atguiguB
8802修改YML
8803修改YML
我们自己配置
结论
8802/8803实现了轮询分组,每次只有一个消费者,8801模块的发的消息只能被8802或8803其中一个接收到,这样避免了重复消费
8802/8803都变成相同组,group两个相同
group:atguiguA
同一个组的多个微服务实例,每次只会有一个拿到
持久化
通过上述,解决了重复消费问题,再看看持久化
停止8802/8803并去除掉8802分组group:atguiguA
8803的分组group:atguiguA没有去掉
8801先发送4条消息到rabbitmq
先启动8802,无分组属性配置,后台没有打出来消息
再启动8803,无分组属性配置,后台打出来了MQ上的消息
SpringCloud Sleuth分布式链路跟踪
为什么会出现这个技术?需要解决哪些问题?
问题
https://cloud.spring.io/spring-cloud-sleuth/reference/html/
Spring Cloud Sleuth提供了一套完整的服务跟踪的解决方案
在分布式系统中提供追踪解决方案并且兼容支持了zipkin
搭建链路监控步骤
1.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
java -jar zipkin-server-2.12.9-exec.jar
运行控制台
http://localhost:9411/zipkin/
术语
完整的调用链路
上图what
名词解释
Trace:类似于树结构的Span结合,表示一条调用链路,存在唯一标识
span:标识调用链路来源,通俗的理解span就是一次请求信息
2.服务提供者
3.服务消费者
4.依次启动eureka7001/8001/80
80调用8001几次测试下
5.打开浏览器访问http://localhost:9411
会出现以下界面
查看
查看依赖关系
SpringCloud Alibaba入门简介
why会出现SpringCloud alibaba
Spring Cloud Netflix项目进入到维护模式
SpringCloud Netflix Projects Entering Maintenance Mode
什么是维护模式
进入维护模式意味着什么
SpringCloud alibaba带来了什么
去哪下
SpringCloud alibaba学习资料获取
百度啊兄弟们,这部分不整理了
SpringCloud Alibaba Nacos服务注册和配置中心
Nacos简介
为什么叫Nacos
一个更易于构建原生应用的动态服务发现、配置管理和服务管理平台
Nacos:Dynamic Naming and Configuration Service
Nacos就是注册中心+配置中心的组合
等价于
Nacos=Eureka+Config+Bus
替代Eureka做服务注册中心
替代Config做服务配置中心
https://github.com/alibaba/Nacos
官网文档
https://nacos.io/zh-cn/
https://spring-cloud-alibaba-group.github.io/github-pages/greenwich/spring-cloud-alibaba.html#_spring_cloud_alibaba_nacos_discovery
各种注册中心对比
安装并运行Nacos
本地Java8+Maven环境已经ok
先从官网下载Nacos
解压安装包,直接运行bin目录下的startup.cmd
命令运行成功后直接访问http://localhost:8848/nacos
默认用户名密码都是nacos
Nacos作为服务注册中心演示
官方文档
基于Nacos的服务提供者
新建module
为了下一章演示nacos集群,参考9001新建9002
基于Nacos的服务消费者
为什么Nacos支持负载均衡
服务注册中心对比
Nacos全景图所示
Nacos和CAP
切换
Nacos支持AP和CP模式的切换
Nacos作为服务配置中心演示
Nacos作为配置中心-基础配置
cloudalibaba-config-nacos-client3377
why配置两个
bootstrap
application
在Nacos中添加配置信息
Nacos中的匹配规则
理论
Nacos中的dataid的组成格式及与SpringBoot配置文件中的匹配规则
配置新增
Nacos界面配置对应
设置DataId
公式
${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
prefix默认为spring.application.name的值
spring.profile.active即为当前环境对应的profile,可以通过配置项spring.profile.active来配置。
file-exetension为配置内容的数据格式,可以通过配置项speing.cloud.nacos.config.file-extension配置
小总结说明
历史配置
Nacos惠济路配置文件的历史版本默认保留30天,此外还有一件回滚功能
回滚
启动前需要在nacos客户端-配置管理-配置管理栏目下有对应的yaml配置文件
运行cloud-config-nacos-client3377的主启动类
调用接口查看配置信息
http://localhost:3377/config/info
自带动态刷新
修改下Nacos中的yaml配置文件,再次调用查看配置的接口,就会发现配置已经刷新
Nacos作为配置中心-分类配置
多环境多项目管理
Nacos的图形化管理界面
配置管理
命名空间
Namespace+group+data ID三者关系?为什么这么设计?
Case
三种方案加载配置
DataID方案
指定spring.profile.active和配置文件的DataID来使不同环境下读取不同的配置
默认空间+默认分组+新建dev和test两个DataID
新建dev配置DataID
新建test配置DataID
通过spring.profile.acvice属性就能进行多环境下配置文件的读取
配置什么就加在什么
test
Group方案
通过Group实现环境区分
新建Group
在nacos图形界面控制台上新建配置文件DataID
bootstrap+application
在config下增加一条group的配置即可。可配置为DEV_GROUP或TEST_GROUP
Namespace方案
新建dev/test的Namespace
回到服务管理-服务列表查看
按照域名配置填写
Nacos集群和持久化配置(重要)
https://nacos.io/zh-cn/docs
官网架构图
上图翻译
按照上说,我们需要mysql数据库
不找了。。。
Nacos持久化配置解释
Nacos默认自带的是嵌入式数据库derby
derby到mysql切换配置步骤
nacos-server-1.1.4\acos\\conf目录下找到sql脚本
nacos-mysql.sql
执行脚本
nacos-server-1.1.4\acos\\conf目录下找到application.properties
启动Nacos,可以看到是个全新的空记录界面,以前是记录进derby
Linux版Nacos+MySQL生产环境配置
预计需要,1个nginx+3个nacos注册中心,1个mysql
Nacos下载Liunx版
https://github.com/alibaba/nacos/releases
nacos-server-1.1.4.tar.gz
解压后安装
集群配置步骤
1.Linux服务器上mysql数据库配置
SQL脚本在哪里
sql语句源文件
自己LInux机器上Mysql数据库粘贴
2.application.properties配置
位置
内容
3.Linux服务器上nacos的集群配置cluster.conf
梳理出3台nacos机器的不同服务端口号
复制出cluster.conf
这个IP不能写127.0.0.1,必须是Linux命令hostname -i能够识别的IP
/mynacos/nacos/bin 目录下有startup.sh
在什么地方,修改什么,怎么修改
修改内容
执行方式
5.Nginx的配置,由他作为负载均衡器
修改nginx的配置文件
nginx.conf
按照指定启动
6.截至到此为止,1个nginx+3个nacos注册中心+mysql
测试通过nginx访问nacos
http://192.168.111.144:1111/nacos/#/login
新建一个配置测试
linux服务器的mysql插入一条记录
微服务springalibaba-provider-payment9002启动注册进nacos集群
yml
高可用小总结
SpringCloud Alibaba Sentinel实现熔断与限流
Sentiel
https://github.com/alibaba/Sentinel
中文
https://github.com/alibaba/Sentinel/wiki/介绍
一句话解释就是我们之前讲过的hystrix
https://github.com/alibaba/Sentinel/releases
服务中的各种问题
服务雪崩
安装Sentiel控制台
sentinel组件由两部分构成
后台
前台8080
安装步骤
运行命令
前提
java8环境OK
8080端口不能被占用
命令
java -jar sentinel-dashboard-1.7.0.jar
访问sentinel管理界面
http://localhost:8080
登录账号密码均为sentinel
初始化演示功能
启动Nacos8848成功
http://localhost:8848/nacos/#/login
Module
cloudalibaba-sentinel-service8401
业务类FlowLimitController
启动Sentinel8080
启动微服务8401
启动8401微服务后台查看sentinel控制台
空空如也,啥也没有
Sentinel采用懒加载说明
执行一次访问
http://localhost:8401/testA
http://localhost:8401/testB
sentinel8080正在监控微服务8401
流控规则
基本介绍
进一步解释说明
流控模式
直接(默认)
直接-快速失败
系统默认
配置及说明
快速点击访问http://localhost:8401/testA
Blocked by Sentinel(flow limiting)
思考???
直接调用默认报错信息,技术方面ok,but,是否应该有我们自己的后续处理
类似有个fallback的兜底方法
关联
当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流自己
B惹事,A挂了
配置A
postman模拟并发密集访问testB
访问B成功
postman里新建多线程集合组
将访问地址添加进新线程组
RUN
大批量线程高并发访问B,导致A失效了
运行后发现testA挂了
点击访问A
链路
多个请求调用同一个微服务
家庭作业试试
流控效果
直接-快速失败(默认的流控处理)
直接失败,抛出异常
com.alibaba.csp.sentinel.slots.block.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
WarmUp配置
多次点击http://localhost:8401/testB
刚开始不行,后续慢慢OK
应用场景
排队等待
匀速排队,阈值必须设置为QPS
com.ailibaba.csp.sentinel.slots.block.controller.RateLimiterController
降级规则
https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7
进一步说明
Sentinel的断路器是没有半开状态的
半开的状态系统自动去检测是否请求有异常,没有异常就关闭断路器恢复使用,有异常则继续打开断路器不可用,具体参考Hystrix
复习Hystrix
降级策略实战
RT
代码
jmeter压测
异常比例
jmeter
异常数
异常数是按照分钟统计的
同异常比例
热点key限流
https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
承上启下复习start
SentinelResource
com.alibaba.csp.sentinel.slots.block.BlockException
1
@SentinelResource(value = \"testHotKey\")
异常打到了前台用户界面看到,不友好
2
@SentinelResource(value = \"testHotKey\
方法testHotKey里面第一个参数只要QPS超过每秒一次,马上降级处理
用了我们自己定义的
× error
http://localhost:8401/testHotKey?p1=abc
http://localhost:8401/testHotKey?p1=abc&p2=33
√ right
http://localhost:8401/testHotKey?p2=abc
参数例外项
上述案例演示了第一个参数p1,当QPS超过1秒1次点击后马上被限流
特殊情况
普通
超过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
其他
手贱添加异常看看o(╥﹏╥)o
后面讲
系统规则
https://github.com/alibaba/Sentinel/wiki/系统自适应限流
各项配置说明
配置全局QPS
@SentinelResource
按资源名称限流+后续处理
启动nacos成功
启动Sentinel成功
pom
业务类RateLimitController
配置流控规则
配置步骤
图形配置和代码关系
表示1秒钟内查询次数大于1,就跑到我们自定义的限流处,限流
1秒钟点击1下,OK
超过上述,疯狂点击,返回了自己定义的限流处理信息,限流发生
额外问题
此时关闭服务8401看看
Sentinel控制台,流控规则消失了?
临时?持久?
按照Url地址限流+后续处理
通过访问URL来限流,会返回Sentinel自带默认的限流处理信息
访问一次
Sentinel控制台配置
疯狂点击http://localhost:8401/rateLimit/byUrl
上面兜底方案面临的问题
客户自定义限流处理逻辑
创建CustomerBlockHandler类用于自定义限流处理逻辑
自定义限流处理类
CustomerBlockHandler
RateLimitController
启动微服务后再调用一次
http://localhost:8401/rateLimit/customerBlockHandler
测试后我们的自定义出来了
更多注解说明
https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81
多说一句
Sentinel主要有三个核心Api
sphU定义资源
Tracer定义统计
ContextUtil定义了上下文
服务熔断功能
sentinel整合ribbon+openFeign+fallback
Ribbon系列
修改84端口
84消费者调用提供者9003
Feign组件一般是消费测
Feign系列
熔断框架比较
规则持久化
修改cloudalibaba-sentinel-server8401
添加Nacos数据源配置
添加Nacos业务规则配置
内容解析
启动8401刷新sentinel发现业务规则变了
快速访问测试接口
http://localhost:8401/rateLimit/byUrl
停止8401再看sentinel
重新启动8401再看sentinel
多次调用
SpringCloud Alibaba Seata处理分布式事务
分布式事务问题
分布式前
单机库存没这个问题
O(∩_∩)O
从1:1-1:N-N:N
分布式之后
Seata简介
官网地址
http://seata.io/zh-cn/
一个典型的分布式事务过程
分布式事务处理过程-ID+三组件模型
Transaction ID(XID)
全局唯一的事务id
三组件概念
Transaction Coordinator(TC)
Transaction Manager(TM)
Resource Manager(RM)
处理过程
发布说明: https://github.com/seata/seata/releases
本地@Transational
全局@GlobalTranstional
seata的分布式交易解决方案
Seata-Server安装
1.官网地址
https://seata.io/zh-cn/
2.下载版本
3.seata-server-0.9.0.zip解压到指定目录并修改conf目录下的file.conf配置文件
先备份原始file.conf文件
主要修改:自定义事务组名称+事务日志存储模式为db+数据库连接
file.conf
service模块
store模块
4.mysql5.7数据库新建库seata
建表db_store.sql在seata-server-0.9.0\\seata\\conf目录里面
db_store.sql
SQL
5.在seata库里新建表
6.修改seata-server-0.9.0\\seata\\conf目录下的registry.conf目录下的registry.conf配置文件
7.先启动Nacos端口号8848
8.再启动seata-server
seata-server-0.9.0\\seata\\bin
seata-server.bat
订单/库存/账户业务数据库准备
Seata没启动报错no available server to connect
分布式事务业务说明
创建业务数据库
seata_order:存储订单的数据库
seata_storage:存储库存的数据库
seata_account:存储账户信息的数据库
建表SQL
按照上述3库分别建立对应业务表
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
最终效果
订单/库存/账户业务微服务准备
下订单-减库存-扣余额-改(订单)状态
新建订单Order-Module
1.seata-order-service2001
2.POM
3.YML
4.file.conf
拷贝seata-server/conf目录下的file.conf
5.registry.conf
拷贝seata-server/conf目录下的registry.conf
6.domain
CommonResult
Order
7.Dao接口实现
OrderDao
resources文件夹下新建mapper文件夹后添加
OrderMapper.xml
8.Service接口及实现
OrderService
AccountService
StorageService
9.Controller
OrderController
10.Config配置
MyBatisConfig
DataSourceProxyConfig
11.主启动
新建库存Storage-Module
1.seata-storage-service2002
新建账户Account-Module
1.seata-account-service2003
Test
数据库初始情况
正常下单
http://localhost:2001/order/create?userId=1&productId=1&count=10&money=100
数据库情况
AccountServiceImpl添加超时
故障情况
OrderServiceImpl@GlobalTransactional
一部分补充
Seata
2019年1月蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案
再看TC/TM/RM三个组件
分布式事务的执行流程
TM开启分布式事务(TM向TC注册全局事务记录)
AT模式如何做到对业务的无侵入
一阶段加载
二阶段提交
三阶段回滚
debug
大厂面试第三季(预告片)
1.Zookeeper实现过分布式锁吗
2.说说你用redis实现过分布式锁吗?如何实现的?你谈谈
3.集群高并发情况下如何保证分布式唯一全局id生成
为什么需要分布式全局唯一ID以及分布式ID的业务需求
ID生成规则部分硬性要求
1.全局唯一
2.趋势递增
3.单调递增
4.信息安全
5.含时间戳
这样就能在开发中快速了解分布式id的生成时间
ID号生成系统的可用性要求
高可用
低延迟
搞QPS
一般通用方案
UUID
But
入数据库性能查
数据库自增主键
单机
集群分布式
基于redis生成全局id策略
snowflake
Twitter的分布式自增ID算法snowflake
结构
https://github.com/twitter-archive/snowflake
工程落地经验
糊涂工具包
https://github.com/looly/hutool
https://hutool.cn/
springboot整合雪花算法
核心代码IdGeneratorSnowflake
优缺点
其他补充
百度开源的分布式唯一ID生成器UidGenerator
5.抗住了多少QPS?数据流回源会有多少QPS?
0 条评论
回复 删除
下一页