Sentinel组件限流降级

官网:

home | Sentinel

文档不是很全, 关于nacos的配置中心的使用完全没有

常见的限流算法

  • 静态窗口限流: 即规定1秒内只能固定处理多少请求
  • 动态窗口限流: 同样是规定1秒内处理多少请求, 但是统计方式与第一个不同, 比如2.5秒则是统计1.5秒到现在的请求数
  • 漏桶限流: 进来可以大流量接收, 处理则是匀速处理
  • 令牌桶算法: 漏桶放的是请求, 令牌桶则是放的令牌, 匀速生成令牌, 只有获取令牌的请求才能处理
  • 令牌大闸: 比如车票, 最开始的数量是固定的, 一旦产生了足够的令牌就不再产生了

使用方法

如果是单机的SpringBoot可以使用sentinel官方的文档:

quick-start | Sentinel

如果是SpringCloud可以参考SpringCloudAlibaba的官方文档:

Sentinel · alibaba/spring-cloud-alibaba Wiki · GitHub

代码实现

添加pom依赖:

<!-- 限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

限流方法处理:

注意降级的方法的入参和返回结果都需要保持一致

/**
     * 降级方法,需包含限流方法的所有参数和BlockException参数
     * @param req
     * @param e
     */
    public void doConfirmBlock(ConfirmOrderDoReq req, BlockException e) {
        LOG.info("购票请求被限流:{}", req);
        throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_FLOW_EXCEPTION);
    }

    @SentinelResource(value = "doConfirm", blockHandler = "doConfirmBlock")
    public void doConfirm(ConfirmOrderDoReq req) {
        //do business....
    }

在main函数添加规则:

@SpringBootApplication
@ComponentScan("com.louye")
@MapperScan("com.louye.train.*.mapper")
@EnableFeignClients("com.louye.train.business.feign")
@EnableCaching
public class BusinessApplication {
    private static final Logger LOG = LoggerFactory.getLogger(BusinessApplication.class);

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(BusinessApplication.class);
        Environment env = app.run(args).getEnvironment();
        LOG.info("启动成功!!");
        LOG.info("地址: \thttp://127.0.0.1:{}{}/hello", env.getProperty("server.port"), env.getProperty("server.servlet.context-path"));

        // 限流规则(这里才是主要, 如果后续引入了sentinel控制台, 则可以直接在控制台进行规则的控制, 不需要代码形式定义限流规则)
        initFlowRules();
        LOG.info("已定义限流规则");
    }

    /**
     * 定义限流规则
     */
    private static void initFlowRules(){
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule();
        rule.setResource("doConfirm");// 资源名需要跟自己添加注解的地方的方法名一致
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(1);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }

}

搭建控台监控流量

参考: dashboard | Sentinel

使用官方jar包

下载指定版本后, 启动:

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

根据官方文档: 初始用户名: sentinel, 密码: sentinel

访问启动的端口即可: http://localhost:8080/

代码中需要增加的配置:

# sentinel
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=localhost:8080

控制台进行限流规则的控制:

但是控制台这样定义的规则是保存在应用内存内部的, 应用一旦重启就没有了, 需要考虑规则的持久化

使用Docker构建镜像

官方目前还没有提供Docker镜像,可以根据需要自己构建镜像

参考博客:

【Mac M1+】Docker 安装 Sentinel - 掘金

下载jar包:https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar

创建sentinel-dashboard-1.8.6目录, 将jar包下载到当前文件夹下,并且编写Dockerfile文件:

FROM openjdk:8

MAINTAINER louye clf1256233771@gmail.com

WORKDIR /cloud-sentinel

# 下载的 jar 包和 Dockerfile 在同一目录下
ARG JAR_FILE=./sentinel-dashboard-1.8.6.jar

COPY ${JAR_FILE} cloud-sentinel.jar

EXPOSE 8080

ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms128m -Xmx256m -Dserver.port=8080 -Djava.security.egd=file:/dev/./urandom"

CMD java $JAVA_OPTS -jar cloud-sentinel.jar

构建镜像:

docker build -t sentinel:1.8.6 .

启动镜像:

 docker run --name sentinel_1.8.6 --platform linux/arm64 -p 8080:8080 -d sentinel:1.8.6

使用nacos持久化sentinel的规则配置

添加依赖

<!-- sentinel + nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

添加配置到bootstrap.properties:

# sentinel + nacos
spring.cloud.sentinel.datasource.flow.nacos.serverAddr=127.0.0.1:8848
spring.cloud.sentinel.datasource.flow.nacos.namespace=train
spring.cloud.sentinel.datasource.flow.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.flow.nacos.dataId=sentinel-business-flow
spring.cloud.sentinel.datasource.flow.nacos.ruleType=flow

在nacos中配置sentinel的规则sentinel-business-flow, 类型选择json:

[
  {
    "resource": "doConfirm",
    "limitApp": "default",
    "grade": 1,
    "count": 100,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "confirmOrderDo",
    "limitApp": "default",
    "grade": 1,
    "count": 4,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "hello",
    "limitApp": "default",
    "grade": 1,
    "count": 10,
    "strategy": 0,
    "controlBehavior": 1,
    "warmUpPeriodSec": 2,
    "clusterMode": false
  }
]
  • resource: 资源名, 添加注解@SentinelResource时定义的
  • limitApp: 针对来源
  • grade: 0: 并发线程数, 1: QPS
  • count: 单机阈值
  • strategy: 流控模式, 0: 直接, 1: 关联, 2: 链路
  • controlBehavior: 流控效果, 0: 快速失败, 1: warm up(预热用于加载数据), 2: 排队等待
  • clusterMode: 是否集群

配置后查看sentinel控制台就可以看到对应的限流规则:

不同限流的概念

  • 关联限流: strategy=1, 在下单和支付的场景中, 这两个操作是不同的两个接口, 可能存在某些原因支付处理速度慢需要限流, 所以关联着下单的接口也会自动受到限流
  • 链路限流: strategy=2, 在两个接口调用同一个Service的方法时, 我们只想对某一个方法的某个接口进行限流,但是并不影响另一个, 采用链路就可以只对某个链路的请求进行限制

熔断配置

场景, 服务A调用服务B, 这时候可能服务B处理很慢或者B服务出现异常, 熔断则直接不对服务B进行访问了然后继续往后走. 但是原有的调用逻辑怎么处理就需要我们补充备用方案.

引入基本依赖:

<!-- 限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- sentinel + nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

bootstrap.properties添加配置:

# sentinel
spring.cloud.sentinel.transport.port=8719
spring.cloud.sentinel.transport.dashboard=localhost:8080
# sentinel + nacos, degrade这个名字可以自定义
spring.cloud.sentinel.datasource.degrade.nacos.serverAddr=127.0.0.1:8848
spring.cloud.sentinel.datasource.degrade.nacos.namespace=train
spring.cloud.sentinel.datasource.degrade.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.degrade.nacos.dataId=sentinel-batch-degrade
spring.cloud.sentinel.datasource.degrade.nacos.ruleType=degrade

# sentinel 默认不监控feign, 需要配置才能监控feign
feign.sentinel.enabled=true
# 上面改成true后, 启动会报注入失败, 需要改成懒加载
spring.cloud.openfeign.lazy-attributes-resolution=true

nacos中配置降级规则:

[{
  "resource": "GET:http://business/business/hello",
  "grade": 0,
  "count": 201,
  "timeWindow": 11,
  "minRequestAmount": 6,
  "statIntervalMs": 1000,
  "slowRatioThreshold": 0.3
}]

对应的展示:

  • resource: 资源名
  • grade: 熔断策略
  • count: 最大RT(响应时间), 超过这个时长则是慢调用
  • timeWindow: 熔断时长
  • minRequestAmount: 最小请求数
  • statIntervalMs: 统计时长
  • slowRatioThreshold: 比例阈值

降级处理配置:

编写fallback的方法实现:

@Component
public class BusinessFeignFallback implements BusinessFeign {
    @Override
    public String hello() {
        return "Fallback";
    }
}

配置Feign, 添加熔断后的处理器:

@FeignClient(value = "business", fallback = BusinessFeignFallback.class)
public interface BusinessFeign {
    @GetMapping("/business/hello")
    String hello();
}

热点参数限流

Sentinel 热点参数限流原理 - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值