庄辉个人网站建设教学,注册公司需要什么条件和材料,wordpress文章自动中文,php做网站用什么软件好1.背景
1.什么是单机限流#xff1f;
小伙伴们或许遇到过下图这样的限流配置 又或者是这样的Nacos动态配置限流规则#xff1a; 以上这些是什么限流#xff1f;没错#xff0c;就是单机限流#xff0c;那么单机限流有什么弊端呢#xff1f;
假设我们集群部署3台机器
小伙伴们或许遇到过下图这样的限流配置 又或者是这样的Nacos动态配置限流规则 以上这些是什么限流没错就是单机限流那么单机限流有什么弊端呢
假设我们集群部署3台机器NodeA/NodeB/NodeC在某时刻同时有25个请求进来假设NodeA收到12个请求NodeB 8个NodeC 5个并且每个单机限流qps10那么这个时候NodeA将会触发限流有两个请求BLOCK掉这是由于可能发生的流量不均导致NodeA节点流量过高导致限流这是因为每个机器都是自己管自己有没有一种方法能够统筹调度呢这就得提到集群限流了 2.什么是集群限流 集群限流就是弄一台Token Server每个客户端机器作为Token Client有请求进来Token Client就会向Token Server拿令牌拿到令牌则不限流反正则限流。其中Token Server可以作为独立运行的项目也可以内嵌式内嵌至每个节点中需将其中一台机器设置为Token Server如果Token Server节点所在机器宕机可以将其他Client节点设置成serversentinel有相关api提供该操作
例如上面的例子集群内有3个节点如果每个节点能承受10的请求那么加起来就是3x1030个请求。也就是说只要qps不超过30个请求都不会触发限流。 2.sentinel实现集群限流
1. 以spring-boot项目构建 sentinel-token-server
pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersion groupIdcom.lee.sentinel.tokenserver/groupIdartifactIdsentinel-token-server/artifactIdversion0.0.1-SNAPSHOT/versionnamesentinel-token-server/namedescriptionDemo project for Spring Boot/descriptionpropertiesjava.version1.8/java.versionspring-boot.version2.3.7.RELEASE/spring-boot.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter/artifactIdexclusionsexclusiongroupIdcom.alibaba.spring/groupIdartifactIdspring-context-support/artifactId/exclusion/exclusions/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId /dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency!--slf4j--dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactId/dependency !--nacos配置中心--dependencygroupIdcom.alibaba.boot/groupIdartifactIdnacos-config-spring-boot-starter/artifactIdversion0.2.12/version!--由于jar包冲突此处排除冲突jar重新导入高版本jar--!--nacos-spring-context-1.1.1.jar需要比spring-context-support-1.0.8.jar更高版本的jar--exclusionsexclusiongroupIdcom.alibaba.spring/groupIdartifactIdspring-context-support/artifactId/exclusion/exclusions/dependency!--重新引入jar包--dependencygroupIdcom.alibaba.spring/groupIdartifactIdspring-context-support/artifactIdversion1.0.11/version/dependency!--sentinel-cluster--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-cluster-server-default/artifactIdversion1.8.5/version/dependency !--sentinel dashboard--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-transport-simple-http/artifactIdversion1.8.5/version/dependency!--sentinel dashboard - nacos 配置动态感知--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactIdversion1.8.5/version/dependency/dependenciesdependencyManagementdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-dependencies/artifactIdversion${spring-boot.version}/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins/build/projectapplication.properties
server.port9009
#应用名称
spring.application.namesentinel-token-server
#nacos config center
nacos.config.server-addr192.168.1.105:8848
ClusterServer启动类 import java.util.HashSet;
import java.util.Set;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;public class ClusterServer {private static final int TOKEN_SERVER_PORT 7777;private static final int IDLE_SECONDS 600;public static void main(String[] args) throws Exception {ClusterTokenServer tokenServer new SentinelDefaultTokenServer();ServerTransportConfig serverConfig new ServerTransportConfig(TOKEN_SERVER_PORT, IDLE_SECONDS); ClusterServerConfigManager.loadGlobalTransportConfig( serverConfig ); //可以设置多个namespaceSetString namespaceSet new HashSetString();namespaceSet.add(user-service); //dataIduser-service-flow-rulesClusterServerConfigManager.loadServerNamespaceSet( namespaceSet ); tokenServer.start();}
}
SpringBoot启动类 基于spring-boot SPI机制初始化限流规则 ClusterTokenInitFunc从
import java.util.List;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.FlowRule;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;public class ClusterTokenInitFunc implements InitFunc {private String remoteAddress 192.168.1.105:8848;// nacos配置中心地址private String groupId SENTINEL_GROUP;private String dataId_postfix -flow-rules;Overridepublic void init() throws Exception {// TODO Auto-generated method stubloadFlowRuleByNacos();}private void loadFlowRuleByNacos() {// TODO Auto-generated method stub// 从Nacos上获取配置进行加载ClusterFlowRuleManager.setPropertySupplier(namespace - {// namespace在ClusterServer.java中已配置String dataId namespace dataId_postfix; // user-service-flow-rules、 coupon-service-flow-rulesReadableDataSourceString, ListFlowRule readableDataSource new NacosDataSource(remoteAddress,groupId, dataId, source - JSON.parseObject(source, new TypeReferenceListFlowRule() {}));return readableDataSource.getProperty();});}}
其中我的Nacos配置dataIduser-service-flow-rules设置如下 [{resource:com.lee.demo.dubbo.demo.user.ISentinelService,grade:1,count:2,clusterMode:true,clusterConfig:{flowId:1001,thresholdType:1,fallbackToLocalWhenFail:true}},{resource:com.lee.demo.dubbo.demo.user.IHelloService,grade:1,count:30,clusterMode:true,clusterConfig:{flowId:1002,thresholdType:1,fallbackToLocalWhenFail:true}}
]
至此sentinel-token-server搭建完成启动服务 2. 配置客户端Token Client
导包 !--nacos配置中心--dependencygroupIdcom.alibaba.boot/groupIdartifactIdnacos-config-spring-boot-starter/artifactIdversion0.2.12/version!--由于jar包冲突此处排除冲突jar重新导入高版本jar--!--nacos-spring-context-1.1.1.jar需要比spring-context-support-1.0.8.jar更高版本的jar--exclusionsexclusiongroupIdcom.alibaba.spring/groupIdartifactIdspring-context-support/artifactId/exclusion/exclusions/dependency!--重新引入jar包--dependencygroupIdcom.alibaba.spring/groupIdartifactIdspring-context-support/artifactIdversion1.0.11/version/dependency!--sentinel-dubbo-adapter --dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-apache-dubbo-adapter/artifactIdversion1.8.5/version/dependency!--sentinel dashboard--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-transport-simple-http/artifactIdversion1.8.5/version/dependency!--sentinel dashboard - nacos 配置动态感知--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactIdversion1.8.5/version/dependency!--sentinel-token-cluster--dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-cluster-client-default/artifactIdversion1.8.5/version/dependency 加载集群流控规则 ClusterFlowRuleInitFunc.java
import java.util.List;import com.alibaba.csp.sentinel.cluster.ClusterStateManager;
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.Converter;
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.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;public class ClusterFlowRuleInitFunc implements InitFunc{private static final String CLUSTER_SERVER_HOST localhost;private static final int CLUSTER_SERVER_PORT 7777;private static final int REQUEST_TIME_OUT 20000;private static final String remoteAddress 192.168.1.105:8848;private static final String groupId SENTINEL_GROUP; private static final String FLOW_POSTFIX-flow-rules;private static final String APP_NAMEuser-service;Overridepublic void init() throws Exception {// TODO Auto-generated method stub//声明为Token ClientClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);//加载集群限流Token Server loadClusterClientConfig(); //加载单机限流规则如果Token Server不可用退化到单机限流initFlowRulesWithDatasource(); }/*** 集群限流规则* */private void loadClusterClientConfig() {ClusterClientAssignConfig assignConfig new ClusterClientAssignConfig();assignConfig.setServerHost(CLUSTER_SERVER_HOST);assignConfig.setServerPort(CLUSTER_SERVER_PORT);ClusterClientConfigManager.applyNewAssignConfig(assignConfig);ClusterClientConfig clientConfig new ClusterClientConfig();clientConfig.setRequestTimeout(REQUEST_TIME_OUT);ClusterClientConfigManager.applyNewConfig(clientConfig);}/*** 单机限流规则* */private void initFlowRulesWithDatasource() { String dataId APP_NAME FLOW_POSTFIX;
// ReadableDataSourceString, ListFlowRule readableDataSource new NacosDataSource(
// remoteAddress, groupId, dataId
// ,source-JSON.parseObject(source,new TypeReferenceListFlowRule() {}));ReadableDataSourceString, ListFlowRule readableDataSource new NacosDataSource(remoteAddress, groupId, dataId, new ConverterString, ListFlowRule() { Overridepublic ListFlowRule convert(String source) {// TODO Auto-generated method stubSystem.out.println(source:source); ListFlowRule rules JSON.parseObject(source,new TypeReferenceListFlowRule() {}); return rules;}}); FlowRuleManager.register2Property(readableDataSource.getProperty());} }
Controller: 至此Token Client配置完成。
接下来启动3个客户端模拟集群 Sentinel-Dashboard上可以看到user-service有三台集群机器 使用jmeter压测工具进行压测 压测结果如下可以看到com.lee.demo.dubbo.demo.user.ISentinelService.testSentinel() 接口的qps一直不会超过6个请求这个峰值是怎么计算的来的呢因为我上面提到的Nacos集群限流配置dataIduser-service-flow-rules中配置com.lee.demo.dubbo.demo.user.ISentinelService的qps2而我们总共有3台机器因此集群限流max qps2x36 至此sentinel上线集群限流demo已完成如有疑问请在评论区评论。