Alibaba-Sentinel简单入门

1、简介

项目地址:https://github.com/alibaba/Sentinel
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制熔断降级系统负载保护等多个维度保护服务的稳定性。

Sentinel 具有以下特征:
  1. 丰富的应用场景:Sentinel 承接了阿里巴巴近10 年的双十一大促流量的核心场
    景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集
    群流量控制、实时熔断下游不可用应用等。
  2. 完备的实时监控:Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入
    应用的单台机器秒级数据,甚至500 台以下规模的集群的汇总运行情况。
  3. 广泛的开源生态:Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如
    与Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配
    置即可快速地接入Sentinel。
  4. 完善的SPI 扩展点:Sentinel 提供简单易用、完善的SPI 扩展接口。您可以通过
    实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。
Sentinel 分为两个部分:
  • 核心库(Java 客户端)不依赖任何框架/库,能够运行于所有Java 运行时环境,同时
    对Dubbo / Spring Cloud 等框架也有较好的支持。
  • 控制台(Dashboard)基于Spring Boot 开发,打包后可以直接运行,不需要额外的
    Tomcat 等应用容器。
Sentinel 基本概念
  1. 资源
    资源是Sentinel 的关键概念。它可以是Java 应用程序中的任何内容,例如,由应用程序提
    供的服务,或由应用程序调用的其它应用提供的服务,甚至可以是一段代码。在接下来的文
    档中,我们都会用资源来描述代码块。
    只要通过Sentinel API 定义的代码,就是资源,能够被Sentinel 保护起来。大部分情况下,
    可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。
  2. 规则
    围绕资源的实时状态设定的规则,可以包括流量控制规则、熔断降级规则以及系统保护规
    则。所有规则可以动态实时调整。

2、Hystrix 与Sentinel 比较

在这里插入图片描述

SpringBoot整合Sentinel

1.添加依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

2.下载Sentinel控制台(需要跟自己的依赖版本对应)
下载

3.配置控制台地址信息

sentinel:
      enabled: true  # 是否开启。默认为 true 开启
      eager: true   # 是否饥饿加载。默认为 false 关闭
      transport:
        port: 8719  # 假如被占用了会自动从8719开始依次+1扫描。直至找到未被占用的端口,默认8719
        dashboard: localhost:8080 # 指定控制台服务的地址
        clientIp: 127.0.0.1
      filter:
        url-patterns: /**

4.启动控制台端口要跟服务中配置的一样

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

5.启动控制台后访问服务的api
流控规则默认是保存在内存中 重启失效
在这里插入图片描述
5.根据访问请求每秒限流快速失败
再次频繁访问Blocked by Sentinel (flow limiting)
在这里插入图片描述
实时监控"汇总资源信息 引入依赖即可

    <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
        </dependency>

在这里插入图片描述
自定义阻塞返回

package cn.cloud.xmall.seckil.config;

import cn.cloud.xmall.common.exception.BizCodeEnum;
import cn.cloud.xmall.common.utils.R;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.fastjson.JSON;

import org.springframework.context.annotation.Configuration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @Description: 自定义阻塞返回方法
 **/

@Configuration
public class XmallSeckillSentinelConfig implements BlockExceptionHandler {

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
        R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(),BizCodeEnum.TO_MANY_REQUEST.getMessage());
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        response.getWriter().write(JSON.toJSONString(error));
    }


}

在这里插入图片描述

流控模式

  1. 基于调用关系的流量控制
    调用关系包括调用方、被调用方;一个方法又可能会调用其它方法,形成一个调用链路的层次关系。Sentinel 通过 NodeSelectorSlot 建立不同资源间的调用的关系,并且通过 ClusterBuilderSlot 记录每个资源的实时统计信息。
    有了调用链路的统计信息,我们可以衍生出多种流量控制手段。

  2. 根据调用方限流
    ContextUtil.enter(resourceName, origin) 方法中的 origin 参数标明了调用方身份。这些信息会在 ClusterBuilderSlot 中被统计。可通过以下命令来展示不同的调用方对同一个资源的调用数据:
    curl http://localhost:8719/origin?id=nodeA

  3. 根据调用链路入口限流:链路限流
    NodeSelectorSlot 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 machine-root 的虚拟节点,调用链的入口都是这个虚节点的子节点。
    一棵典型的调用树如下图所示:

               machine-root
                 /       \
                /         \
          Entrance1     Entrance2
             /             \
            /               \
    

    DefaultNode(nodeA) DefaultNode(nodeA)上图中来自入口 Entrance1 和 Entrance2 的请求都调用到了资源 NodeA,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 strategy 为 RuleConstant.STRATEGY_CHAIN,同时设置 refResource 为 Entrance1 来表示只有从入口 Entrance1 的调用才会记录到 NodeA 的限流统计当中,而不关心经 Entrance2 到来的调用。
    调用链的入口(上下文)是通过 API 方法 ContextUtil.enter(contextName) 定义的,其中 contextName 即对应调用链路入口名称。

  4. 具有关系的资源流量控制:关联流量控制
    当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,read_db 和 write_db 这两个资源分别代表数据库读写,我们可以给 read_db 设置限流规则来达到写优先的目的:设置 strategy 为 RuleConstant.STRATEGY_RELATE 同时设置 refResource 为 write_db。这样当写库操作过于频繁时,读数据的请求会被限流。

熔断降级

1.开启Sentinel对Feign的支持

feign:
  sentinel:
    enabled: true  #开启支持sentinel

开启后可以在控制台监控到远程调用
在这里插入图片描述
1.添加远程调用失败回调(调用方 熔断保护)
超大流量的时候必须牺牲一些远程服务,远程服务指定降级策略,提供方是在运行,但是不运行自己 的业务逻辑,返回的是默认的熔断数据,限流后的数据

/**
 *  fallback远程调用失败回调
 */
@FeignClient(value = "xmall-seckil",fallback = SeckillFeignServiceFallBack.class)
@Component
public class SeckillFeignServiceFallBack implements SeckillFeignService {
    @Override
    public R getSkuSeckilInfo(Long skuId) {
        return R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(),BizCodeEnum.TO_MANY_REQUEST.getMessage());
    }
}

哪怕远程服务宕机 也不会出现服务崩溃现象

2.被调用方熔断保护

feign:
  sentinel:
    enabled: true  #开启支持sentinel

调用方手动指定降级策略,远程服务被降级处理默认触发熔断回调方法
在这里插入图片描述
自定义受保护的资源
基于代码

try(Entry entry = SphU.entry("SeckillSkus")){
     //业务逻辑
     Set<String> keys = redisTemplate.keys(SESSION__CACHE_PREFIX + "*");
 }catch (BlockException e){
     log.error("资源被限流,{}",e.getMessage());
 }

在这里插入图片描述

2022-04-16 23:04:51.433 ERROR 63008 --- [io-25000-exec-4] c.c.x.s.service.impl.SeckillServiceImpl  : 资源被限流,null
2022-04-16 23:04:51.669  INFO 63008 --- [io-25000-exec-9] c.c.x.s.controller.SeckillController     : getCurrentSeckillSkus正在执行

基于注解
@SentinelResource(value = “SeckillSkus@Resource”)
添加在方法上

可以指定被流控之后的降级处理方法 是针对指定方法被降级时候触发

@SentinelResource(value = "SeckillSkus@Resource",blockHandler = "blockHandler")

定义限流方法(返回值参数需要一致)

  public List<SeckillSkuRedisTo> blockHandler(BlockException e) {
        log.error("SentinelResource被限流");
        return null;
    }
2022-04-16 23:19:42.446 ERROR 37392 --- [io-25000-exec-2] c.c.x.s.service.impl.SeckillServiceImpl  : SentinelResource被限流
2022-04-16 23:19:42.525  INFO 37392 --- [io-25000-exec-4] c.c.x.s.controller.SeckillController     : getCurrentSeckillSkus正在执行

fallback方法 是所有异常降级
可以写在同一个方法,也可以写在别的类里 写在别的类里必须是静态的且指定 类.class

Sentinel 网关流控

在这里插入图片描述
在网关层面引入依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值