516、Java Spring Cloud Alibaba -【Spring Cloud Alibaba Sentinel - 下】 2021.10.11

132 篇文章 0 订阅

1、Sentinel 控制台配合项目实战

1.1 尝试对访问路径限流

1.打开刚才的“簇点链路”菜单,尝试对访问路径限流:

在这里插入图片描述
在这里插入图片描述

资源名:唯一名称,默认请求路径。
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)。

阈值类型

QPS(Query Per Second):每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。
线程数:当调用该api的线程数达到阈值的时候,进行限流。

在这里插入图片描述

流控模式
直接:api达到限流条件时,直接限流。
关联:当关联的资源达到阈值时就限流自己。A接口与B接口关联,当B接口到达阈值,让A接口限流起到保护B接口的作用。 例如支付接口与下单接口,当支付接口到达阈值,让下单接口限流,起到保护支付接口的作用。
链路:只记录指定链路上的流量(指定资源入口资源进来的流量,如果达到阈值,就进行限流)。

 流控效果

快速失败:是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。
Warm up:即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
排队等候:会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。

2.我设置的 QPS的值是1,直接api,快速失败,所以 1秒内去多次请求 /api/member/service:

#### 请求测试
GET http://localhost:10801/api/member/service
Accept: */*
Cache-Control: no-cache

请求得到结果:

Blocked by Sentinel (flow limiting)

事实证明已经被 Sentinel 限制访问,直接快速失败了。

1.2. 尝试对服务资源限流

首先,为了防止多规则的干扰,将刚才设置的 访问路径限流规则 删去。

在这里插入图片描述

1.打开刚才的“簇点链路”菜单,尝试对服务资源限流:
在这里插入图片描述

QPS(Query Per Second):每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。

在这里插入图片描述

2.我设置的 QPS的值是1,直接api,快速失败,所以 1秒内去多次调用 memberService.sayHello():

请求测试
GET http://localhost:10801/api/member/service
Accept: /
Cache-Control: no-cache

请求得到结果:

I am sorry, Member!

结果为什么没有报错?居然能正常返回?仔细的同学会发现都是我设置了降级方法 sayHelloFail() 的功劳:

    @SentinelResource(value = "sayHello", fallback = "sayHelloFail")
    public String sayHello() {
        return "Hello, Member! ";
    }

    public String sayHelloFail() {
        return "I am sorry, Member! ";
    }

1.3 尝试对异常服务熔断

1.打开刚才的“簇点链路”菜单,尝试对异常服务熔断:
在这里插入图片描述

熔断策略
慢调用比例:选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
异常比例:当单位统计时长(statIntervalMs)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 [0.0, 1.0],代表 0% - 100%。
异常数:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

在这里插入图片描述

2.我们对代码进行一点小改造,并且重启项目:

    @RequestMapping("/service")
    public String service(String name) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(400);
        return memberService.sayHello(name);
    }

3.我设置的 最大容忍响应时间是 200ms,比例是 50%,代码中强制延迟 400ms,也就是 100% 超时,并且设置了在单位时间内 5 次请求有 50% 是这种情况才会熔断,所以 1 秒内去超过 5 次请求 /api/member/service:

#### 请求测试
GET http://localhost:10801/api/member/service
Accept: */*
Cache-Control: no-cache

请求得到结果:

Blocked by Sentinel (flow limiting)

事实证明已经被 Sentinel 限制访问,异常服务熔断了。

4.我设置的 熔断时间为 2 秒,在 2 秒后再去请求 2 次 /api/member/service:

#### 请求测试
GET http://localhost:10801/api/member/service
Accept: */*
Cache-Control: no-cache

请求得到结果:

Hello, Member!
Blocked by Sentinel (flow limiting)

结果为什么是这样?不是才请求 2 次吗?而且 2 秒后不是应该放行了吗?因为我代码中强制延迟 400ms,2 秒后的请求还是超时,第一次成功是因为需要统计数据。

Sentinel 经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

5.类似 4.2章节 的情形,如果我把代码中强制延迟 400ms 写在资源服务中:

    @SentinelResource(value = "sayHello", fallback = "sayHelloFail")
    public String sayHello(String name) throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(400);
        return "Hello, Member! " + name;
    }

    public String sayHelloFail(String name) {
        return "I am sorry, Member! " + name;
    }

在这里插入图片描述
一样的设置,一样的请求, 1 秒内去超过 5 次请求 /api/member/service:

#### 请求测试
GET http://localhost:10801/api/member/service
Accept: */*
Cache-Control: no-cache

请求得到结果:

I am sorry, Member!

事实证明已经被 Sentinel 限制访问,异常服务虽然已经被熔断,但是设置了降级方法 sayHelloFail() 还是能正常返回结果。

1.4 尝试对热点参数限流

热点就是经常访问的数据;
比如商品接口的 QPS 限定的是 100,有一天要秒杀,带着秒杀商品 ID 的请求的 QPS 限制在 50,这样还能有 50 的 QPS 用来访问其他的商品;

我们先对代码进行一点小改造,加一个请求参数 name**,并且重启项目**:

@Service
public class MemberService {

    @SentinelResource(value = "sayHello", fallback = "sayHelloFail")
    public String sayHello(String name) {
        return "Hello, Member! " + name;
    }

    public String sayHelloFail(String name) {
        return "I am sorry, Member! " + name;
    }

}

@RestController
@RequestMapping
public class HelloController {

    @Resource
    private MemberService memberService;

    @RequestMapping("/service")
    public String service(String name) {
        return memberService.sayHello(name);
    }

}

2.打开的“热点规则”菜单,新增一个资源名为“sayHello”的热点规则:
在这里插入图片描述

参数索引 设置 0,表示第一个请求参数
单机阈值 设置 10,统计窗口时长 设置 1
参数值 设置 字符串 baicai,限流阈值 设置 1

总的来说,就是同样的请求 /api/member/service?name=xxx, 当参数传 baicai 时,QPS 例外控制为 1,而参数传别的任何值,QPS 控制为 10。

3.尝试 1秒内去多次请求 /api/member/service?name=baicai:

#### 请求测试
GET http://localhost:10801/api/member/service?name=baicai
Accept: */*
Cache-Control: no-cache

请求得到结果:

I am sorry, Member! baicai

4.尝试 1秒内去多次请求 /api/member/service?name=luobo:

#### 请求测试
GET http://localhost:10801/api/member/service?name=luobo
Accept: */*
Cache-Control: no-cache

请求得到结果:

Hello, Member! luobo

事实证明当参数为 baicai 时,QPS 超过 1 就被限制访问,但是设置了降级方法 sayHelloFail() 还是能正常返回结果。

1.5. 尝试黑白名单控制

很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。


在这里插入图片描述
测试结果和以上类似,这里就不做过多阐述了。看到这里,Sentinel 的强大好用是否已经征服你了呢?

2、参考链接

[01] 掘金 - Java Spring Cloud Alibaba Sentinel

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值