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
重启服务进行测试
点击超过两次后对接口进行了限流