Spring Cloud Alibaba入门到进阶实战课程大纲
2025-02-26 14:32:12 0 举报
AI智能生成
这是我对Spring Cloud Alibaba的理解,分享给大家学习。 更多干货内容,欢迎关注我的公众号:Fox爱分享
作者其他创作
大纲/内容
1.微服务架构的概述
什么是微服务架构
图灵电商项目微服务架构图
为什么要使用微服务架构
好的架构不是设计出来的,而是演进出来的。
服务架构的演进
案例:淘宝架构的演进之路
初始架构:单机架构
第一次演进:Tomcat与数据库分开部署
第二次演进:引入本地缓存和分布式缓存
第三次演进:引入反向代理实现负载均衡
第四次演进:数据库读写分离
第五次演进:数据库按业务分库
第六次演进:把大表拆分为小表
第七次演进:使用LVS或F5来使多个Nginx负载均衡
第八次演进:通过DNS轮询实现机房间的负载均衡
第九次演进:引入NoSQL数据库和搜索引擎等技术
第十次演进:大应用拆分为小应用
第十一次演进:复用的功能抽离成微服务
哪些原因导致系统架构往微服务架构的方向演进
1.业务规模的增长
2.敏捷开发与快速迭代
3.技术储备完善
4.微服务架构生态的完善
微服务架构的优缺点
微服务架构的优点
1.更易于开发和维护
2.快速迭代+灵活
3.系统的伸缩性增强
4.技术选型灵活
5.错误隔离
微服务架构的缺点
1.落地一个微服务架构项目比较复杂
2.服务依赖和调用链路更复杂
3.数据一致性问题
4.问题排查的链路加长
5.学习成本高
什么情况下可以考虑使用微服务架构
已经对当前的系统使用了很多优化手段
微服务架构能够给技术团队和业务扩展带来正向的影响
技术团队的人员齐整、技术支撑足够
2.微服务架构落地方案及常用技术栈选型
Java微服务的落地技术方案选型
Apache Dubbo + Zookeeper/Nacos
适合对性能要求较高的微服务架构
Spring Boot+Spring Cloud + Spring Cloud Alibaba
适合构建在阿里云生态系统中的微服务,以及需要全面治理功能的场景
图灵电商微服务架构图
Java微服务的常用技术栈选型
注册中心
作用
服务的注册与发现
技术栈选型
Spring Cloud Netflix Eureka
Spring Cloud Consul
Spring Cloud Zookeeper
Spring Cloud Alibaba Nacos
服务调用和负载均衡
负载均衡器
作用
技术栈选型
Spring Cloud Netflix Ribbon
Spring Cloud LoadBalancer
服务调用
作用
技术栈选型
Spring Cloud OpenFeign
服务限流熔断降级
作用
技术栈选型
Spring Cloud Netflix Hystrix
Spring Cloud Circuit Breaker
Spring Cloud Alibaba Sentinel
配置中心
作用
技术栈选型
Spring Cloud Config
Spring Cloud Zookeeper
Spring Cloud Alibaba Nacos
微服务网关
作用
技术栈选型
Spring Cloud Netflix Zuul
Spring Cloud Gateway
分布式事务
作用
技术栈选型
Spring Cloud Alibaba Seata
服务链路跟踪
作用
技术栈选型
Spring Cloud Sleuth+Zipkin
Apache Skywalking
服务安全
作用
技术栈选型
Spring Cloud Security
Sa-Token
分布式消息
作用
技术栈选型
Spring Cloud Stream
RabbitMQ
Kafka
RocketMQ
3. 轻松玩转微服务:新手入门Spring Cloud Alibaba
技术版本选型
Spring Boot Version :3.2.4
Spring Cloud Version :2023.0.1
Spring Cloud Alibaba Version : 2023.0.1.0
新手上路:快速搭建你的第一个微服务
发现新大陆:Nacos让服务互相认识
一键调用:OpenFeign简化服务间调用
配置不求人:Nacos配置中心动态管理
事务不头疼:Seata解决分布式事务
流量不再怕:Sentinel限流保护服务
智能门卫:Gateway轻松守护微服务入口
监控可视化:Skywalking实时追踪服务链路
Spring Cloud Alibaba学习项目vip_springcloud_alibaba_2024
课程目标
新手快速入门Spring Cloud Alibaba,轻松玩转微服务
项目介绍
是什么
Spring Cloud Alibaba学习项目,快速入门Spring Cloud&Spring Cloud Alibaba一站式微服务解决方案
技术版本选型(官方推荐版本)
官方推荐
Spring Boot Version :3.2.4
Spring Cloud Version :2023.0.1
Spring Cloud Alibaba Version : 2023.0.1.0
Nacos Version: 2.3.2
Sentinel Version: 1.8.6
Seata Version:2.0.0
低版本的官方推荐
想学习更低版本的同学可以去看我们前两期的为微服务课程
图灵vip6期
Spring Boot Version :3.0.2
Spring Cloud Version :2022.0.0
Spring Cloud Alibaba Version : 2022.0.0.0
图灵vip5期
Spring Boot Version :2.3.12.RELEASE
Spring Cloud Version :Hoxton.SR12
Spring Cloud Alibaba Version :2.2.8.RELEASE
项目代码下载地址
项目结构
tlmall-order : 订单服务
tlmall-storage: 库存服务
tlmall-account: 账户服务
tlmall-gateway: 网关服务
tlmall-frontend: 前端服务,用于测试,可用postman代替
下单业务场景
用户下单购买货物的场景,下单后:
1. 先请求库存模块,扣减库存;
2.扣减账户余额;
3.生成订单信息返回响应。
1. 先请求库存模块,扣减库存;
2.扣减账户余额;
3.生成订单信息返回响应。
怎么学
小白直接跟着老师的课程安排学习。
课程安排
新手上路:快速搭建你的第一个微服务
发现新大陆:Nacos让服务互相认识
一键调用:OpenFeign简化服务间调用
配置不求人:Nacos配置中心动态管理
事务不头疼:Seata解决分布式事务
流量不再怕:Sentinel限流保护服务
智能门卫:Gateway轻松守护微服务入口
监控可视化:Skywalking实时追踪服务链路
赶时间,想快速部署体验的同学,可以直接跳到最后的项目快速部署,作为微服务深入学习的Demo
前期准备工作
需要的基础知识
会使用Spring Boot实现一个接口
会使用Mybatis操作mysql数据库
会使用git拉取代码
项目搭建环境要求
jdk 21
maven 3.9.5
配置阿里云maven镜像仓库
idea 2023.3.2
新手上路:快速搭建你的第一个微服务
速通版
1. git clone 拉取项目代码,导入idea中
2. git checkout v1.0.1
项目结构包含四个服务
tlmall-order : 订单服务
tlmall-storage: 库存服务
tlmall-account: 账户服务
tlmall-frontend: 前端服务,用于测试,可用postman代替
重点
实现的需求:用户下单扣减库存,扣减账户余额
如何引入Spring Cloud Alibaba的依赖?
父工程Pom文件内容
<dependencyManagement>和<dependency>的区别
环境准备
在启动服务前,请先配置 Host 地址映射,确保服务能够正常启动
需要导入Mysql数据库脚本文件,路径spring-cloud-alibaba-examples/config/sql/init.sql
可能遇到的问题
利用revision统一子工程的版本号,maven打包时提示{project_namme}:{revision} cannot be find
项目演示
启动所有微服务,测试
查询库存: localhost:8010/storage/?commodityCode=1
查询余额:localhost:8020/account/?userId=fox
下单: http://localhost:8080/order (此处时利用前端服务tlmall-frontend下单,也可用postman调用订单接口测试)
查询订单:localhost:8030/order/getOrder?userId=fox
发现问题
用户正常下单,没有扣减库存,没有扣减账户余额
新的需求
微服务间需要实现服务间的调用,比如订单微服务8030如何调到库存微服务8010,如何实现?
解决方案
利用Spring框架提供的RestTemplate实现服务间的调用
1)@Bean的方式配置RestTemplate
2)订单服务的OrderServiceImpl中引入RestTemplate
3)通过restTemplate.postForObject方法调用库存服务和账户服务
发现问题
//RestTemplate远程调用
String storage_url = "http://localhost:8010/storage/reduce-stock";
Integer storageCode = restTemplate.postForObject(storage_url,storageDTO, Result.class).getCode();
String storage_url = "http://localhost:8010/storage/reduce-stock";
Integer storageCode = restTemplate.postForObject(storage_url,storageDTO, Result.class).getCode();
微服务所在的IP地址和端口号硬编码写死了,如果库存服务(服务提供者)IP和端口发生变化,或者新增多个库存服务如何调用
新的需求
需要实现服务发现的功能,比如订单服务调用前能够获取到最新的库存服务列表
解决方案
可以引入注册中心Nacos,实现服务的注册与发现,比如将库存服务注册到Nacos, 订单服务调用之前从Nacos获取到库存服务的列表
发现新大陆:Nacos让服务互相认识
作用
服务的注册与发现
为什么要引入注册中心
Nacos是什么
官方文档
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称
一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台
简单理解就是注册中心+配置中心
Nacos下载安装
注意版本
Nacos Version: 2.3.2
官网下载安装包
历史安装包地址
https://download.nacos.io/nacos-server/nacos-server-2.3.2.zip
解压后进入bin目录
官方安装文档
windows单机模式运行
startup.cmd -m standalone
运行成功后直接访问http://localhost:8848/nacos,默认账户密码都是nacos
微服务整合Nacos注册中心
官方参考文档
整合Nacos的服务提供者(库存服务)
服务注册
服务提供者可以通过 Nacos 的服务注册功能将其服务注册到 Nacos server 上。
1)引入依赖
库存服务的pom.xml中添加nacos-discovery 注册中心依赖
2)库存服务的application.yml中配置Nacos注册中心地址
3) 在启动类上使用 @EnableDiscoveryClient 注解开启服务注册与发现功能
这一步可忽略,因为nacos-discovery实现了服务自动注册
重新启动库存服务,然后去nacos控制台查看库存服务是否成功注册
同理,账户服务配置同上
整合Nacos的服务调用(消费)者 (订单服务)
服务注册
订单服务也需要注册到Nacos,配置同上
服务发现
服务调用者可以通过 Nacos 的服务发现功能从 Nacos server 上获取到它要调用的服务。
发现问题
订单服务作为服务调用者,需要获取库存服务列表然后选择一个库存服务节点发起调用,那应该调用哪一个库存服务?
新的需求
如何实现选择一个库存服务节点发起调用?
解决方案
RestTemplate+LoadBalancer 实现服务调用
什么是LoadBalancer
官方文档
Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器
订单服务利用负载均衡器LoadBalancer,从库存服务列表中选择一个节点,再通过RestTemplate实现库存服务调用
怎么用
1) 订单服务的pom.xml 中添加LoadBalancer的依赖
2) 订单服务的application.yml中添加配置spring.cloud.loadbalancer.nacos.enabled=true
3)RestTemplate通过添加 @LoadBlanced 注解接入LoadBalancer
4)订单服务调用逻辑中,RestTemplate远程调用String storage_url = "http://localhost:8010/storage/reduce-stock"可以改为String storage_url = "http://tlmall-storage/storage/reduce-stock"。使用微服务名tlmall-storage代替localhost:8010
重启所有服务,测试
Nacos控制台查看服务是否注册成功
下单:http://localhost:8080/order
查看是否成功扣减库存
借助idea工具,增加一个库存服务8011,再次下单,查看当有2个库存服务的时候,能否调到8011的库存服务
关于Nacos注册中心更多的配置使用,会在Nacos注册中心实战课程中进行详解
小结
通过Nacos注册中心可以实现微服务的注册与发现
思考:RestTemplate+LoadBalancer这种方式进行微服务调用存在什么问题?
发现问题
代码可读性差,编程体验不统一
参数复杂时URL难以维护
新的需求
是否有比RestTemplate+LoadBalancer更方便好用的服务调用组件?
解决方案
可以选择OpenFeign简化服务调用
一键调用:OpenFeign简化服务间调用
作用
服务间的远程调用,比如通过OpenFeign可以实现订单服务调用远程的库存服务
已经有了LoadBalancer为什么还要用openFeign
是什么
官方文档
OpenFeign是Spring Cloud框架中集成的声明式HTTP客户端工具
OpenFeign可以让远程调用服务达到像本地调用方法一样的体验。
怎么用
OpenFeign在服务消费端使用,比如订单服务使用OpenFeign调用库存服务和账户服务
1)引入依赖
订单服务的pom.xml中引入OpenFeign的依赖
2) 在订单服务启动类上添加@EnableFeignClients注解,开启openFeign功能
3) 编写OpenFeign客户端,调用库存微服务和账户微服务
4)订单服务发起调用,像调用本地方式一样远程调用库存服务和账户服务
重启订单服务,测试
Nacos控制台查看服务是否注册成功
下单:http://localhost:8080/order
查看是否成功扣减库存
借助idea工具,增加一个库存服务8011,再次下单,查看当有2个库存服务的时候,能否调到8011的库存服务
关于OpenFeign更多的配置使用和扩展,会在OpenFeign实战课程中进行详解
小结
通过OpenFeign可以实现微服务之间的远程调用
配置不求人:Nacos配置中心动态管理
作用
配置中心就是一种统一管理各种应用配置的基础服务组件。
微服务为什么需要配置中心
一个微服务一个application.yml,100个微服务100个application.yml,如果注册中心地址变了,想象一下怎么改配置
配置中心使得配置信息集中管理,易于维护,并且可以动态更新配置
怎么用
官方参考文档
配置中心这块官方文档太乱了(github,官网文档不同步,不更新),跟着老师的思路来配置
Nacos配置中心配置方式的变化
在SpringBoot2.4这个大版本中有一项非常重要的改动:出于对云原生多配置文件的支持,默认关闭了对bootstrap.yml的使用。
解决方案
方案1: 重新启用bootstrap.yml(不推荐)
方案2: 使用spring.config.import(官方推荐)
订单服务整合Nacos配置中心
目标: 把微服务中公共的配置配置统一管理,比如订单服务的注册中心配置和数据库公共配置可以抽取出来
1) 在Nacos控制台创建dataId(对应spring.config.import指定的配置文件名)
抽取application.yml中配置信息配置到Nacos指定的dataId文件中
公共配置
nacos-discovery.yml
db-common.yml
订单服务自己的配置
tlmall-order.yml
同时注释掉application.yml对应的配置
2)引入依赖
订单服务的pom.xml中引入nacos-config依赖
3) 在订单服务的application.yml 配置文件中配置 Nacos Config 地址并引入服务配置
使用spring.config.import(官方推荐)
指定的配置文件对应Nacos配置中心配置的dataId
重启订单服务,测试
可以先在application.yml中增加nacos日志打印配置,便于查看从配置中心拉取配置的情况
查看订单服务是否启动成功,并成功注册到Nacos注册中心
如果没有拉取到数据库配置是会报错的
下单:http://localhost:8080/order
查看是否成功扣减库存
同上步骤,库存服务和账户服务整合Nacos配置中心
相关资料
所有配置文件在spring-cloud-alibaba-examples/config/nacos-config/nacos_config_export_v1.0.5.zip包下,在Nacos配置中心中直接导入配置即可
关于Nacos配置中心更多的配置使用,会在Nacos配置中心实战课程中进行详解
小结
通过Nacos配置中心可以实现微服务配置的统一管理
事务不头疼:Seata解决分布式事务
为什么要使用分布式事务
问题重现
当账户余额会0时,还是可以下单成功,而且扣减库存
新的需求
下单逻辑需要保证数据一致性,当账户余额不够时,库存回滚,下单失败
解决方案
思考:使用spring事务能解决问题吗?
不能
使用分布式事务解决方案Seata (官方推荐)
Seata是什么
官方文档
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。
首选Seata AT 模式(官方推荐),可以做到业务无侵入
Seata AT模式的工作流程
非常重要的三个概念(要理解)
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
比如,当前订单服务下单,调用库存服务扣减库存,调用账户服务扣减账户余额
订单服务要接入TM组件
下单操作需要开启全局事务(向TC申请一个全局事务XID),进入下单逻辑
如果下单正常,需要通知TC提交全局事务
如果下单异常,比如余额不够,需要通知TC回滚全局事务
订单服务,库存服务,账户服务都要接入RM组件
提交本地事务的同时,需要向TC注册分支事务信息
接收TC的通知,提交或回滚分支事务
TC是独立的服务
维护TM申请的全局事务信息和 RM提交的分支事务信息
TM通知TC全局事务提交或者回滚的时候,TM要通知RM分支事务提交或回滚
AT模式工作流程
问题:如何知道调用的是同一个分布式事务?
开启全局事务会分配一个全局事务XID,微服务链路会传递XID,注册每个分支事务都会带上XID
Seata Server(TC)安装部署
注意版本
Seata Version:2.0.0
下载地址
https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.zip
官网参考资料
Seata新手部署指南
seata 参数配置官网参考
TC端存储模式
全局事务分支事务信息存储到哪儿?
Seata1.x 支持的模式
file:单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高,但是只支持单机模式部署,生产环境不考虑。
db:高可用模式,全局事务会话信息通过db共享,相应性能差些
redis:1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置
Seata2.x新增的Raft模式
利用Raft算法实现多个TC之间数据的同步。
raft模式是最理想的方案,但是当前并不成熟,所以不用考虑。
从稳定性角度考虑,最终选择采用db模式
创建seata数据库,sql脚本在seata-server-2.0.0\seata\script\server\db\mysql.sql
思考:RM和TM如何找到TC服务
可以将TC服务注册到Nacos,RM和TC通过Nacos注册中心实现TC服务的发现
注意:Seata的注册中心是作用于Seata自身的,和微服务自身配置的注册中心无关,但可以共用注册中心。
可以创建一个seata的命名空间,区分seata的TC服务和业务微服务
思考:TC的配置是不是也可以交个Nacos配置中心管理?
最终方案:db存储模式+Nacos(注册&配置中心)方式部署
前置环境准备
1.db模式准备好seata的数据库
2.准备好Nacos环境
配置Nacos注册中心
配置将Seata Server注册到Nacos,修改conf/application.yml文件
注意
这个cluster配置,默认TC是default集群,TM和RM要通过这个集群名找TC集群
请确保client(RM TM)与server(TC)的注册处于同一个namespace和group,不然会找不到server服务。
配置Nacos配置中心
1)配置Nacos配置中心地址,修改conf/application.yml文件
2)将seata server的配置上传配置至Nacos配置中心
a) 获取/seata/script/config-center/config.txt,修改为db存储模式,并修改mysql连接配置
TC如何使用mysql8?
b) 配置事务分组, TC要与client(RM TM)配置的事务分组一致
事务分组如何找到后端Seata集群?
c) 在nacos配置中心中新建dataId为seataServer.properties的配置,配置内容为上面修改后的config.txt中的配置信息
注意
是在seata命名空间下新建seataServer.properties,要和conf/application.yml中的config配置对应上
特别注意seataServer.properties是否是SEATA_GROUP
启动Seata Server
windows点击bin目录下seata-server.bat直接启动
启动成功,查看控制台http://127.0.0.1:7091,账号密码都是seata。
在Nacos注册中心中可以查看到seata-server注册成功
微服务整合Seata AT模式实战
业务场景
用户下单,订单服务调用库存服务扣减库存,调用账户服务扣减账户余额
事务发起者:订单服务
事务参与者:库存服务,账户服务
订单服务(事务发起者)整合Seata
1)引入seata的依赖
2) 订单服务对应数据库中添加undo_log表(仅AT模式)
3)订单服务application.yml中添加seata配置
需要在nacos的控制台中创建一个seata的命名空间,用于和业务微服务隔离
注意:请确保client与server的注册中心和配置中心namespace和group一致
优化:可以将seata配置移到配置中心中
4)订单服务作为全局事务发起者,在下单方法上添加@GlobalTransactional注解
库存服务(事务参与者)整合Seata
和整合订单服务前三步一样
4)库存服务只需要在扣减库存方法上添加Spring事务@Transactional注解
账户服务(事务参与者)整合Seata
配置同库存服务一样
Seata2.x常见问题
微服务启动报错:io.seata.config.exception.ConfigNotFoundException: service.vgroupMapping.default_tx_group configuration item is required
产生的原因&解决思路
原因:无法拉取到service.vgroupMapping.default_tx_group=default这个配置,也就找不到集群名为default的seata server服务
思路1:检查下微服务端seata配置是否未配置事务分组seata.tx-service-group=default_tx_group
思路2:检查下namespace和group配置server端和client端是否对应,特别注意seataServer.properties是否是SEATA_GROUP
seata的配置文件seataServer.properties
seata server报错:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
产生的原因&解决思路
原因:无法连上数据库
思路:检查下seataServer.properties中jdbc配置是否正确,检查jdbc版本和mysql版本是否匹配
重启所有服务,测试分布式事务是否生效
下单:http://localhost:8080/order
分布式事务成功场景,模拟正常下单、扣库存,扣余额
分布式事务失败场景,模拟下单扣库存成功、扣余额失败,事务是否回滚
有个问题:seata2.0.0 版本的bug,还是版本不兼容引起的
事务发生回滚,回滚成功了,但是最外层代码无法捕捉到原始的BusinessException异常,只能捕捉到RuntimeException运行时异常
原因分析
建议:不要在生产上用最新版本Seata2.0.0,坑有点多
关于Seata更多的配置使用,会在Seata实战课程中进行详解
小结
通过Seata可以解决微服务分布式事务的问题
流量不再怕:Sentinel限流保护服务
微服务架构为什么要使用流控降级组件
为了提高系统运行期间的稳定性和可用性
需求:对下单接口进行流控
sentinel是什么
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
官方文档
sentinel的安装
官方参考文档
sentinel由两部分构成
核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。
安装Sentinel控制台
注意版本
Sentinel Version: 1.8.6
官方文档地址
下载地址
https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
启动sentinel控制台
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=tlmall-sentinel-dashboard:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=tlmall-sentinel-dashboard:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
如若8080端口冲突,可使用 -Dserver.port=新端口 进行设置。
访问sentinel控制台
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel
访问:http://localhost:8888
sentinel整合微服务
官方参考文档
以订单服务为例
1)引入sentinel的依赖
2)业务代码中配置需要保护的资源
mvc接口方法自动埋点,不需要配置
非mvc接口方法可以使用@SentinelResource 注解用来标识资源是否被限流、降级
对下单接口进行流控,此处不需要处理
3)添加yml配置,为订单服务设置sentinel控制台地址
此配置可以移到配置中心,新增一个sentinel-dashboard.yml的配置
测试,重启订单服务,对用户下单进行流控
启动sentinel控制台,在sentinel控制台中设置流控规则
注意:需要先访问一次下单接口,sentinel控制台才会有订单服务记录
将单机阈值调为1,用postman测试下单接口,是否被流控
sentinel更多的实战操作,比如各种规则配置,整合loadbalancer,openFeign,规则持久化等,都会在sentinel实战课中讲解
小结
通过sentinel可以实现微服务的流控降级
智能门卫:Gateway轻松守护微服务入口
微服务为什么需要API网关
在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢?
如果根据每个微服务的地址发起调用,存在如下问题:
为了解决上面的问题,微服务引入了 API网关 的概念
Spring Cloud Gateway是什么
官方文档
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
微服务快速接入Spring Cloud Gateway
构建网关服务
创建一个新的module模块tlmall-gateway
pom.xml中引入Spring Cloud Gateway网关依赖
注意:gateway会和spring-webmvc的依赖冲突,需要排除spring-webmvc
微服务快速接入网关服务
以订单服务为例,在网关服务的application.yml
库存服务,账户服务同上
网关服务的完整的application.yml配置如下
此配置可以移到配置中心,新增一个tlmall-gateway.yml的配置
测试,启动网关服务
postman中通过网关服务的18888端口下单,看能否成功
tlmall-frontend前端服务order.html中访问地址都替换为tlmall-gateway:18888,测试下单是否成功
关于Spring Cloud Gateway更多的操作,会在Spring Cloud Gateway实战课程中讲解
小结
gateway就是整个微服务架构的流量入口
监控可视化:Skywalking实时追踪服务链路
全链路追踪的作用
对请求源头到底层服务的调用链路中间的所有环节进行监控。
skywalking是什么
官方网站
skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。
SkyWalking 是观察性分析平台和应用性能管理系统,提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
Skywalking整体架构
SkyWalking 环境搭建部署
下载 SkyWalking
apache-skywalking-apm-10.0.1.tar.gz
https://www.apache.org/dyn/closer.cgi/skywalking/10.0.1/apache-skywalking-apm-10.0.1.tar.gz
skywalking的后端服务OAP+可视化UI
apache-skywalking-java-agent-9.3.0.tgz
https://www.apache.org/dyn/closer.cgi/skywalking/java-agent/9.3.0/apache-skywalking-java-agent-9.3.0.tgz
用于从微服务采集数据的探针
搭建SkyWalking OAP 服务
1)修改配置
先使用默认的H2数据库存储,不用修改config/application.yml配置
skywalking-web-ui服务会占用 8080 端口, 修改端口可以修改webapp/webapp.yml
2)windows下启动脚本bin/startup.bat
启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui
访问UI界面,如果端口改为了18080,访问:http://localhost:18080/
微服务接入Skywalking agent探针
微服务配置jvm参数,接入skywalking
以订单服务为例,idea启动配置中配置skywalking agent
账户服务,库存服务同上
测试,用户下单,在skywalking UI界面查看是否有链路数据
常见问题: 没有查看到网关服务的数据
需要将agent包下的optional-plugins/apm-spring-cloud-gateway-4.x-plugin-9.3.0.jar 拷贝到plugins下
关于Skywalking更多的操作,会在Skywalking实战课程中讲解
小结
通过Skywalking可以实现微服务调用链路追踪
项目快速部署
小白不要直接跳过这节,跟着老师的课程安排的步骤学习
赶时间,只想快速部署跑起来体验的同学,可以参考这节快速部署体验
具体步骤
1.部署前准备
在启动服务前,请先配置 Host 地址映射,确保服务能够正常启动
不配置也可以,都用localhost或者ip
拉取代码
git clone git@gitee.com:dongchenglin/vip_springcloud_alibaba_2024.git
2.服务本地化部署
2.1 微服务环境准备
Nacos
Seata Server
Sentinel 控制台
Skywalking服务端
这些组件都要启动,参考前面每个组件的部署篇
2.2 导入项目数据库
需要导入Mysql数据库脚本文件,路径spring-cloud-alibaba-examples/config/sql/init.sql
2.3 导入微服务配置到Nacos配置中心
在public命名空间下,导入微服务的配置
路径:spring-cloud-alibaba-examples/config/nacos-config/nacos_config_export_v1.0.8.zip
2.4 启动所有微服务
3. 测试,下单接口: http://localhost:8080/order
4. 微服务高手之路:Spring Cloud Alibaba核心组件深度实战
Nacos注册中心实战
课程目标
了解注册中心的设计思路,理解注册中心的核心功能需求
掌握Nacos注册中心使用,能够灵活运用Nacos
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
用过Nacos但了解不深的同学可以直接学这节课
想学Nacos源码的同学可以看Nacos源码剖析课
课上代码
项目地址
git切换到nacos-teach分支,选择 tag v2.0.0
注册中心的设计思路
面试夺命连环三问
1)微服务为什么会用到注册中心?
2)如何设计一个注册中心?
3)注册中心应该包含哪些常见功能?
服务注册、服务发现和服务的健康检查机制。
注册中心的设计思路
Nacos基础回顾
发现新大陆:Nacos让服务互相认识
Nacos注册中心的架构
Nacos注册中心核心概念和功能
核心概念
服务 (Service)
元数据 (Service Metadata)
服务注册中心 (Service Registry)
命名空间(Namespace)
服务分组(Group)
核心功能
服务注册
服务心跳
服务同步
服务发现
服务健康检查
微服务整合Nacos注册中心常用配置项详解
准备测试环境
会员服务tlmall-user, 订单服务tlmall-order01
速通版
项目地址
可以切换到nacos-teach分支tag v2.0.0获取代码
会员调用获取订单接口,获取订单信息
服务逻辑隔离配置
数据模型
Namespace 隔离设计
1)在nacos控制台创建一个fox的命名空间
2)订单服务配置namespace为fox
重启订单服务,测试: 用户调用订单接口能否查询到订单信息
无法调通订单服务,提示:No instances available for tlmall-order01
原因:tlmall-order01和tlmall-user使用了不同的namespace,导致服务隔离,tlmall-user无法发现可用的tlmall-order01服务。
group服务分组
课后作业:验证group是否也可以实现隔离
服务领域模型
集群配置
测试,不同的集群的微服务之间是否能够调用
临时实例和持久化实例
健康检查的方式
临时实例使用客户端上报模式,需要能够自动摘除不健康实例,而且无需持久化存储实例。
持久化实例使用服务端探测的健康检查方式,因为客户端不会上报心跳, 所以不能自动摘除下线的实例。
适用场景
上层的业务微服务,例如订单微服务,库存微服务都可以上报心跳,都是临时实例
⼀些基础的组件例如数据库、缓存等,这些往往不能上报心跳,这种类型的服务在注册时,就需要作为持久化实例注册。
如何配置
Nacos默认注册的都是临时实例
常见错误
Current service DEFAULT_GROUP@@tlmall-order01 is ephemeral service, can't register persistent instance.
在 Nacos2.0 中将是否持久化的数据抽象至服务级别, 且不再允许⼀个服务同时存在持久化实例和非持久化实例,实例的持久化属性继承自服务的持久化属性。
The Raft Group [naming_persistent_service_v2] did not find the Leader node
要配置持久实例必须得是nacos集群模式
Nacos安全配置
Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险。
官方参考文档
怎么做
nacos server端
conf/application.properties添加如下配置
随机字符串生成工具:
注意:鉴权开关是修改之后立马生效的,不需要重启服务端。
nacos client端
nacos sever开启鉴权后,微服务会提示 user not found!
微服务的application.yml中添加如下配置
默认用户名密码都是nacos,可以在nacos控制台创建新用户
重启微服务,测试是否成功注册到nacos
Nacos高可用集群最佳实践
nacos部署方式
单机模式 - 用于测试和单机试用。
集群模式 - 用于生产环境,确保高可用。
官方文档
集群部署架构图
最终方案:nginx+三节点nacos集群+mysql
为了保证数据一致性,集群环境需要用mysql(三节点都可以访问到mysql)替换内嵌的derby数据库。
搭建步骤
1)前期环境准备
三台linux虚拟机
安装好 JDK,需要 1.8 及其以上版本
注意: nacos2.3.2不能使用OpenJDK
Nacos 2.3.2 开启鉴权后控制台无论使用什么密码登录都显示账户密码错误
Centos7自带的OpenJDK和安装JDK1.8图文教程
建议: 2核 CPU / 4G 内存 及其以上
准备好nacos2.3.2的安装包
2)配置集群配置文件
注意:不要使用localhost或127.0.0.1,针对多网卡环境,nacos可以指定网卡或ip
3)开启默认鉴权插件
修改conf目录下的application.properties文件
4)配置数据源
使用外置mysql数据源,生产使用建议至少主备模式
4.1)初始化 MySQL 数据库
sql脚本
4.2)修改application.properties配置
常见错误
Nacos Server did not start because dumpservice bean construction failure :
No DataSource set
No DataSource set
检查nacos的mysql连接,数据库的ip、数据库、用户名和密码
5) 分别启动三个nacos节点
以192.168.65.207为例,进入nacos目录,启动nacos
6) 访问nacos管理界面
登录http://192.168.65.207:8848/nacos,用户名和密码都是nacos
nacos2.3.2的bug
注意: nacos2.3.2不能使用OpenJDK
Nacos 2.3.2 开启鉴权后控制台无论使用什么密码登录都显示账户密码错误
7) 微服务访问nacos,在yml中配置
Nginx配置负载均衡
注意
使用nginx请求时,需要配置成TCP转发,不能配置http2转发,否则连接会被nginx断开。 9849和7848端口为服务端之间的通信端口,请勿暴露到外部网络环境和客户端测。
搭建步骤
1)准备nginx环境
1.1 )如果安装了nginx,先检查nginx是否有stream模块,输出中包含:--with-stream
1.2) 安装nginx
如果提示依赖包下载失败,更换镜像源
2)配置http模块
在nginx的http下面配置http协议相关的地址和端口
3)配置grpc
需要nginx有stream模块支持
4) 启动nginx,然后就可以正常使用了。
5) 微服务访问nacos,yml中配置
负载均衡器LoadBalancer实战
课程目标
掌握LoadBalancer的使用,能根据业务需求扩展负载均衡算法
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
先学nacos注册中心,再学LoadBalancer
课上代码
项目地址
git切换到nacos-teach分支,选择 tag v2.1.0
LoadBalancer基础回顾
是什么
官方文档
Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。
作用
从注册中心拉取库存服务列表,让订单服务根据负载均衡算法(比如轮询)调用某个库存服务
怎么用
1) 订单服务的pom.xml 中添加LoadBalancer的依赖
2) 订单服务的application.yml中添加配置spring.cloud.loadbalancer.nacos.enabled=true
作用:选择基于nacos本地集群优先的负载均衡策略
3)RestTemplate通过添加 @LoadBlanced 注解接入LoadBalancer
4)订单服务调用逻辑中,RestTemplate远程调用String storage_url = "http://localhost:8010/storage/reduce-stock"可以改为String storage_url = "http://tlmall-storage/storage/reduce-stock"。使用微服务名tlmall-storage代替localhost:8010
LoadBalancer生产最佳实践
负载均衡策略配置
内置的负载均衡策略
轮询(默认)
随机
NacosLoadBalancer
本地集群优先的原则,会先根据cluster配置优先选择本地集群,再根据权重选择具体的实例
注意:如果配置了spring.cloud.loadbalancer.nacos.enabled=true,会选择NacosLoadBalancer负载均衡算法
测试:可以启动两个订单服务,会员服务发起调用
1)将spring.cloud.loadbalancer.nacos.enabled=false,测试是否有轮询效果
2)将spring.cloud.loadbalancer.nacos.enabled=true,配置cluster,测试本地集群优先是否生效
如何修改负载均衡策略为随机策略
注意,需要先将spring.cloud.loadbalancer.nacos.enabled=false
1)通过@Bean的方式配置随机的负载均衡策略,可以参考轮询策略的@Bean实现
2)配置随机策略生效方式
方式1:全局生效,所有调用的接口都生效 (配置在服务启动类上)
方式2:局部生效,只对调用的接口生效 (配置在openFeign的接口上)
同上,同样的方式也可以配置其他的内置负载均衡策略
自定义负载均衡策略
需求: 实现基于ip hash的负载均衡策略
1)实现ip hash策略的负载均衡器MyCustomLoadBalancer,可以参考RandomLoadBalancer实现
2) 通过@Bean的方式配置ip hash的负载均衡策略
3) 配置ip hash策略生效
测试: 会员服务调用订单服务,是否走了自定义的ip hash策略
RestTemplate+@LoadBalanced注解使用不当导致的bug及其解决方案
问题重现
某些特殊场景,微服务启动期间需要从其他微服务获取一些初始化的数据,很多同学会选择在Bean的初始化方法中去调用其他的微服务获取数据
注意:在微服务架构中,通常推荐在服务启动后的业务逻辑中调用其他服务,而不是在Bean的初始化方法中进行。这是因为Bean的初始化阶段可能发生在服务完全就绪之前,此时调用其他服务可能会遇到各种问题,如服务尚未注册、网络未就绪等。
演示: 在会员服务的Controller的初始化方法中调用订单服务,会出现什么问题?
1)UserController实现InitializingBean接口
2)启动会员服务,会启动失败,找不到要调用的微服务名
原因分析
业务Bean初始化期间使用@LoadBalanced修饰的RestTemplate,还没有负载均衡器的能力,简单点理解就是:此时,负载均衡器的功能还没生效,不能去调用其他微服务
问题的关键就在于 @LoadBalanced修饰的RestTemplate 是什么时候具有负载均衡能力的
深入分析
@LoadBalanced 注解原理
参考源码:LoadBalancerAutoConfiguration
1.@LoadBalanced利用@Qualifier作为restTemplates注入的筛选条件,筛选出具有负载均衡标识的RestTemplate。
2.被@LoadBalanced注解的restTemplate会被定制,添加LoadBalancerInterceptor拦截器(拦截器中实现了负载均衡的逻辑)。
发现问题的关键
LoadBalancerInterceptor拦截器是利用SmartInitializingSingleton注入的
SmartInitializingSingleton是在所有的bean都实例化完成之后才会调用的,所以在bean的实例化期间使用@LoadBalanced修饰的restTemplate是不具备负载均衡作用的。
参考源码:DefaultListableBeanFactory#preInstantiateSingletons
解决思路
思路1
在服务启动后的业务逻辑中调用其他服务,而不是在Bean的初始化方法中进行。
思路2
如果不使用@LoadBalanced注解,也可以通过添加LoadBalancerInterceptor拦截器让RestTemplate起到负载均衡器的作用。
服务调用组件OpenFeign实战
课程目标
掌握OpenFeign的使用和扩展配置,能根据业务需求扩展配置OpenFeign
理解OpenFeign的调用流程
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
学习顺序:Nacos注册中心——>LoadBalancer——>OpenFeign
课上代码
项目地址
git切换到nacos-teach分支,选择 tag v2.2.1 (完整版)
基础回顾
为什么要使用OpenFeign
LoadBalancer+RestTemplate进行微服务调用存在缺陷
代码可读性差,编程体验不统一
参数复杂时URL难以维护
是什么
官方文档
OpenFeign是Spring Cloud框架中集成的声明式HTTP客户端工具
OpenFeign可以让远程调用服务达到像本地调用方法一样的体验。
怎么用
以会员服务调用订单服务为例
课堂演示代码:git切换到nacos-teach分支,选择 tag v2.2.0
1)引入依赖
会员服务(服务调用者)引入OpenFeign依赖
注意:需要引入loadbalancer依赖
2)在启动类上添加@EnableFeignClients注解,开启openFeign功能
3)编写OpenFeign客户端,配置订单服务(服务提供者)接口
4)会员服务发起调用,像调用本地方式一样调用订单服务
openFeign接口方法编写规范
在编写OpenFeign接口方法时,需要遵循以下规范
1.接口中的方法必须使用@RequestMapping、@GetMapping、@PostMapping等注解来声明HTTP请求的类型。
2.方法的参数可以使用@RequestParam、@RequestHeader、@PathVariable等注解来指定如何传递HTTP请求的参数。
3.可以使用@RequestBody来指定如何传递请求体中的参数。
4.可以使用@HeaderMap来传递头部信息。
案例演示
GET请求
GET请求,参数全放URL中,不建议放BODY,部分浏览器可能会限制不读取body中的数据;
GET请求参数过长的话,也会有问题,适用于参数不长的场景;
GET请求参数过长的话,也会有问题,适用于参数不长的场景;
目标接口方法
OpenFeign接口方法
post请求
@RequestBody
目标接口方法
OpenFeign接口方法
url后面追加参数
目标接口方法
OpenFeign接口方法
url中加参数
目标接口方法
OpenFeign接口方法
openFeign的调用流程
openFeign常用扩展点配置实战
openFeign 提供了很多的扩展机制,让用户可以更加灵活的使用。
测试环境
会员服务调用订单服务
日志配置
有时候我们遇到 Bug,比如接口调用失败、参数没收到等问题,或者想看看调用性能,就需要配置 Feign 的日志了,以此让 Feign 把请求信息输出来。
配置方式
Java Bean
全局生效
利用@Configuration实现全局生效,对所有的微服务调用者都生效
1)定义一个配置类,指定日志级别
4种日志级别
2) 在application.yml中配置 Client 的日志级别才能正常输出日志,格式是"logging.level.feign接口包路径=debug"
3) 测试:分别选择BASIC和FULL级别日志,查看控制台输出
局部生效
让指定的微服务生效,在@FeignClient 注解中指定configuration
注意:此时配置类就不能添加@Configuration注解
yml配置文件
全局生效
配置 {服务名} 为 default
对所有的微服务调用者都生效
局部生效
配置 {服务名} 为 具体服务名
对调用的微服务提供者进行配置
这两种配置方式掌握一种即可,建议在yml中配置,可以利用配置中心对配置进行统一管理
测试日志配置是否生效
调整日志级别为FULL或BASIC,访问localhost:8050/user/getOrder?userId=fox,查看控制台输出
超时时间配置
OpenFeign使用两个超时参数
connectTimeout 可以防止由于较长的服务器处理时间而阻塞调用者。
readTimeout 从连接建立时开始应用,当返回响应花费太长时间时触发。
补充说明: OpenFeign的底层用的是LoadBalancer,但超时时间以OpenFeign配置为准
配置方式
Java Bean
yml配置文件
测试超时配置是否生效
利用Thread.sleep修改订单接口的调用时间,验证是否超时
契约配置(了解即可)
Spring Cloud 在 Feign 的基础上做了扩展,可以让 Feign 支持 Spring MVC 的注解来调用。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。
配置方式
Java Bean
yml配置文件
注意:修改契约配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原生的注解
OrderFeignService 中配置使用Feign原生的注解
客户端组件配置
Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,没有连接池,我们可以集成别的组件来替换掉 URLConnection,比如 Apache HttpClient5,OkHttp。
Feign发起调用真正执行逻辑:feign.Client#execute (扩展点)
配置Apache HttpClient5(推荐)
1)引入依赖
2)修改yml配置,启用Apache HttpClient5 ,引入依赖后是默认启用的,可以忽略
关于配置可参考源码: org.springframework.cloud.openfeign.FeignAutoConfiguration
测试:调用会进入feign.hc5.ApacheHttp5Client#execute
配置 OkHttp
1)引入依赖
2)修改yml配置,将 Feign 的 HttpClient 禁用,启用 OkHttp
关于配置可参考源码: org.springframework.cloud.openfeign.FeignAutoConfiguration
测试:调用会进入feign.okhttp.OkHttpClient#execute
GZIP 压缩配置
开启压缩可以有效节约网络资源,提升接口性能,我们可以配置 GZIP 来压缩数据
yml配置
关于配置可参考源码:org.springframework.cloud.openfeign.encoding.FeignAcceptGzipEncodingAutoConfiguration
编码器解码器配置
Feign 中提供了自定义的编码解码器设置,同时也提供了多种编码器的实现,比如 Gson、Jaxb、Jackson。我们可以用不同的编码解码器来处理数据的传输。如果你想传输 XML 格式的数据,可以自定义 XML 编码解码器来实现,或者使用官方提供的 Jaxb。
扩展点:feign.codec.Encoder & feign.codec.Decoder
配置方式
引入依赖
Java Bean
yml配置文件
拦截器配置
通过拦截器实现参数传递
常用场景:统一添加 header 信息
比如向服务提供者传递全局事务XID,会员ID, 认证token令牌,链路追踪的traceID等等
扩展点: feign.RequestInterceptor
每次 feign 发起http调用之前,会去执行拦截器中的逻辑。
自定义拦截器实现认证逻辑
需求场景
微服务调用链路需要传递请求头的token信息
如果不做任何配置,直接使用openFeign在服务间进行调用就会丢失请求头
解决方案
方案1:增加接口参数
毫无疑问,这方案不好,因为对代码有侵入,需要开发人员每次手动的获取和添加接口参数,因此舍弃
方案2:添加拦截器
1) 代码实现拦截器
2)配置拦截器生效
方式1:Java Bean
方式2: yml配置文件
测试:postman中增加请求头参数Authorization,查看会员服务openFeign日志是否有Authorization信息
Nacos配置中心实战
课程目标
掌握nacos配置中心的常用配置的使用
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
课上代码
项目地址
git切换到nacos-teach分支,选择 tag v2.3.0,v2.3.1
基础回顾
微服务为什么需要配置中心
一个微服务一个application.yml,100个微服务100个application.yml,如果注册中心地址变了,想象一下怎么改配置
配置中心使得配置信息集中管理,易于维护,并且可以动态更新配置
怎么用
Nacos配置中心配置方式的变化
在SpringBoot2.4这个大版本中有一项非常重要的改动:出于对云原生多配置文件的支持,默认关闭了对bootstrap.yml的使用。
解决方案
方案1: 重新启用bootstrap.yml(不推荐)
方案2: 使用spring.config.import(官方推荐)
订单服务整合Nacos配置中心
目标: 把微服务中公共的配置配置统一管理,比如订单服务的注册中心配置和数据库公共配置可以抽取出来
演示环境,以订单服务tlmall-order-config-demo为例
代码地址
1) 在Nacos控制台创建dataId(对应spring.config.import指定的配置文件名)
抽取application.yml中配置信息配置到Nacos指定的dataId文件中
公共配置
nacos-discovery.yml
db-common.yml
订单服务自己的配置
tlmall-order-config-demo.yml
同时注释掉application.yml对应的配置
2)引入依赖
订单服务的pom.xml中引入nacos-config依赖
3) 在订单服务的application.yml 配置文件中配置 Nacos Config 地址并引入服务配置
使用spring.config.import(官方推荐)
注意事项
指定的配置文件对应Nacos配置中心配置的dataId
重启订单服务测试
可以先在application.yml中增加nacos日志打印配置,便于查看从配置中心拉取配置的情况
查看订单服务是否启动成功,并成功注册到Nacos注册中心
如果没有拉取到数据库配置是会报错的
课后作业
tlmall-user-config-demo整合nacos配置中心
Nacos 配置中心常用配置详解
profile 粒度的配置
在日常开发中如果遇到多套环境下的不同配置,可以通过Spring 提供的 ${spring.profiles.active} 这个配置项来配置。
以订单服务为例,配置开发环境和生产环境
1)演示环境准备
1.1) 准备测试代码
1.2) 配置中心增加开发环境和生产环境的配置文件
tlmall-order-config-demo-dev.yml
tlmall-order-config-demo-prod.yml
2)修改application.yml配置
2.1) 配置spring.profiles.active为开发环境
2.2) import中引入${spring.application.name}-${spring.profiles.active}.yml配置
3)测试
3.1)重启订单服务,调用localhost:8060/order/post1,查看测试结果
3.2) 配置jvm参数-Dspring.profiles.active=prod,重启服务,调用localhost:8060/order/post1,查看测试结果
自定义 Namespace 的配置
用于进行租户粒度的配置隔离。
不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。
在没有明确指定 ${spring.cloud.nacos.config.namespace} 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。
测试
1)Nacos配置克隆
将public命名空间下的配置克隆到fox命名空间
2)application.yml中增加spring.cloud.nacos.config.namespace配置
启动订单服务,查看控制台是否拉取了配置
自定义 Group 的配置
主要用于区分不同的微服务或应用组件
一个应用可能使用了database_url配置和MQ_topic配置,我们可以将这些配置分别划分到不同的Group中,以便更好地管理和维护。
在没有明确指定 ${spring.cloud.nacos.config.group} 配置的情况下, 默认使用的是组 DEFAULT_GROUP 。
配置的优先级
按import的配置顺序加载,重复的配置会被覆盖
配置的动态刷新
spring-cloud-starter-alibaba-nacos-config 支持配置的动态更新。
测试:当动态配置刷新时,会更新到 Enviroment中
1)修改启动类,每隔3s从Enviroment中获取order.count的值,并启动订单服务
2)进入配置中心,修改tlmall-order-config-demo-prod.yml的配置,order.count从100改成300
查看控制台输出,count是否从100改为300
调用localhost:8060/order/post1,查看count是否从100改为300
结论:可以从Environment获取到配置中心更改的值,但是OrderController(Bean对象)中@Value修饰的值没有变化
思考:如何实现Spring管理的Bean对象中@Value修饰的属性的动态更新
解决方案
使用@RefreshScope注解实现Bean的动态刷新
使用@RefreshScope修饰的OrderController,访问/order/post1接口可以获取最新的值
测试
调用localhost:8060/order/post1,查看count是否从100改为300
注意:@RefreshScope 使用不当会导致@Scheduled定时任务失效
场景重现
当利用@RefreshScope刷新配置后会导致定时任务失效
测试
当在配置中心变更属性后,定时任务失效
当再次访问/count接口时,定时任务生效
原因分析
@RefreshScope修饰的bean的属性发生变更后,会从缓存中清除。此时没有这个bean,定时任务当然也就不生效了。
解决方案
实现Spring事件监听器,监听 RefreshScopeRefreshedEvent事件,监听方法中进行一次定时方法的调用
OpenFeign开启对feign.Request.Options属性的刷新支持
拓展:Nacos插件
配置加密
需求
为了保证用户敏感配置数据的安全,对配置中心的配置数据加密
解决方案
使用Nacos 加解密插件
在 Nacos 服务端启动的时候就会加载所有依赖的加解密算法,然后通过发布配置的 dataId 的前缀(cipher-[加密算法名称])来进行匹配是否需要加解密和使用的加解密算法。
客户端发布的配置会在客户端通过filter完成加解密,也就是配置在传输过程中都是密文的。而控制台发布的配置会在服务端进行处理。
客户端发布的配置会在客户端通过filter完成加解密,也就是配置在传输过程中都是密文的。而控制台发布的配置会在服务端进行处理。
注意:目前插件需要自己编译,并未上传至maven中央仓库
怎么用
1)环境准备
1.1)编译插件之前需要先编译nacos并安装至本地仓库.
注意:拉取的是最新版的nacos,可以切换到2.3.2的分支后编译
nacos2.3.2源码编译填坑
官方编译命令mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U执行后各种报错
编译环境:jdk8, maven3.5.4
最终编译命令
1.2)编译nacos-aes-encryption-plugin插件
注意:切换到2.2.x的分支编译不会报错
编译环境:jdk8, maven3.5.4
1.3 ) 在nacos的config包下引入nacos-aes-encryption-plugin依赖,重新编译nacos服务端源码
3)创建加密配置
配置前缀使用cipher-[加密算法名称]-dataId来标识这个配置需要加密,系统会自动识别并加密。例如使用 AES 算法来解密配置:cipher-aes-nacos-discovery.yml。
4) 查看mysql数据库config_info表存储的cipher-aes-nacos-discovery.yml数据,是否加密
微服务端如何使用
1)pom.xml中引入加密插件依赖
作用:可以拉取cipher-aes-为前缀的配置
2)在spring.congfig.import中引入cipher-aes-nacos-discovery.yml
Alibaba流控组件Sentinel实战
课程目标
理解常用的服务雪崩解决方案
掌握sentinel的使用,掌握sentinel控制台常用的规则配置
理解sentinel的工作原理
理解Sentinel规则生效流程,能自己实现sentinel配置规则的持久化
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
课上代码
项目地址
git切换到fox-dev分支,选择 tag v2.4.0,v2.4.1
高频面试题:服务雪崩及其解决方案
需求
当服务访问量达到一定程度,流量扛不住的时候,该如何处理?
服务之间相互依赖,当服务A出现响应时间过长,影响到服务B的响应,进而产生连锁反应,直至影响整个依赖链上的所有服务,该如何处理?
商品详情展示服务会依赖商品服务, 价格服务, 商品评论服务。调用三个依赖服务会共享商品详情服务的线程池
如果其中的商品评论服务不可用, 就会出现线程池里所有线程都因等待响应而被阻塞, 从而造成服务雪崩
什么是服务雪崩
在微服务调用链路中,因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程,就叫服务雪崩效应。
当服务调用者使用同步调用时, 会产生大量的等待线程占用系统资源。一旦线程资源被耗尽,服务调用者提供的服务也将处于不可用状态, 于是服务雪崩效应产生了。
常见解决雪崩问题的方案
超时机制
设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止地等待。
由于释放资源速度较快,一定程度上可以抑制资源耗尽的问题。但是这种解决方案只是缓解了雪崩问题,并不能解决雪崩问题。
服务限流
限制业务访问的QPS,避免服务因为流量的突增而故障。
这种是从预防层面来解决雪崩问题。
资源隔离
资源隔离分为进程隔离,线程隔离和信号量隔离。
隔离机制的本质就是将服务调用的粒度划分的更小,以此来减少服务生产崩溃而对服务调用带来的影响,避免服务雪崩现象产生。
比如限定每个业务能使用的线程数,避免耗尽整个线程池的资源。当商品评论服务不可用时, 即使商品服务独立分配的20个线程全部处于同步等待状态,也不会影响其他依赖服务的调用。
服务熔断降级
参考了电路熔断的设计
如果某个目标服务调用慢或者有大量超时,此时,熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用。
当依赖的服务有大量超时时,在让新的请求去访问根本没有意义,只会无畏的消耗现有资源。
有服务熔断,必然要有服务降级。
所谓降级,就是当某个服务熔断之后,服务将不再被调用,此时客户端可以自己准备一个本地的fallback(回退)回调,返回一个缺省值。 例如:(备用接口/缓存/mock数据) 。这样做,虽然服务水平下降,但好歹可用,比直接挂掉要强,当然这也要看适合的业务场景。
Sentinel基础使用详解
为什么会用到sentinel
为了提高系统运行期间的稳定性和可用性
sentinel是什么
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件
官方文档
怎么用
sentinel的核心概念
资源(Resource)
规则(Rule)
Sentinel快速开始
基于API实现资源保护
1)引入依赖
2)定义受保护的资源和流控规则
测试效果:http://localhost:8800/hello
缺点
业务侵入性很强,需要在controller中写入非业务代码.
配置不灵活, 添加新的受保护资源,需要手动添加 init方法来添加流控规则
基于@SentinelResource注解埋点实现资源保护
Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException 等。
注意:注解方式埋点不支持 private 方法。
源码入口:com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect
接入步骤
1)引入依赖
2)配置切面支持
3)HelloController中编写测试逻辑,添加@SentinelResource,并配置blockHandler和fallback
使用注意事项
单独新建一个类用于处理受保护资源的BlockException和fallback,更加的解耦且灵活。
可以通过配置blockHandlerClass和fallbackClass实现
测试效果:http://localhost:8800/hello2
微服务中如何使用sentinel
sentinel的安装
官方参考文档
sentinel由两部分构成
核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持
控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。
安装Sentinel控制台
注意版本
Sentinel Version: 1.8.6
官方文档地址
下载地址
https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar
启动sentinel控制台
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=tlmall-sentinel-dashboard:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
java -Dserver.port=8888 -Dcsp.sentinel.dashboard.server=tlmall-sentinel-dashboard:8888 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.6.jar
如若8080端口冲突,可使用 -Dserver.port=新端口 进行设置。
访问sentinel控制台
从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 sentinel
访问:http://localhost:8888
注意: Sentinel 会在客户端首次调用时候进行初始化,开始向控制台发送心跳包。因此需要确保客户端有访问量,才能在控制台上看到监控数据。
Java应用和Sentinel Dashboard通信原理
测试:http://localhost:8719/getRules?type=flow 获取流控规则信息
sentinel整合微服务
官方参考文档
以订单服务为例
1)引入sentinel的依赖
2)业务代码中配置需要保护的资源
mvc接口方法自动埋点,不需要配置
非mvc接口方法可以使用@SentinelResource 注解用来标识资源是否被限流、降级
3)添加yml配置,为订单服务设置sentinel控制台地址
测试,重启订单服务,对获取订单接口进行流控
启动sentinel控制台,在sentinel控制台中设置流控规则
注意:需要先访问一次获取接口,sentinel控制台才会有订单服务记录
将单机阈值调为1,用postman测试获取接口,是否被流控
通过Sentinel 对外暴露的 Endpoint查看流控配置
1)引入依赖
2)添加Sentinel后,需要暴露/actuator/sentinel端点
3)访问http://localhost:8060/actuator/sentinel, 可以查看流控规则信息
RestTemplate整合Sentinel
Spring Cloud Alibaba Sentinel 支持对 RestTemplate 的服务调用使用 Sentinel 进行保护,在构造 RestTemplate bean的时候需要加上 @SentinelRestTemplate 注解。
Sentinel RestTemplate 限流的资源规则提供两种粒度:
- httpmethod:schema://host:port:协议、主机和端口
- httpmethod:schema://host:port/path:协议、主机、端口和路径
整合步骤
以tlmall-user-sentinel-demo为例,会员服务查询订单服务,已经接入sentinel
1)RestTemplate添加@SentinelRestTemplate注解
异常处理配置
源码跟踪:
com.alibaba.cloud.sentinel.custom.SentinelBeanPostProcessor
com.alibaba.cloud.sentinel.custom.SentinelProtectInterceptor#intercept
com.alibaba.cloud.sentinel.custom.SentinelBeanPostProcessor
com.alibaba.cloud.sentinel.custom.SentinelProtectInterceptor#intercept
2)添加yml配置,开启sentinel对resttemplate的支持,默认开启,可忽略
3) 测试
在sentinel控制台中对被保护的restTemplate资源进行限流配置,测试是否限流
访问订单接口localhost:8050/user/getOrder?userId=fox
在sentinel控制台中对被保护的restTemplate资源进行熔断规则配置,测试是否熔断降级
访问订单接口http://localhost:8050/user/getOrder?userId=foxxxx
注意:要先删除限流规则,再测试
OpenFeign整合Sentinel
Sentinel 适配了 Feign 组件。
源码跟踪:com.alibaba.cloud.sentinel.feign.SentinelInvocationHandler#invoke
整合步骤
1)yml配置文件中开启 Sentinel 对 Feign 的支持
2)在Feign的声明式接口上添加fallback或者fallbackFactory属性
3)测试
访问:http://localhost:8050/user/getOrder?userId=fox,生成如下sentinel openFeign的资源
测试限流
在sentinel控制台配置流控规则
访问:http://localhost:8050/user/getOrder?userId=fox,测试流控规则是否生效
测试降级
访问http://localhost:8050/user/getOrder?userId=foxxxx(userId=foxxxx订单服务会抛出异常),测试降级是否生效
关闭tlmall-order-sentinel-demo服务,访问http://localhost:8050/user/getOrder?userId=fox,测试降级是否生效
Sentinel工作原理
官方文档
Sentinel常用规则配置详解
通过Sentinel控制台进行sentinel的规则配置
Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。
阿里云提供了 企业级的 Sentinel 控制台,应用高可用服务 AHAS
测试环境准备
启动nacos server
启动sentinel 控制台
演示环境初始代码
git切换到fox-dev分支,选择 tag v2.4.0
结合课上演示掌握sentinel开源控制台的规则配置
实时监控
监控接口的通过的QPS和拒绝的QPS
注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。
注意: 实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制。
簇点链路
用来显示微服务的所监控的API。
注意: 簇点监控是内存态的信息,它仅展示启动后调用过的资源。
流控规则
官方文档
影响流控效果的关键因素
resource:资源名,即限流规则的作用对象
count: 限流阈值
grade: 限流阈值类型,QPS 或线程数
strategy: 根据调用关系选择策略
基于 QPS/并发数的流量控制
QPS
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
流控的效果
为什么是这个效果?
参考源码:DefaultBlockExceptionHandler
新的需求:需要对异常进行统一管理
实现思路
springwebmvc接口资源限流入口在HandlerInterceptor的实现类AbstractSentinelInterceptor的preHandle方法中,对异常的处理是BlockExceptionHandler的实现类
自定义BlockExceptionHandler 的实现类统一处理BlockException
重启服务后测试的流控效果
注意:因为流控规则是写入内存中的,重启服务流控规则会丢失,需要重新配置
并发线程数
并发线程数控制用于保护业务线程池不被慢调用耗尽。
简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
流控效果
基于调用关系的流量控制
根据调用方限流
origin 参数标明了调用方身份。
可通过以下命令来展示不同的调用方对同一个资源的调用数据
资源/order/getOrder被两个不同的调用方调用
注意:默认是没有实现来源数据的,需要实现RequestOriginParser接口
简单理解就是:可以实现对userId=fox限流,对userId=foxx不限流
拓展: 可以实现对请求头,请求参数的流控
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
自定义的RequestOriginParser接口实现类MyRequestOriginParser中指定了userId的值可以为来源
测试效果
http://localhost:8060/order/getOrder?userId=fox 会被流控
因为实现了MyRequestOriginParser,userId=fox会被解析出fox为来源赋值给origin,而来源fox是被流控了的
http://localhost:8060/order/getOrder?userId=foxx 不会被流控
具有关系的资源流量控制:关联流量控制
简单理解就是:当关联资源A达到阈值,对资源B流控
可使用关联限流来避免具有关联关系的资源之间过度的争抢,比如当写库操作过于频繁时(可以配置一个阈值),读数据的请求会被限流
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
测试效果
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
指定http请求接口是 http://localhost:8060/order/getOrderById/1
http://localhost:8060/order/getOrder?userId=fox 会被流控
根据调用链路入口限流:链路限流
简单点理解就是: 资源A和B都会调用C,设置入口资源是A,当C达到阈值了,对入口资源A进行流控,而不会对B进行流控
注意,高版本此功能直接使用不生效,如何解决?
1.8.6中需要在yml中配置spring.cloud.sentinel.web-context-unify属性为false
启动订单服务tlmall-order-sentinel-demo,测试
准备测试环境
OrderServiceImpl#getOrderById 方法添加注解@SentinelResource进行资源保护
参考OrderController#getOrderById方法 新增TestController测试类
测试接口
配置流控规则
测试效果
http://localhost:8060/test2/1 会被流控
http://localhost:8060/test1/1 不会被流控
流控效果
快速失败(直接拒绝)
达到阈值后,新的请求会被立即拒绝并抛出FlowException异常。是默认的处理方式。
用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
Warm Up(预热)
预热模式,对超出阈值的请求同样是拒绝并抛出异常。但这种模式阈值会动态变化,从一个较小值逐渐增加到最大阈值。
冷加载因子: codeFactor 默认是3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
流控效果
匀速排队(排队等待)
让所有的请求按照先后次序排队执行,两个请求的间隔不能小于指定时长
会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。
主要用于处理间隔性突发的流量,例如消息队列。
注意:匀速排队模式暂时不支持 QPS > 1000 的场景。
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置流控规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
流控效果
熔断降级规则
官方文档
作用
对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。
熔断降级规则(DegradeRule)属性
熔断策略
慢调用比例
当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
启动订单服务tlmall-order-sentinel-demo,测试
准备测试环境
添加测试代码TestController#test
查询接口
配置降级规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
查看实时监控,可以看到断路器熔断效果
此时浏览器访问会出现服务降级结果
异常比例
当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。
启动订单服务tlmall-order-sentinel-demo,测试
准备测试环境
添加测试代码TestController#test222
查询接口
配置降级规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
查看实时监控,可以看到断路器熔断效果
异常数
当单位统计时长内的异常数目超过阈值之后会自动进行熔断。
启动订单服务tlmall-order-sentinel-demo,测试
准备测试环境
添加测试代码TestController#test222
查询接口
配置降级规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
查看实时监控,可以看到断路器熔断效果
热点规则
官方文档
热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。
注意
1.热点规则需要使用@SentinelResource("resourceName")注解,否则不生效
2.参数必须是7种基本数据类型才会生效
2.参数必须是7种基本数据类型才会生效
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置热点规则
注意: 资源名必须是@SentinelResource(value="资源名")中 配置的资源名,热点规则依赖于注解
测试
http://localhost:8060/order/getOrderById/3 限流的阈值为1
http://localhost:8060/order/getOrderById/1 限流的阈值为2
系统规则
官方文档
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。
系统自适应保护的目的
- 保证系统不被拖垮
- 在系统稳定的前提下,保持系统的吞吐量
系统规则支持以下的阈值类型
Load(仅对 Linux/Unix-like 机器生效):当系统 load1 超过阈值,且系统当前的并发线程数超过系统容量时才会触发系统保护。系统容量由系统的 maxQps * minRt 计算得出。设定参考值一般是 CPU cores * 2.5。
CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0)。
RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。
启动订单服务tlmall-order-sentinel-demo,测试
配置系统规则
为了演示出效果,这里使用压测工具jmeter进行测试
线程组的配置
测试订单接口
查看实时监控,可以看到限流效果
授权控制规则
官方文档
来源访问控制(黑白名单)
来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
来源访问控制规则(AuthorityRule)配置项:
- resource:资源名,即限流规则的作用对象。
- limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB。
- strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式。
origin 参数标明了调用方身份。
其实和限流规则中的调用方限流本质的原理是一致的,只是应用场景的区别而已
可通过以下命令来展示不同的调用方对同一个资源的调用数据
资源/order/getOrder被两个不同的调用方调用
注意:默认是没有实现来源数据的,需要实现RequestOriginParser接口
简单理解就是:可以实现对userId的 黑白名单配置
启动订单服务tlmall-order-sentinel-demo,测试
查询订单接口
配置授权规则
自定义的RequestOriginParser接口实现类MyRequestOriginParser中指定了userId的值可以为来源
测试效果
http://localhost:8060/order/getOrder?userId=fox 不会被限制访问
http://localhost:8060/order/getOrder?userId=foxx 会被限制访问
foxx是黑名单
集群规则
官网文档
开源版sentinel 控制台没有真正实现(不做过多讲解,了解即可)
云上版本 AHAS Sentinel 提供开箱即用的全自动托管集群流控能力,无需手动指定/分配 token server 以及管理连接状态,同时支持分钟小时级别流控、大流量低延时场景流控场景,同时支持 Istio/Envoy 场景的 Mesh 流控能力。
Sentinel规则持久化
Sentinel控制台规则推送三种模式
原始模式(默认)
如果不做任何修改,Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存中
优点
简单,无依赖
缺点
应用重启规则就会消失,仅用于简单测试,不能用于生产环境
改造方式
扩展写数据源(WritableDataSource)
核心源码参考:com.alibaba.csp.sentinel.command.handler.ModifyRulesCommandHandler#handle
拉模式
客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等
优点
简单,无任何依赖;规则持久化
缺点
不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。
改造方式
扩展写数据源(WritableDataSource)
官方实现的方案
基于文件实现拉模式
官方demo: sentinel-demo/sentinel-demo-dynamic-file-rule
fox老师实现的方案
基于Nacos实现拉模式,实现写数据源
当sentinel控制台推送规则到内存后就将规则发布到Nacos配置中心
核心实现:com.alibaba.nacos.api.config.ConfigService#publishConfig
推模式
规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。
生产环境下一般采用 push 模式的数据源。
优点
规则持久化;有更好的实时性和一致性保证
缺点
引入第三方依赖
改造方式
扩展读数据源(ReadableDataSource)
官方实现方案
基于Nacos配置中心控制台实现推送
官方demo: sentinel-demo-nacos-datasource
基于Nacos配置中心控制台实现推送
以tlmall-order-sentinel-demo为例,测试流控规则是否能持久化
实现步骤
1)引入依赖
此依赖包中实现了读数据源
2)yml中增加从Nacos数据源读取流控规则的配置
如何指定规则类型: RuleType
源码参考:com.alibaba.cloud.sentinel.datasource.config.AbstractDataSourceProperties#postRegister
3) nacos配置中心中配置流控规则
测试
重启订单微服务,测试流控规则是否生效
重启之后,订单微服务是存在流控规则的
从Nacos配置中心拉取到了流控规则
测试订单查询接口
订单查询接口被流控了
缺点
通过sentinel控制台修改的流控规则还是会丢失
发现问题
只能从Nacos配置中心读取规则数据,通过Sentinel控制台推送的规则不能写入Nacos配置中心,规则数据还是会丢失
新的需求
通过Sentinel控制台修改流控规则后,Nacos配置中心对应的流控规则也会更新
解决方案
方案1
改造Sentinel控制台,配置规则的时候推送到Nacos配置中心
不建议,需要改造Sentinel控制台源码
如何改造?后续sentinel持久化源码分析课中有实现
方案2
微服务端扩展写数据源(WritableDataSource),将规则保存到Nacos配置中心
思路: 推拉结合,使用官方提供的读数据源扩展,自己实现Nacos写数据源
参考课上源码实现
fox-dev分支 tag v2.4.2
测试
Sentinel控制台修改流控规则后,Nacos配置中心的流控规则是否也会被更新
Sentinel控制台流控规则阈值改为2
Nacos配置中心中流控规则阈值也变成了2
更多的原理和实现方式可以在后续源码课程中深入学习
Sentinel规则持久化进阶课程
Sentinel规则持久化拉模式实战及其源码分析(两节)
Sentinel规则持久化源码分析图
Alibaba分布式事务组件Seata实战
课程目标
掌握微服务快速整合Seata实现分布式事务
重点掌握Seata AT模式,理解AT模式的工作原理
怎么学
Seata的课程安排
Seata版本选择
Seata版本2.0.0
注意:生产环境不建议用这个版本,bug有点多
可以降低版本,比如选择Seata1.7.0
可以去看vip第六期微服务专题Seata课程,是基于Seata1.7.0的
注意:使用Spring Cloud Alibaba一定要先考虑版本兼容性的问题
版本选型
本课程会详细讲解Seata官方首推的AT模式
在《轻松玩转微服务:新手入门Spring Cloud Alibaba》中整合的就是Seata AT模式
如果想了解其他模式,比如TCC,可以看《Alibaba分布式事务组件Seata XA&TCC实战》
课上代码
项目地址
git切换到fox-dev分支,选择 tag v1.0.6
Seata基础快速回顾
课程目标:微服务快速整合Seata
事务不头疼:Seata解决分布式事务
为什么要使用分布式事务
问题重现
当账户余额会0时,还是可以下单成功,而且扣减库存
新的需求
下单逻辑需要保证数据一致性,当账户余额不够时,库存回滚,下单失败
解决方案
思考:使用spring事务能解决问题吗?
不能
使用分布式事务解决方案Seata (官方推荐)
Seata是什么
官方文档
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。
首选Seata AT 模式(官方推荐),可以做到业务无侵入
Seata AT模式的工作流程
非常重要的三个概念(要理解)
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
比如,当前订单服务下单,调用库存服务扣减库存,调用账户服务扣减账户余额
订单服务要接入TM组件
下单操作需要开启全局事务(向TC申请一个全局事务XID),进入下单逻辑
如果下单正常,需要通知TC提交全局事务
如果下单异常,比如余额不够,需要通知TC回滚全局事务
订单服务,库存服务,账户服务都要接入RM组件
提交本地事务的同时,需要向TC注册分支事务信息
接收TC的通知,提交或回滚分支事务
TC是独立的服务
维护TM申请的全局事务信息和 RM提交的分支事务信息
TM通知TC全局事务提交或者回滚的时候,TM要通知RM分支事务提交或回滚
AT模式工作流程
问题:如何知道调用的是同一个分布式事务?
开启全局事务会分配一个全局事务XID,微服务链路会传递XID,注册每个分支事务都会带上XID
Seata Server(TC)安装部署
注意版本
Seata Version:2.0.0
下载地址
https://github.com/apache/incubator-seata/releases/download/v2.0.0/seata-server-2.0.0.zip
官网参考资料
Seata新手部署指南
seata 参数配置官网参考
TC端存储模式
全局事务分支事务信息存储到哪儿?
Seata1.x 支持的模式
file:单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高,但是只支持单机模式部署,生产环境不考虑。
db:高可用模式,全局事务会话信息通过db共享,相应性能差些
redis:1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置
Seata2.x新增的Raft模式
利用Raft算法实现多个TC之间数据的同步。
raft模式是最理想的方案,但是当前并不成熟,所以不用考虑。
从稳定性角度考虑,最终选择采用db模式
创建seata数据库,sql脚本在seata-server-2.0.0\seata\script\server\db\mysql.sql
思考:RM和TM如何找到TC服务
可以将TC服务注册到Nacos,RM和TC通过Nacos注册中心实现TC服务的发现
注意:Seata的注册中心是作用于Seata自身的,和微服务自身配置的注册中心无关,但可以共用注册中心。
可以创建一个seata的命名空间,区分seata的TC服务和业务微服务
思考:TC的配置是不是也可以交个Nacos配置中心管理?
最终方案:db存储模式+Nacos(注册&配置中心)方式部署
前置环境准备
1.db模式准备好seata的数据库
2.准备好Nacos环境
配置Nacos注册中心
配置将Seata Server注册到Nacos,修改conf/application.yml文件
注意
这个cluster配置,默认TC是default集群,TM和RM要通过这个集群名找TC集群
请确保client(RM TM)与server(TC)的注册处于同一个namespace和group,不然会找不到server服务。
配置Nacos配置中心
1)配置Nacos配置中心地址,修改conf/application.yml文件
2)将seata server的配置上传配置至Nacos配置中心
a) 获取/seata/script/config-center/config.txt,修改为db存储模式,并修改mysql连接配置
TC如何使用mysql8?
b) 配置事务分组, TC要与client(RM TM)配置的事务分组一致
事务分组如何找到后端Seata集群?
c) 在nacos配置中心中新建dataId为seataServer.properties的配置,配置内容为上面修改后的config.txt中的配置信息
注意
是在seata命名空间下新建seataServer.properties,要和conf/application.yml中的config配置对应上
特别注意seataServer.properties是否是SEATA_GROUP
启动Seata Server
windows点击bin目录下seata-server.bat直接启动
启动成功,查看控制台http://127.0.0.1:7091,账号密码都是seata。
在Nacos注册中心中可以查看到seata-server注册成功
微服务整合Seata AT模式实战
业务场景
用户下单,订单服务调用库存服务扣减库存,调用账户服务扣减账户余额
事务发起者:订单服务
事务参与者:库存服务,账户服务
订单服务(事务发起者)整合Seata
1)引入seata的依赖
2) 订单服务对应数据库中添加undo_log表(仅AT模式)
3)订单服务application.yml中添加seata配置
需要在nacos的控制台中创建一个seata的命名空间,用于和业务微服务隔离
注意:请确保client与server的注册中心和配置中心namespace和group一致
优化:可以将seata配置移到配置中心中
4)订单服务作为全局事务发起者,在下单方法上添加@GlobalTransactional注解
库存服务(事务参与者)整合Seata
和整合订单服务前三步一样
4)库存服务只需要在扣减库存方法上添加Spring事务@Transactional注解
账户服务(事务参与者)整合Seata
配置同库存服务一样
Seata2.x常见问题
微服务启动报错:io.seata.config.exception.ConfigNotFoundException: service.vgroupMapping.default_tx_group configuration item is required
产生的原因&解决思路
原因:无法拉取到service.vgroupMapping.default_tx_group=default这个配置,也就找不到集群名为default的seata server服务
思路1:检查下微服务端seata配置是否未配置事务分组seata.tx-service-group=default_tx_group
思路2:检查下namespace和group配置server端和client端是否对应,特别注意seataServer.properties是否是SEATA_GROUP
seata server报错:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
产生的原因&解决思路
原因:无法连上数据库
思路:检查下seataServer.properties中jdbc配置是否正确,检查jdbc版本和mysql版本是否匹配
重启所有服务,测试分布式事务是否生效
下单:http://localhost:8080/order
分布式事务成功场景,模拟正常下单、扣库存,扣余额
分布式事务失败场景,模拟下单扣库存成功、扣余额失败,事务是否回滚
有个问题:seata2.0.0 版本的bug,还是版本不兼容引起的
事务发生回滚,回滚成功了,但是最外层代码无法捕捉到原始的BusinessException异常,只能捕捉到RuntimeException运行时异常
原因分析
建议:不要在生产上用最新版本Seata2.0.0,坑有点多
关于Seata更多的配置使用,会在Seata实战课程中进行详解
小结
通过Seata可以解决微服务分布式事务的问题
Seata AT模式的设计思路剖析
业界处理分布式事务的常用思路
两阶段提交
什么是两阶段提交(2PC)
一阶段
TM(事务管理器)通知各个RM(资源管理器)准备提交(prepare 预提交)它们的事务分支。
注意:以mysql为例,此阶段sql执行了,但是事务没有提交,数据库连接对象也没有释放
二阶段
TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare失败的话,则TM通知所有RM回滚自己的事务分支。
两阶段提交方案下全局事务的ACID特性,是依赖于RM的。各个事务分支的ACID特性共同构成了全局事务的ACID特性。
使用AT模式的前提
基于支持本地 ACID 事务的关系型数据库。
Java 应用,通过 JDBC 访问数据库。
2PC存在的问题
同步阻塞问题
2PC 中的参与者是阻塞的。在第一阶段收到请求后就会预先锁定资源,一直到 commit 后才会释放。
单点故障
由于协调者的重要性,一旦协调者TM发生故障,参与者RM会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。
数据不一致
若协调者第二阶段发送提交请求时崩溃,可能部分参与者收到commit请求提交了事务,而另一部分参与者未收到commit请求而放弃事务,从而造成数据不一致的问题。
Seata AT模式
适用场景
业务流程长、业务流程多
参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
设计思路
Seata AT模式的核心是对业务无侵入,是一种改进后的两阶段提交
一阶段
业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源。
一阶段的核心在于对业务sql进行解析,转换成undolog,并同时入库,这是怎么做的呢?
二阶段
提交异步化,非常快速地完成。回滚通过一阶段的回滚日志进行反向补偿。
分布式事务操作成功,则TC通知RM异步删除undolog
分布式事务操作失败,TM向TC发送回滚请求,RM 收到协调器TC发来的回滚请求,通过 XID 和 Branch ID 找到相应的回滚日志记录,通过回滚记录生成反向的更新 SQL 并执行,以完成分支的回滚。
以下单业务为例
优势
一阶段提交本地事务,无锁,高性能
补偿服务易于实现
事件驱动架构,参与者可异步执行,高吞吐
缺点
不保证隔离性
Seata AT模式是如何处理隔离性(多个事务并发)问题的
官方文档
写隔离
一阶段本地事务提交前,需要确保先拿到 全局锁 。
拿不到 全局锁 ,不能提交本地事务。
拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。
读隔离
SELECT FOR UPDATE
怎么使用Seata框架,来保证事务的隔离性?
脏读 select 语句加 for update,代理方法增加@GlobalLock+@Transactional 或@GlobalTransactional
脏写 必须使用@GlobalTransactional
微服务API网关Spring Cloud Gateway实战
课程目标
理解Spring Cloud Gateway的核心概念和工作原理
能够使用Spring Cloud Gateway实现微服务API网关
掌握Spring Cloud Gateway的常用配置和扩展点,能够在工作中根据业务需求进行扩展
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
技术选型
使用Spring Cloud Gateway实现微服务网关
阿里云推荐的微服务网关方案:Higress
官网地址
云原生网关Higress实战
产品对比
课上代码
项目地址
nacos-examples/tlmall-gateway01
git切换到fox-dev分支,选择 tag v2.5.0
基础回顾
智能门卫:Gateway轻松守护微服务入口
微服务为什么需要API网关
在微服务架构中,通常一个系统会被拆分为多个微服务,面对这么多微服务客户端应该如何去调用呢?
如果根据每个微服务的地址发起调用,存在如下问题:
为了解决上面的问题,微服务引入了 API网关 的概念
Spring Cloud Gateway是什么
官方文档
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。
Spring Cloud Gateway 是由 WebFlux + Netty + Reactor 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
微服务快速接入Spring Cloud Gateway
构建网关服务
创建一个新的module模块tlmall-gateway
pom.xml中引入Spring Cloud Gateway网关依赖
注意:gateway会和spring-webmvc的依赖冲突,需要排除spring-webmvc
微服务快速接入网关服务
以订单服务为例,在网关服务的application.yml
库存服务,账户服务同上
网关服务的完整的application.yml配置如下
此配置可以移到配置中心,新增一个tlmall-gateway.yml的配置
测试,启动网关服务
postman中通过网关服务的18888端口下单,看能否成功
tlmall-frontend前端服务order.html中访问地址都替换为tlmall-gateway:18888,测试下单是否成功
关于Spring Cloud Gateway更多的操作,会在Spring Cloud Gateway实战课程中讲解
小结
gateway就是整个微服务架构的流量入口
Gateway的工作原理分析
核心概念
路由(route)
路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。
断言(predicates)
断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。
如果断言为真,则说明请求的URL和配置的路由匹配。
过滤器(Filter)
Filter可以对请求和响应进行处理。
SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。
工作原理
客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑。
Gateway常用配置与自定义扩展详解
路由断言工厂(Route Predicate Factories)配置
官方文档
predicates:路由断言,判断请求是否符合要求,符合则转发到路由目的地。
通过网关启动日志,可以查看内置路由断言工厂
路径匹配
测试调用订单查询接口是否能正常调通
Header匹配
使用postman测试调用http://localhost:18888/order/getOrder?userId=fox
不带请求头X-Request-Id
带请求头X-Request-Id
过滤器工厂( GatewayFilter Factories)配置
官方文档
GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理
常用的过滤器工厂
添加请求头
需求:给所有进入mall-order的请求添加一个请求头:X-Request-color=red。
只需要修改gateway服务的application.yml文件,添加路由过滤即可
测试
在OrderController中添加测试代码
调用http://localhost:18888/order/testgateway
添加请求参数
测试
添加测试代码
调用http://localhost:18888/order/testgateway3
自定义过滤器工厂
继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。
实现步骤
1)实现自定义过滤器工厂CheckAuthGatewayFilterFactory
2)配置自定义的过滤器工厂
测试
调用http://localhost:18888/order/getOrder?userId=fox
查看控制台输出
全局过滤器(Global Filters)配置
官方网址
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。
区别
- GatewayFilter:网关过滤器,需要通过spring.cloud.routes.filters配置在具体的路由下,只作用在当前特定路由上,也可以通过配置spring.cloud.default-filters让它作用于全局路由上。
- GlobalFilter:全局过滤器,不需要再配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain能够识别的过滤器。
常见的全局过滤器
负载均衡器的过滤器ReactiveLoadBalancerClientFilter
其实就是用来整合负载均衡器loadbalancer的
配置
自定义全局过滤器
需求:实现token校验
自定义全局过滤器CheckAuthFilter
测试,postman调用http://localhost:18888/order/getOrder?userId=fox
请求头部没有携带token
请求头部携带token
Gateway跨域资源共享配置(CORS Configuration)
在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。
所谓同源(即在同一个域)就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。
CORS
跨域问题测试
测试代码Order.html
测试结果
如何解决gateway跨域问题?
官方文档
通过yml配置的方式
通过java配置的方式
限流
Gateway基于redis+lua脚本限流
官方文档
spring cloud官方提供了RequestRateLimiter过滤器工厂,基于redis+lua脚本方式采用令牌桶算法实现了限流。
请求不被允许时返回状态:HTTP 429 - Too Many Requests。
实现步骤
1) 添加依赖
2)修改 application.yml ,添加redis配置和RequestRateLimiter过滤器工厂配置
3) 配置keyResolver,可以指定限流策略,比如url限流,参数限流,ip限流等等
4) 测试
参数限流:http://localhost:18888/order/getOrder?userId=fox
Gateway整合sentinel限流
官方文档
限流维度
- route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
- 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
Gateway整合sentinel实现网关限流步骤
1)引入依赖
2)添加yml配置,接入sentinel dashboard,通过sentinel控制台配置网关流控规则
重启网关服务进行测试
测试接口
配置流控规则
route维度
注意:基于SpringBoot3的 Spring Cloud Gateway和Sentinel存在兼容性问题
默认的DefaultBlockRequestHandler会抛出上面的异常
解决方案
重新BlockRequestHandler异常处理逻辑
1)自定义实现BlockRequestHandler接口
2) 实现ApplicationRunner接口,springboot启动之后替换异常处理类
测试
配置流控规则
API维度
1)创建API
2)配置流控规则
测试效果
Sentinel网关流控实现原理
链路追踪组件Skywalking实战
课程目标
掌握Skywalking的使用,解决微服务链路追踪问题
怎么学
没接触过微服务的同学一定要先把《轻松玩转微服务:新手入门Spring Cloud Alibaba》这节课跟一遍
课上代码
项目地址
skywalking-examples/springboot-skywalking-demo
git切换到fox-dev分支,选择 tag v2.6.0
基础回顾
监控可视化:Skywalking实时追踪服务链路
全链路追踪的作用
对请求源头到底层服务的调用链路中间的所有环节进行监控。
skywalking是什么
官方网站
skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。
SkyWalking 是观察性分析平台和应用性能管理系统,提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
Skywalking整体架构
SkyWalking 环境搭建部署
下载 SkyWalking
apache-skywalking-apm-10.0.1.tar.gz
https://www.apache.org/dyn/closer.cgi/skywalking/10.0.1/apache-skywalking-apm-10.0.1.tar.gz
skywalking的后端服务OAP+可视化UI
apache-skywalking-java-agent-9.3.0.tgz
https://www.apache.org/dyn/closer.cgi/skywalking/java-agent/9.3.0/apache-skywalking-java-agent-9.3.0.tgz
用于从微服务采集数据的探针
搭建SkyWalking OAP 服务
1)修改配置
先使用默认的H2数据库存储,不用修改config/application.yml配置
skywalking-web-ui服务会占用 8080 端口, 修改端口可以修改webapp/webapp.yml
2)windows下启动脚本bin/startup.bat
启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui
访问UI界面,如果端口改为了18080,访问:http://localhost:18080/
微服务接入Skywalking agent探针
微服务配置jvm参数,接入skywalking
以订单服务为例,idea启动配置中配置skywalking agent
账户服务,库存服务同上
测试,用户下单,在skywalking UI界面查看是否有链路数据
常见问题: 没有查看到网关服务的数据
需要将agent包下的optional-plugins/apm-spring-cloud-gateway-4.x-plugin-9.3.0.jar 拷贝到plugins下
网关服务整合日志框架后不打印traceId
参考
关于Skywalking更多的操作,会在Skywalking实战课程中讲解
小结
通过Skywalking可以实现微服务调用链路追踪
常用配置
演示环境
以springboot-skywalking-demo为例,配置skywalking-agent
测试接口
Skywalking集成日志框架
官方文档
实现步骤
1)引入依赖
2) 微服务添加logback-spring.xml文件,并配置 %tid 占位符
测试 ,调用http://localhost:8000/user/list
查看控制台日志
3) Skywalking通过grpc上报日志 (需要v8.4.0以上)
gRPC报告程序可以将收集到的日志转发到SkyWalking OAP服务器上
logback-spring.xml中添加GRPCLogClientAppender
Skywalking UI效果
自定义SkyWalking链路追踪
需求
希望对项目中的业务方法,实现链路追踪,方便我们排查问题
实现步骤
1)引入依赖
在业务方法中可以使用TraceContext获取到traceId
测试 ,调用http://localhost:8000/user/list
控制台打印traceId
在Skywalking UI中查询tranceId
2) @Trace将方法加入追踪链路
如果一个业务方法想在ui界面的追踪链路上显示出来,只需要在业务方法上加上@Trace注解即可
还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。
实现方式:在方法上增加@Tag或者@Tags。
Skywalking告警通知
官方文档
skywalking发行版中提供了默认的alarm-setting.yml文件,包括一些规则
告警规则的定义分为三部分:
- 告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件;
- 网络钩子(Webhook}:当警告触发时,哪些服务终端需要被通知;
- gRPC钩子:远程gRPC方法的主机和端口,告警触发后调用;
比如service_resp_time_rule规则
该规则表示服务{name}的响应时间在最近10分钟的3分钟内超过1000ms
属性的含义
测试告警通知
1) 编写接口,模拟慢查询
2) 访问接口http://localhost:8000/user/info/2,过段时间会在skywalking控制界面出现了告警信息
3) 实现回调接口
当前10.0.1版本出现回调不通的bug
排查思路
4) 在config/alarm-settings.yml中配置回调接口,并重启skywalking服务
测试访问:http://localhost:8000/user/info/2,满足告警规则后,控制台输出告警信息
Skywalking持久化追踪数据
基于elasticsearch持久化
1.准备好elasticsearch环境(参考ES专题)
启动elasticsearch服务
2.修改config/application.yml配置文件,指定存储使用ES,修改elasticsearch的连接配置
3. 启动Skywalking服务
启动时会向elasticsearch中创建大量的index索引用于持久化数据
启动应用程序,查看追踪数据是否已经持久化到elasticsearch的索引中,然后重启skywalking,验证追踪数据会不会丢失
Skywalking集群部署(oap服务高可用)
Skywalking集群是将skywalking oap作为一个服务注册到nacos上,只要skywalking oap服务没有全部宕机,保证有一个skywalking oap在运行,就能进行追踪。
搭建一个skywalking oap集群需要:
(1)至少一个Nacos(也可以是nacos集群)
(2)至少一个ElasticSearch(也可以是es集群)
(3)至少2个skywalking oap服务;
(4)至少1个UI(UI也可以集群多个,用Nginx代理统一入口)
(2)至少一个ElasticSearch(也可以是es集群)
(3)至少2个skywalking oap服务;
(4)至少1个UI(UI也可以集群多个,用Nginx代理统一入口)
搭建步骤
1.修改config/application.yml文件
使用nacos作为注册中心
修改nacos配置
可以选择性修改监听端口
修改存储策略,使用elasticsearch作为storage
2. 配置ui服务webapp/application.yml文件的oap-service,写多个oap服务地址
3.启动微服务测试
指定微服务的jvm参数
微服务安全组件Sa-Token实战
为什么选择使用Sa-Token?
相对于Spring Security配置繁琐,Sa-Token简单易用,功能齐全
提供了开箱即用的微服务认证方案
课程目标
掌握权限认证框架Sa-Token的基本使用
使用Sa-Token实现微服务安全认证
怎么学
结合Sa-Token官方文档(非常详细)
官方代码仓库
sa-token-demo案例齐全
课上代码
项目地址
git切换到sa-token分支,选择 tag v2.7.0
Sa-Token基础
Sa-Token的介绍
Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、单点登录、OAuth2.0、分布式Session会话、微服务网关鉴权 等一系列权限相关问题。
SpringBoot整合Sa-Token
官方文档
登录认证
官方文档
权限认证
官方文档
基于Sa-Token实现微服务安全
分布式Session会话
网关统一鉴权
内部服务外网隔离
课程视频已经被sa-token官方加入官方文档导航栏
5.微服务架构揭秘:Spring Cloud Alibaba组件底层原理与源码剖析
Nacos注册中心底层原理与源码剖析
Nacos配置中心底层原理与源码剖析
流控组件Sentinel底层原理与源码剖析
分布式事务组件Seata底层原理与源码剖析
Spring扩展点在微服务组件中的应用
6.微服务算法解密:Spring Cloud Alibaba核心组件算法深入剖析
限流算法:保护服务不因突发流量而崩溃
固定窗口
滑动窗口
漏桶
令牌桶
数据一致性算法:确保数据在分布式系统中的一致状态
Raft
Distro协议
使用DeepSeek高效学习Spring Cloud Alibaba
亲测有效!6种DeepSeek-R1 671B满血模型替代方案
SpringBoot + Spring AI Alibaba 整合阿里云百炼DeepSeek大模型

收藏

收藏
0 条评论
下一页