Day11-SpringCloud alibaba服务降级熔断框架Sentinel


俩贼能熬夜的人!! -
—-2022.1.7 3:00:00
[toc]
Sentinel介绍及下载安装
Sentinel 是什么?
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。
Sentinel 具有以下特征:
丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
官网:这里

下载安装可视端
启动
http://localhost:8080 账号密码为 sentinel 启动命令为
java -jar jar包名
创建项目
pom.xml<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel-datasource-nacos 后续做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--openfeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>yaml
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery: # http://1.116.182.96:8888/files
server-addr: localhost:8848 #Nacos服务注册中心地址
sentinel:
transport:
dashboard: localhost:8080 #配置Sentinel dashboard地址
port: 8719
datasource:
ds1:
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
management:
endpoints:
web:
exposure:
include: '*'
feign:
sentinel:
enabled: true # 激活Sentinel对Feign的支持
主启动类
public class MainApp8401
{
public static void main(String[] args) {
SpringApplication.run(MainApp8401.class, args);
}
}Controller测试类package com.atguigu.springcloud.alibaba.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
/**
* @auther zzyy
* @create 2020-02-24 16:26
*/
public class FlowLimitController
{
public String testA()
{
return "------testA";
}
public String testB()
{
log.info(Thread.currentThread().getName()+"\t"+"...testB");
return "------testB";
}
public String testD()
{
// try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
// log.info("testD 测试RT");
log.info("testD 异常比例");
int age = 10/0;
return "------testD";
}
public String testE()
{
log.info("testE 测试异常数");
int age = 10/0;
return "------testE 测试异常数";
}
public String testHotKey( String p1,
String p2)
{
//int age = 10/0;
return "------testHotKey";
}
public String deal_testHotKey (String p1, String p2, BlockException exception)
{
return "------deal_testHotKey,o(╥﹏╥)o"; //sentinel系统默认的提示:Blocked by Sentinel (flow limiting)
}
}访问
http://localhost:8401/testB看看控制台实时监控

Sentinel流控规则


流控模式—–直接


每秒三下触发默认限流规则 抛出异常
流控模式—–关联

测试:

PostMan中新建多线程集合组

后台运行 /testB 前台访问 /testA
效果: (被限流)

流控模式—–链路

Sentinel降级规则
Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级,请使用最新版本以更好地利用熔断降级的能力。支持半开了
熔断策略
Sentinel 提供以下几种熔断策略:
- 慢调用比例 (
SLOW_REQUEST_RATIO):选择以慢调用比例作为阈值,需要设置允许的慢调用RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。- 异常比例 (
ERROR_RATIO):当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0],代表 0% - 100%。- 异常数 (
ERROR_COUNT):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
Sentinel热点规则
返回自定义异常显示
|
设定热点规则


关于该资源内部出错
@SentinelResource处理的是Sentinel控制台配置的违规情况,有blockHandler方法配置的兜底处理;
RuntimeExceptionint age = 10/0,这个是java运行时报出的运行时异常RunTimeException,@SentinelResource不管
总结
@SentinelResource主管配置出错,运行出错该走异常走异常
Sentinel系统规则(了解即可)

@SentinelResource
关键属性:
value:资源名称,必需项(不能为空)fallback:fallback函数名称,可选项,用于在抛出异常的时候提供 fallback处理逻辑。fallback函数可以针对所有类型的异常(除了exceptionsToIgnore里面排除掉的异常类型)进行处理。fallback函数签名和位置要求: 返回值类型必须与原函数返回值类型一致;方法参数列表需要和原函数一致,或者可以额外多一个 Throwable类型的参数用于接收对应的异常。
public CommonResult byUrl()
{
int age = 10/0;
return new CommonResult(200,"按url限流测试OK",new Payment(2020L,"serial002"));
}
public CommonResult runTimeException(Throwable exception) //这里不能用Exception
{
return new CommonResult(666,exception.getClass().getCanonicalName()+"\t 运行时异常");
}blockHandler:实现处理函数,该函数的传参必须与资源点的传参一样,并且最后加上BlockException异常参数;同时,返回类型也必须一样。
public CommonResult byResource()
{
return new CommonResult(200,"按资源名称限流测试OK",new Payment(2020L,"serial001"));
}
public CommonResult handleException(BlockException exception)
{
return new CommonResult(444,exception.getClass().getCanonicalName()+"\t 服务不可用");
}blockHandlerClass: 自定义限流处理类fallbackClass: 自定义异常类
同时启用blockHander 和 fallback
给出结论: 单次运行异常走 fallback的处理 方法 触发QPS走blockHander的处理方法
整合Ribbon+openFeign+fallback实现服务熔断
客户端引入依赖
<!--SpringCloud openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--SpringCloud ailibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud ailibaba sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>主启动类
public class OrderNacosMain84
{
public static void main(String[] args) {
SpringApplication.run(OrderNacosMain84.class, args);
}
}配置RestTemplate 负载均衡
public class ApplicationContextConfig
{
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
public class ApplicationContextConfig
{
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}Controller测试//测试RestTemplate
public String SERVICE_URL;
public CommonResult<Payment> paymentSQ2( Long id)
{
return restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class);
}


可以看见是轮询访问服务端
//测试OpenFeign
//==================OpenFeign
private PaymentService paymentService;
public CommonResult<Payment> paymentSQL( Long id)
{
return paymentService.paymentSQL(id);
}
=============================================================================
//service
public interface PaymentService
{
public CommonResult<Payment> paymentSQL( Long id);
}
这里就不截图了 同样效果
实现熔断
//@SentinelResource(value = "fallback") //没有配置
//@SentinelResource(value = "fallback",fallback = "handlerFallback") //fallback只负责业务异常
//@SentinelResource(value = "fallback",blockHandler = "blockHandler") //blockHandler只负责sentinel控制台配置违规
public CommonResult<Payment> fallback( Long id)
{
CommonResult<Payment> result = restTemplate.getForObject(SERVICE_URL + "/paymentSQL/"+id,CommonResult.class,id);
if (id == 4) {
throw new IllegalArgumentException ("IllegalArgumentException,非法参数异常....");
}else if (result.getData() == null) {
throw new NullPointerException ("NullPointerException,该ID没有对应记录,空指针异常");
}
return result;
}
//本例是fallback
public CommonResult handlerFallback( Long id,Throwable e) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(444,"兜底异常handlerFallback,exception内容 "+e.getMessage(),payment);
}
//本例是blockHandler
public CommonResult blockHandler( Long id,BlockException blockException) {
Payment payment = new Payment(id,"null");
return new CommonResult<>(445,"blockHandler-sentinel限流,无此流水: blockException "+blockException.getMessage(),payment);
}关闭远程服务试试

持久化配置
引出: 一旦重启引用 sentinel配置规则会消失

实现步骤
<!--SpringCloud ailibaba sentinel-datasource-nacos --> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency>
+ yaml
```yaml
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
server-addr: IP:8848 #Nacos服务注册中心地址
sentinel:
transport:
dashboard: localhost:8080 #配置Sentinel dashboard地址
port: 8719
datasource:
ds1:
nacos:
server-addr: IP:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow在Nacos可视化面板添加规则
resource:资源名称;
limitApp:来源应用;
grade:阈值类型,0表示线程数,1表示QPS;
count:单机阈值;
strategy:流控模式,0表示直接,1表示关联,2表示链路;
controlBehavior:流控效果,0表示快速失败,1表示Warm Up,2表示排队等待;
clusterMode:是否集群。
[
{
"resource": "/rateLimit/byUrl",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]


成功!







