流量控制
- 并发线程数
- QPS
- 资源
- 规则
- Entry->请求
限制规则的核心因素FlowRule
- resoure
- count
- grade
- limitApp
- ControlBehavior
维度
并发线程数
- Hystrix线程池隔离
- Sentinel 并发线程数
QPS(TPS)
策略(流量控制的策略)
-
直接拒绝
-
warm up(冷启动i)
-
匀速排队
通过ControlBehavior属性来控制策略
基于调用关系来做流量控制(维度)
-
FlowRule
-
根据调用方来限流
limitApp -
根据调用链路入口来限流
-
针对具有关系的资源来限流
Sentinel控制台
1、下载
github地址::https://github.com/alibaba/Sentinel/releases
2、启动命令
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.4.jar
配置:
3、配置文件挂载到控制台上
挂载成功
4、Jmeter测试
- 打开Jmeter新建一个Http请求
- 配置线程池
- 配置http请求
- 运行测试,观察控制台可以看见波动
动态限流规则
- config center: zookeeper / apollo / etcd / redis / Consul / Eureka / Nacos
- 规则的感知(Pull,Push)
DataSource(接口)
- pull
- push
Sentinel扩展(InitFunc实现)
原来代码是放在主方法里面的,例如:
package com.chaoxing.springboot_sentinel;
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 org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class SpringBootSentinelApplication {
public static void main(String[] args) {
initFlowRule();
SpringApplication.run(SpringBootSentinelApplication.class, args);
}
/**
*定义限流规则,初始化规则方便使用
*/
private static void initFlowRule(){
List<FlowRule> rules = new ArrayList<>();
FlowRule flowRule = new FlowRule();
//绑定规则名称,针对那个规则设置规则
flowRule.setResource("doTest");
//QPS或者并发数
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//QPS=5
flowRule.setCount(5);
//添加规则
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
}
现在:
1、创建FlowRuleInitFunc 引用InitFunc接口
2、设置Sentinel限流方式
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.init.InitFunc;
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 java.util.ArrayList;
import java.util.List;
/**
* @Author :Kun
* @Date 2022/6/27 15:37
*/
public class FlowRuleInitFunc implements InitFunc {
@Override
/**
*定义限流规则,初始化规则方便使用
*/
public void init() throws Exception {
List<FlowRule> rules = new ArrayList<>();
FlowRule flowRule = new FlowRule();
//绑定规则名称,针对那个规则设置规则
flowRule.setResource("resource_Name");
//QPS或者并发数
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
//QPS=5
flowRule.setCount(5);
//添加规则
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
}
3、在resources下创建META-INF文件夹
4、在META-INF下创建 services文件夹
5、新建接口文件(SPI)进行扩展
文件名:com.alibaba.csp.sentinel.init.InitFunc
6、写入路径
使用Nacos设置限流规则
1、导入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
2、编写方法
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
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 com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.util.ArrayList;
import java.util.List;
/**
* @Author :Kun
* @Date 2022/6/27 15:37
*/
public class FlowRuleInitFunc implements InitFunc {
private final String nacosAddress = "127.0.0.1:8848";
private final String groupId = "SENTINEL_GROUP";
private final String dataId ="SpringBoot-sentinel";
@Override
/**
*定义限流规则,初始化规则方便使用
*/
public void init() throws Exception {
// List<FlowRule> rules = new ArrayList<>();
// FlowRule flowRule = new FlowRule();
// //绑定规则名称,针对那个规则设置规则
// flowRule.setResource("resource_Name");
// //QPS或者并发数
// flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// //QPS=5
// flowRule.setCount(5);
// //添加规则
// rules.add(flowRule);
// FlowRuleManager.loadRules(rules);
//从远程服务器加载规则(Nacos)
ReadableDataSource<String,List<FlowRule>> flowRuleDs =
new NacosDataSource<List<FlowRule>>(nacosAddress,groupId,dataId,
s -> JSON.parseObject(s,new TypeReference<List<FlowRule>>(){}));
FlowRuleManager.register2Property(flowRuleDs.getProperty());
}
}
3、在nacos编写规则
使用集成方式利用nacos编写规则
1、在nacos设置规则
2、在配置文件中编辑
#使用nacos编辑规则方便Sentinel熔断降级机制的使用
spring.cloud.sentinel.datasource.dsl.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.dsl.nacos.data-id=SpringBoot-sentinel
spring.cloud.sentinel.datasource.dsl.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.dsl.nacos.rule-type=flow
spring.cloud.sentinel.datasource.dsl.nacos.data-type=json
spring.cloud.sentinel.datasource.dsl.nacos.username=nacos
spring.cloud.sentinel.datasource.dsl.nacos.password=nacos
3、流控规则显示成功
使用集群的方式设置限流规则
1、集群示意图
2、建立project sentinel-token-sever
3、添加依赖
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.chaoxing.sentinel</groupId>
<artifactId>sentinel-token-sever</artifactId>
<version>1.0-SNAPSHOT</version>
<name>sentinel-token-sever</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-server-default</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.0</version>
</dependency>***
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
4、建立服务类ClusterServer
package com.chaoxing.sentinel;
import com.alibaba.csp.sentinel.cluster.client.ClusterTokenClient;
import com.alibaba.csp.sentinel.cluster.server.ClusterTokenServer;
import com.alibaba.csp.sentinel.cluster.server.SentinelDefaultTokenServer;
import com.alibaba.csp.sentinel.cluster.server.config.ClusterServerConfigManager;
import com.alibaba.csp.sentinel.cluster.server.config.ServerTransportConfig;
import java.util.Collections;
/**
* @Author :Kun
* @Date 2022/6/27 16:38
*/
public class ClusterServer {
public static void main(String[] args) throws Exception {
ClusterTokenServer tokenServer = new SentinelDefaultTokenServer();
//手动载入namespace和ClusterServerConfigManager
//集群限制流服务端通信相关配置
ClusterServerConfigManager.loadGlobalTransportConfig(new ServerTransportConfig().setIdleSeconds(600).setPort(9999));
//加载namespace集合列表
ClusterServerConfigManager.loadServerNamespaceSet(Collections.singleton("APP-Test"));
tokenServer.start();
//Token-client会上报自己的project.name到token-server会根据namespace来统一
}
}
5、建立获取配置类FlowRuleInitFunc
package com.chaoxing.sentinel;
import com.alibaba.csp.sentinel.cluster.flow.rule.ClusterFlowRuleManager;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
import com.alibaba.csp.sentinel.slots.block.flow.ClusterFlowConfig;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.util.List;
/**
* @Author :Kun
* @Date 2022/6/27 15:37
*/
public class FlowRuleInitFunc implements InitFunc {
private final String nacosAddress = "127.0.0.1:8848";
private final String groupId = "SENTINEL_GROUP";
private final String dataId ="-flow-rules";
@Override
/**
*定义限流规则,初始化规则方便使用
*/
public void init() throws Exception {
ClusterFlowRuleManager.setPropertySupplier(namespace->{
ReadableDataSource<String,List<FlowRule>> flowRuleDs =
new NacosDataSource<List<FlowRule>>(nacosAddress,groupId,namespace+dataId,
s -> JSON.parseObject(s,new TypeReference<List<FlowRule>>(){}));
return flowRuleDs.getProperty();
});
}
}
6、添加从nacos获取配置的配置文件
7、添加VM
-Dcsp.sentinel.dashboard.server=127.0.0.1:8080 -Dproject.name=sentinel-token-sever
8、在nacos中配置
9、运行
10.客户端连接
修改FlowRuleInitFunc方法
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientAssignConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource;
import com.alibaba.csp.sentinel.init.InitFunc;
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 com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import java.util.ArrayList;
import java.util.List;
/**
* @Author :Kun
* @Date 2022/6/27 15:37
*/
public class FlowRuleInitFunc implements InitFunc {
private final String nacosAddress = "127.0.0.1:8848";
private final String groupId = "SENTINEL_GROUP";
private final String dataId ="-flow-rules";
private final String clusterServerHost="localhost";
private final int clusterServerPort=9999;
private final int requestTimeOut=20000;
private final String appname = "App-Test";
@Override
/**
*定义限流规则,初始化规则方便使用
*/
public void init() throws Exception {
loadClusterConfig();
registerFlowRule();
}
private void loadClusterConfig(){
ClusterClientAssignConfig assignConfig = new ClusterClientAssignConfig();
assignConfig.setServerHost(clusterServerHost);//放到配置中心
assignConfig.setServerPort(clusterServerPort);
ClusterClientConfigManager.applyNewAssignConfig(assignConfig);
ClusterClientConfig clientConfig = new ClusterClientConfig();
clientConfig.setRequestTimeout(requestTimeOut);//放到配置中心
ClusterClientConfigManager.applyNewConfig(clientConfig);
}
private void registerFlowRule(){
ReadableDataSource<String,List<FlowRule>> flowRuleDs =
new NacosDataSource<List<FlowRule>>(nacosAddress,groupId,appname+dataId,
s -> JSON.parseObject(s,new TypeReference<List<FlowRule>>(){}));
FlowRuleManager.register2Property(flowRuleDs.getProperty());
}
}
11、设置主方法为客户端
package com.chaoxing.springboot_sentinel;
import com.alibaba.csp.sentinel.cluster.ClusterStateManager;
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 org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.ArrayList;
import java.util.List;
@SpringBootApplication
public class SpringBootSentinelApplication {
public static void main(String[] args) {
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);
SpringApplication.run(SpringBootSentinelApplication.class, args);
}
}
12 调试vm options
-Dsever.port=8888 -Dproject.name=App-Test -Dcsp.sentinel.dashboard.server=127.0.0.1:8080
13 确定配置文件可用
14 运行测试
连接成功