快捷搜索:

sentinel限流实战

sentinel限流实战

使用场景

限流:我们通常使用TPS对流量来进行描述,限流就是限制服务被调用的并发TPS,从而对系统进行自我保护。

1.项目在上线之前经过性能测试评估,例如服务在 TPS 达到 1w/s 时系统资源利用率飙升,与此同时响应时间急剧增大,那我们就要控制该服务的调用TPS,超过该 TPS 的流量就需要进行干预,可以采取拒绝、排队等策略,实现流量的削峰填谷。

2.开放平台,对接口进行收费,免费用户要控制调用TPS,账户的等级不同,允许调用的TPS也不同

实战

源码参考

https://gitee.com/liuerchong/news-artical

搭建限流服务

参考这篇文章

客户端服务搭建

pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>news-artical</artifactId>
        <groupId>com.liu.news</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>ap-article</artifactId>

    <dependencies>

        <dependency>
            <groupId>com.liu.news</groupId>
            <artifactId>artical-common-db</artifactId>
        </dependency>
        <dependency>
            <groupId>com.liu.news</groupId>
            <artifactId>artical-common-public</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-web-servlet</artifactId>
        </dependency>

    </dependencies>

</project>

配置文件 bootstrap.yml

server:
  port: 9070
spring:
  profiles:
    active: dev
  application:
    name: ap-artical
  main:
    allow-bean-definition-overriding: true
  cloud:
    nacos:
      discovery:
        username: nacos
        password: nacos
        server-addr: 172.17.169.81:8848
        namespace: b561281a-fb95-411e-b75b-cf36bfc90854
        group: ATICAL_CLNEWS_DEV_GROUP
      config:
        server-addr: ${spring.cloud.nacos.discovery.server-addr}
        file-extension: yml
        namespace: ${spring.cloud.nacos.discovery.namespace}
        group: ${spring.cloud.nacos.discovery.group}
    sentinel:
      transport:
        port: 8719 # spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了1个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中
        dashboard: 127.0.0.1:5003
      eager: true
      filter:
        enabled: false
      datasource:
        flow:
          nacos:
            server-addr: localhost:8848
            namespace: ${spring.cloud.nacos.discovery.namespace}
            data-id: ${spring.application.name}-flow-rules
            group-id: ${spring.cloud.nacos.discovery.group}
            data-type: json
            rule-type: flow
        degrade:
          nacos:
            server-addr: localhost:8848
            namespace: ${spring.cloud.nacos.discovery.namespace}
            data-id: ${spring.application.name}-degrade-rules
            group-id: ${spring.cloud.nacos.discovery.group}
            data-type: json
            rule-type: degrade
        system:
          nacos:
            server-addr: localhost:8848
            namespace: ${spring.cloud.nacos.discovery.namespace}
            data-id: ${spring.application.name}-system-rules
            group-id: ${spring.cloud.nacos.discovery.group}
            data-type: json
            rule-type: system
        authority:
          nacos:
            server-addr: localhost:8848
            namespace: ${spring.cloud.nacos.discovery.namespace}
            data-id: ${spring.application.name}-authority-rules
            group-id: ${spring.cloud.nacos.discovery.group}
            data-type: json
            rule-type: authority
        param-flow:
          nacos:
            server-addr: localhost:8848
            namespace: ${spring.cloud.nacos.discovery.namespace}
            data-id: ${spring.application.name}-param-flow-rules
            group-id: ${spring.cloud.nacos.discovery.group}
            data-type: json
            rule-type: param-flow
      management:
        endpoints:
          web:
            exposure:
              include: "*"

application.yml

spring:

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver #数据库驱动包
    url: jdbc:mysql://localhost:3307/artical?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true
    username: root
    password: root
mybatis-plus:
  global-config:
    db-config:
      field-strategy: not_empty
      #驼峰下划线转换
      column-underline: true
      #逻辑删除配置
      logic-delete-value: 0
      logic-not-delete-value: 1
      db-type: mysql
    refresh: false
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false

启动类

package com.liu.news.artical;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * @author lx
 * @version 1.0
 * @description: TODO
 * @date 2021/7/23 13:33
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ApArticleApplication {

    public static void main(String[] args) throws InterruptedException{

        SpringApplication.run(ApArticleApplication.class, args);

    }
}

服务类

参考这篇文章

https://blog..net/liuerchong/article/details/119052304

文章服务搭建

限流服务和客户端服务应该注意的地方

datasource:
  flow:
    nacos:
      server-addr: localhost:8848
      namespace: ${spring.cloud.nacos.discovery.namespace}
      data-id: ${spring.application.name}-flow-rules
      group-id: ${spring.cloud.nacos.discovery.group}
      data-type: json
      rule-type: flow

sentinel持久化的nacos服务器ip 端口 命名空间,组,数据格式,规则 ,data-id命名与客户端配置的地址如上部分必须一一对应,不然不起作用。

限流规则

流控规则

资源名:唯一名称,默认请求路径

阈值类型/单机阈值: QPS (每秒钟的请求数量):当调用该api的QPS达到阈值的时候,进行限流 线程数:当调用该api的线程数达到阈值的时候,进行限流

是否集群:不需要集群

流控效果: 快速失败:直接失败,抛异常 Warm Up:根据codeFactor (冷加载因子,默认3)的值,从阈值 / codeFactor,经过预热时长,才达到设置的QPS阈值 排队等待:匀速排队,让请求以匀速的速度通过,阈值类型必须设置为QPS,则无效

1,流控模式

直接(默认)–> 快速失败

打开sentinel界面,创建流控规则

保存后,持久化到nacos

核对对应的服务器地址,组,命名空间,文件名是否与客户端配置一一对应

限流规则创建完毕

客户端限流配置

在要限流的服务方法上添加 注解@SentinelResource

@SentinelResource(value = "articleList",
        blockHandlerClass = ApArticleBlockHandler.class,
        blockHandler = "blockHandler",
        fallbackClass = ApArticleFallback.class,
        fallback = "fallback")

https://blog..net/liuerchong/article/details/119055193

重启服务进行测试

点击超过两次后对接口进行了限流

经验分享 程序员 职场和发展