前言
大家好,一直以来我都本着用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 基础知识 的铺垫。目前正在出一个SpringCloud
长期系列教程,从入门到进阶, 篇幅会较多~
适合人群
- 有一定的Java基础
- 想尝试微服务开发
- 有SpringBoot开发基础
- 想学习或了解SpringCloud
- 想提高自己的同学
大佬可以绕过 ~
背景
如果你是一路看过来的,很高兴你能够耐心看完。之前带大家学了Springboot
这门框架,熟练掌握了单体应用
的开发,如今微服务
开发盛行,对我们的技术要求也是越来越高,薪资也是令人兴奋。这个系列将会带大家学习SpringCloud
微服务开发,我会带大家一步一步的入门,耐心看完你一定会有收获
~
情景回顾
xdm昨天迟到了哈,今天补上,全给大家整完。上期带大家一起认识了OpenFeign
以及带大家体验了常用的方法,本期带着上期遗留下来的问题学习sentinel
,我们一起来看一下吧~
Sentinel是啥
同样的,我们先了解一下它到底是个啥?为啥要用它, 其实sentinel
并不是springcloud
大家族的一员,这里还是带大家整一下,它还是很强大的
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从流量控制、熔断降级、系统自适应保护等多个维度来帮助您保障微服务的稳定性
Sentinel发展史
- 2012 年,Sentinel 诞生,主要功能为入口流量控制。
- 2013-2017 年,Sentinel 在阿里巴巴集团内部迅速发展,成为基础技术模块,覆盖了所有的核心场景。Sentinel 也因此积累了大量的流量归整场景以及生产实践。
- 2018 年,Sentinel 开源,并持续演进。
- 2019 年,Sentinel 朝着多语言扩展的方向不断探索,推出 C++ 原生版本,同时针对 Service Mesh 场景也推出了 Envoy 集群流量控制支持,以解决 Service Mesh 架构下多语言限流的问题。
- 2020 年,推出 Sentinel Go 版本,继续朝着云原生方向演进。
- 2021 年,Sentinel 正在朝着 2.0 云原生高可用决策中心组件进行演进;同时推出了 Sentinel Rust 原生版本。同时我们也在 Rust 社区进行了 Envoy WASM extension 及 eBPF extension 等场景探索。
核心概念
- 资源
- 规则
资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容,例如,由应用程序提供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。
只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源
围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规则。所有规则可以动态实时调整
流量控制
流量控制在网络传输中是一个常用的概念,它用于调整网络包的发送数据。然而,从系统稳定性角度考虑,在处理请求的速度上,也有非常多的讲究。任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。Sentinel 作为一个调配器,可以根据需要把随机的请求调整成合适的形状
流量控制有以下几个角度:
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系;
- 运行指标,例如 QPS、线程池、系统负载等;
- 控制的效果,例如直接限流、冷启动、排队等。
熔断降级
Sentinel
和 Hystrix
的原则是一致的: 当调用链路中某个资源出现不稳定,例如,表现为 timeout
,异常比例升高的时候,则对这个资源的调用进行限制,并让请求快速失败,避免影响到其它的资源,最终产生雪崩的效果。
系统负载保护
Sentinel
同时提供系统维度的自适应保护能力。防止雪崩
,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用
整合Sentinel
有了大概的了解之后,我们发现它很强大,下面我们就整它,同样的为了方便练习,新建一个模块, 引入如下依赖:
<!-- sentinel--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-transport-simple-http</artifactId> <version>1.7.1</version> </dependency> <!-- 配置中心--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> 复制代码
启动类正常建,无需额外注解, 下面新建一个TestController
@RestController public class TestController { } 复制代码
sentinel是有控制台
的, 我们在jar
包里引入了,就是这个com.alibaba.csp
,官方也提供了下载,我们这里直接整进去,启动项目,可以打开控制台瞅一眼, 在这之前我们需要加一下配置
server: port: 8082 spring: application: name: sentinel cloud: # nacos nacos: config: server-addr: 127.0.0.1:8848 file-extension: yml # sentinel sentinel: transport: dashboard: localhost:8080 port: 8719 eager: true # 禁止控制台懒加载 复制代码
这个port
要注意一下,它是客户端和控制台通信的端口,如果被占用了,就会从8719
往后扫描直到未占用的端口,也就是说客户端会采集一些数据发到控制台去展示,好了之后,启动项目,打开localhost:8080
,会发现应用
那一栏多了一个,就是我们刚刚启动的项目
我们点击链路
,发现里面是空的,因为我们还没建api接口,下面新建几个接口测试一下:
@GetMapping("/hello") public String test1() throws InterruptedException { return "hello"; } 复制代码
重新运行一下,发现簇点链路
多了我们新建的/hello
, 然后我们就可以通过控制台,对它做一些规则
操作, 功能很多,什么qps,timeout,流量阀值,排队
等等,大家自己可以取尝试操作一下,就不一一演示了
@SentinelResource
下面给大家讲一个服务回退的用法,类似我们之前讲的hystrix
,这里主要有两种
- 异常回退
@Service public class HelloService { @SentinelResource(value= "hello", fallback = "helloCallback") public String hello() { try { throw new Exception("报错了"); } catch (Exception e) { e.printStackTrace(); } return "hello"; } // 异常回退 -- 触发异常 public String helloCallback(Throwable throwable) { return "这是异常回调 ---> " + throwable.getMessage(); } } 复制代码
- sentinel回退
@Service public class HelloService { @SentinelResource(value= "hello", fallback = "helloCallback", blockHandler = "helloCallback1") public String hello() { // try { // throw new Exception("报错了"); // } catch (Exception e) { // e.printStackTrace(); // } return "hello"; } // 异常回退 -- 触发异常 / (触发规则 如果没有helloCallback1则会回调到该方法) public String helloCallback(Throwable throwable) { return "这是异常回调 ---> " + throwable.getMessage(); } // sentinel回退 / 触发规则 public String helloCallback1(BlockException e) { return "sentinel 回退 ---> " + e.getMessage(); } } 复制代码
持久化配置
细心的小伙伴会发现,我每次重启项目之后,我之前定义的规则都没了,原因是在控制台创建的时候并没有持久化,都是在内存
里的数据,所以重启就没了,下面就整合nacos
配置中心,看一下如何通过配置使用,我们需要引入
<!-- sentinel 动态配置中心--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> <version>1.7.1</version> </dependency> 复制代码
修改配置:
sentinel: transport: dashboard: localhost:8080 port: 8719 eager: true # 禁止控制台懒加载 datasource: ds1: nacos: server-addr: localhost:8848 dataId: sentinel groupId: DEFAULT_GROUP data-type: json rule-type: flow 复制代码
下面,我们就可以在配置中心新建配置了,修改都是实时生效的,新建一个配置dataIdsentinel
,文件类型为json
,这里给大家一个示例
[ { "app":"user-service",// 服务名称 "resource": "/list", //资源名称 "count": 1, //阀值 "grade": 1, //阀值类型,0表示线程数,1表示QPS; "limitApp": "default", //来源应用 "strategy": 0,// 流控模式,0表示直接,1表示关联,2表示链路; "controlBehavior": 0 //流控效果,0表示快速失败,1表示Warm Up,2表示排队等待 } ] 复制代码
结束语
本期到这里就结束了, 总结一下,本节主要讲了什么是Sentinel
, 以及带大家整了一下它的控制台和如何持久化配置,主要是控制台规则的使用,这个要靠大家自己去体会了, 建议大家自己多去尝试 ~
下期预告
在构建微服务的过程中,网关(api gateway)
显得尤为重要,几乎主流的微服务都有网关。之前也给大家讲过了,网关可以帮助我们管理接口,因为大部分对外都是提供的rest
, 我们把网关
作为一个闸口,统一对请求验证,鉴权,错误统一处理,限流,转发,埋点,接口文档
等等, 只要你想到的都可以,下期就带大家认识一下spring cloud大家族的一员 Zuul Gateway
。 关注我,不迷路, 下期不见不散 ~