Sentinel

Sentinel 是一个全面的流量控制组件,用于保护服务的稳定性。它提供了丰富的流量控制策略,如秒杀控制、熔断降级、实时监控等。Sentinel 与 Hystrix 相比,具有更多应用场景和更完善的生态。本文详细介绍了Sentinel的使用,包括通过Dashboard控制台设置规则,自定义流控响应,以及熔断和降级的区别和联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、什么是Sentinel?

二、我们为什么使用Sentinel?

三、Sentinel和Hystrix有什么区别

 四、如何使用Sentinel

1、Dashboard控制台

 2、Sentinel基本使用(设置规则的时候记得要重新设置,因为是保存在内存中)

3、自定义流控相应(当不满足规则时返回我们定义的数据)

4、熔断、降级

5、 降级和熔断的关系

①什么是降级?

②什么是熔断?

③熔断和降级的关系

6、网关流量控制


一、什么是Sentinel?

Sentinel以流量为切入点,从流量控制、流量路由、熔断降级、系统自适应过载保护、热点流量防护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:

  • 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Apache Dubbo、gRPC、Quarkus 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。同时 Sentinel 提供 Java/Go/C++ 等多语言的原生实现。
  • 完善的 SPI 扩展机制:Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

二、我们为什么使用Sentinel?

【大流量请求】:在秒杀和大促开始前,如果准备不充分,瞬间大量请求会造成服务提供者的不可用。
【硬件故障】:可能为硬件损坏造成的服务器主机宕机, 网络硬件故障造成的服务提供者的不可访问。
【缓存击穿】:一般发生在缓存应用重启, 缓存失效时高并发,所有缓存被清空时,以及短时间内大量缓存失效时。大量的缓存不命中, 使请求直击后端,造成服务提供者超负荷运行,引起服务不可用。
保持系统的稳定性。

三、Sentinel和Hystrix有什么区别

在这里插入图片描述

四、如何使用Sentinel

1、Dashboard控制台

Sentinel 可以简单的分为 Sentinel 核心库和 Dashboard控制台。核心库不依赖 Dashboard,但是结合 Dashboard 可以取得最好的效果。

访问https://github.com/alibaba/Sentinel,把代码clone下来,通过mvn clean pakcage打包,

运行命令,

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

访问控制台,如果发现下面的界面就说明运行成功了

 2、Sentinel基本使用(设置规则的时候记得要重新设置,因为是保存在内存中)

我们说的资源,可以是任何东西,服务,服务里的方法,甚至是一段代码。使用 Sentinel 来进行资源保护,主要分为几个步骤:

  1. 定义资源
  2. 定义规则
  3. 检验规则是否生效

方法一(基于try-catch定义资源):

package com.example.demo.gulimall34;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

@RestController
@Slf4j
public class SentinelController {

//①定义资源
    private static final String RESOURCE_NAME = "hello";

    @RequestMapping(value = "/hello")
    public String hello() {
        Entry entry = null;
        try {
            entry = SphU.entry(RESOURCE_NAME);
            // 被保护的业务逻辑
            //int i=1/0;
            String str = "hello world";
            log.info("=====" + str);
            return str;
        } catch (BlockException ex) {
            // 资源访问阻止,被限流或被降级
            //进行相应的处理操作
            log.info("block!");
        } catch (Exception ex) {
            // 若需要配置降级规则,需要通过这种方式记录业务异常
            Tracer.traceEntry(ex, entry);
        } finally {
            if (entry != null) {
                entry.exit();
            }
        }
        return null;
    }

//定义规则
    /**
     * 设置流控规则
     */
    @PostConstruct
    public static void initFlowRules() {
        List<FlowRule> flowRules = new ArrayList<>();
        FlowRule flowRule = new FlowRule();
        // 设置受保护的资源
        flowRule.setResource(RESOURCE_NAME);
        // 设置流控规则 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 设置受保护的资源阈值
        // Set limit QPS to 20.
        flowRule.setCount(1);
        flowRules.add(flowRule);
        // 加载配置好的规则
        FlowRuleManager.loadRules(flowRules);
    }
}

方法二(基于注解来定义资源):

// 原本的业务方法.
    @SentinelResource(value = "findOrderByUserId",
            blockHandler = "handleException", // 指定触发限流等规则时执行的方法名
            fallback = "fallback" // 指定fallback降级执行的方法名
            //blockHandlerClass = ExceptionUtil.class, // 指定blockHandler函数的所在类,如果在当前类可以忽略
            //fallbackClass = ExceptionUtil.class,  指定fallback函数所在类,如果在当前类可以忽略
    )
    @RequestMapping(value = "/user/findOrderByUserId/{id}")
    public String findOrderByUserId(@PathVariable("id") Integer id) {
        throw new RuntimeException("getUserById command failed");
    }

    // blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用
    public String handleException(@PathVariable("id") Integer id, BlockException ex) {
        return new String("admin");
    }

    // fallback 函数,原方法调用被降级的时候调用
    public String fallback(@PathVariable("id") Integer id, Throwable e) {
        return new String("admin1");
    }

2)在控制台定义规则

③、进行访问,检验规则是否生效

 我们设置的QPS是1,所以第二次访问就是空白

3、自定义流控相应(当不满足规则时返回我们定义的数据)

①导入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

 ②暴露终端的位置

management.endpoints.web.exposure.include=*

③写配置文件


//自定义限流,降级异常处理对象
@Slf4j
@Configuration
public class SekillSentinelConfiguration{
    public SekillSentinelConfiguration(){
        WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
            @Override
            public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
                httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
                httpServletResponse.getWriter().write("记得要设置返回值的编码哦");
            }
        });
    }
}

④定义流控规则

⑤验证

4、熔断、降级

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 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。

远程调用的设置:

①设置配置信息,开启熔断配置

spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080
spring.cloud.sentinel.transport.clientIp=127.0.0.1
feign.sentinel.enabled=true

②开启注册中心,调用者服务,被调用者服务;调用远程;如果远程调用失败,就会熔断

@Slf4j
@RestController
@RequestMapping("product/spuinfo")
public class SpuInfoController {
//    验证sentinel的使用
    @GetMapping("/getSentinel")
    public R getSentinel(){
        List<Long> list=new ArrayList<>();
        list.add(1L);
        list.add(11L);
        R skuHasStock = wareFeignService.getSentinel(list);
        return skuHasStock;
    }

}

@Component
@FeignClient(value = "guli-ware",fallback = WareFeignServiceImpl.class)
public interface WareFeignService {
    @PostMapping(value = "ware/waresku/hasStock")
    R getSkuHasStock(@RequestBody List<Long> SkuIds);

    @RequestMapping(value = "ware/waresku/sentinel")
    R getSentinel(@RequestBody List<Long> SkuIds);

}

@Slf4j
@Component
public class WareFeignServiceImpl implements WareFeignService {
    @Override
    public R getSkuHasStock(List<Long> SkuIds) {
        log.info("到底能不能行啊");
        return R.error().setData("我要使用sentinel的熔断机制啦");
    }

    @Override
    public R getSentinel(List<Long> SkuIds) {
        log.info("到底能不能行啊");
        return R.error().setData("我要使用sentinel的熔断机制啦");
    }
}
@Slf4j
@RestController
@RequestMapping("product/spuinfo")
public class SpuInfoController {

//    验证sentinel的使用
    @GetMapping("/getSentinel")
    public R getSentinel(){
        List<Long> list=new ArrayList<>();
        list.add(1L);
        list.add(11L);
        R skuHasStock = wareFeignService.getSentinel(list);
        return skuHasStock;
    }

}

③自定义降级


//自定义限流,降级异常处理对象
@Slf4j
@Configuration
public class SekillSentinelConfiguration{
    public SekillSentinelConfiguration(){
        WebCallbackManager.setUrlBlockHandler(new UrlBlockHandler() {
            @Override
            public void blocked(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws IOException {
                httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8");
                httpServletResponse.getWriter().write("记得要设置返回值的编码哦");
            }
        });
    }
}

5、 降级和熔断的关系

①什么是降级?

降级主要有三种方式:超时、不可用、限流

②什么是熔断?

熔断很好理解,就是一个断开的过程;

熔断就像是家里的保险丝一样,当电流达到一定条件时,比如保险丝能承受的电流是5A,如果你的电流达到了6A,因为保险丝承受不了这么高的电流,保险丝就会融化,这时候电路就会断开,起到了保护电器的作用;

在微服务里面也是一样,当下游的服务因为某种原因突然变得不可用或响应过慢,上游服务为了保证自己整体服务的可用性,不再继续调用目标服务,直接返回,快速释放资源。如果目标服务情况好转则恢复调用;

③熔断和降级的关系

降级和熔断其实就是服务安全中的2个不同的流程,在服务发生故障时,肯定是先断开(熔断)与服务的连接,然后在执行降级逻辑;

6、网关流量控制

。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值