官网地址
sentinel官网: https://github.com/alibaba/Sentinel/wiki/主页
sentinel 下载地址: https://github.com/alibaba/Sentinel/releases
nacos官网: https://nacos.io/zh-cn/docs/deployment.html
nacos下载地址: https://github.com/alibaba/nacos/releases
部署
容器部署
简化的示例,展示了如何在Docker Compose文件中定义Sentinel和Nacos:
yml
version: '3'
services:
nacos:
image: nacos/nacos-server:latest
ports:
- "8848:8848"
environment:
- MODE=standalone
# 其他Nacos配置...
sentinel:
image: your-sentinel-image:latest # 替换为您的Sentinel镜像
ports:
- "8080:8080" # Sentinel控制台端口
depends_on:
- nacos
environment:
- SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_NAME=nacos
- SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_TYPE=nacos
- SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_NAMESPACE=public # 您的Nacos命名空间
- SPRING_CLOUD_SENTINEL_DATASOURCE_DS1_SERVER-ADDR=nacos:8848 # 指向Nacos服务的地址
# 其他Sentinel配置...
启动Docker Compose
bash
docker-compose up -d
jar启动
- 下载Sentinel JAR包
- 访问Sentinel的官方GitHub地址或Maven仓库,下载适合您项目的Sentinel JAR包。例如,sentinel-dashboard-xxx.jar。
- 配置Nacos数据源:
- 在Spring Cloud项目中,需要添加Nacos数据源相关的Maven依赖。例如:
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>您的Sentinel版本</version>
</dependency>
- 在项目的配置文件(如application.properties或application.yml)中,配置Nacos数据源的相关参数,如Nacos服务器的地址、端口、命名空间、数据ID等。例如:
xml
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds1.nacos.dataId=sentinel-rules
spring.cloud.sentinel.datasource.ds1.nacos.group=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.namespace=public
# 其他配置项...
- 启动Sentinel:
- 在命令行中,进入包含Sentinel JAR包的目录。
- 使用java -jar命令启动Sentinel,并指定配置文件(如果需要)。例如:
bash
java -jar sentinel-dashboard-xxx.jar --spring.config.location=classpath:application.properties
注意:这里假设已经将Nacos数据源的配置写入了application.properties文件,并且该文件位于类路径(classpath)下。如果配置文件位置不同,需要相应地修改--spring.config.location参数的值。
DEMO
java
public class NacosDataSourceDemo {
private static final String KEY = "TestResource";
// nacos server ip
private static final String remoteAddress = "localhost:8848";
// nacos group
private static final String groupId = "Sentinel_Demo";
// nacos dataId
private static final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";
// if change to true, should be config NACOS_NAMESPACE_ID
private static boolean isDemoNamespace = false;
// fill your namespace id,if you want to use namespace. for example: 0f5c7314-4983-4022-ad5a-347de1d1057d,you can get it on nacos's console
private static final String NACOS_NAMESPACE_ID = "${namespace}";
public static void main(String[] args) {
if (isDemoNamespace) {
loadMyNamespaceRules();
} else {
loadRules();
}
// Assume we config: resource is `TestResource`, initial QPS threshold is 5.
FlowQpsRunner runner = new FlowQpsRunner(KEY, 1, 100);
runner.simulateTraffic();
runner.tick();
}
private static void loadRules() {
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
private static void loadMyNamespaceRules() {
Properties properties = new Properties();
properties.put(PropertyKeyConst.SERVER_ADDR, remoteAddress);
properties.put(PropertyKeyConst.NAMESPACE, NACOS_NAMESPACE_ID);
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(properties, groupId, dataId,
source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
集成Spring Cloud Gateway
步骤:
1. 添加依赖
在 Spring Cloud Gateway 项目的 pom.xml 文件中,添加 Sentinel 和 Spring Cloud Alibaba 的相关依赖。这通常包括 Spring Cloud Alibaba Sentinel 的依赖以及 Spring Cloud Gateway 的依赖。
xml
<!-- Spring Cloud Gateway 核心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Cloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>你的版本号</version>
</dependency>
2. 配置Sentinel
在 application.yml 或 application.properties 配置文件中,配置 Sentinel 的相关参数,如数据源(例如 Nacos)、限流规则、熔断规则等。
yml
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080 # Sentinel 控制台地址
port: 8719 # Sentinel 客户端与控制台通信的端口,默认8719
datasource:
# 这里可以配置 Nacos 数据源,用于动态加载限流规则等
flow:
nacos:
server-addr: localhost:8848
dataId: ${spring.application.name}-flow-rules
groupId: DEFAULT_GROUP
namespace: public
rule-type: flow
# 其他 Sentinel 和 Gateway 配置...
3. 设置限流和熔断规则
可以通过 Sentinel 控制台动态设置限流和熔断规则,也可以通过配置文件静态设置。在 Sentinel 控制台中,可以创建流控规则、熔断规则等,并实时查看和修改它们。
4. 启动于测试
启动 Spring Cloud Gateway 应用,并通过浏览器或 Postman 等工具发送请求来测试限流和熔断功能是否生效。可以观察 Sentinel 控制台中的实时监控数据,以验证限流和熔断规则是否按预期工作。
DEMO
java
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider,
ServerCodecConfigurer serverCodecConfigurer) {
this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
this.serverCodecConfigurer = serverCodecConfigurer;
}
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
// Register the block exception handler for Spring Cloud Gateway.
return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
}
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
@PostConstruct
public void doInit() {
initCustomizedApis();
initGatewayRules();
}
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("some_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/ahas"));
add(new ApiPathPredicateItem().setPattern("/product/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
ApiDefinition api2 = new ApiDefinition("another_customized_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api1);
definitions.add(api2);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("aliyun_route")
.setCount(10)
.setIntervalSec(1)
);
rules.add(new GatewayFlowRule("aliyun_route")
.setCount(2)
.setIntervalSec(2)
.setBurst(2)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_CLIENT_IP)
)
);
rules.add(new GatewayFlowRule("httpbin_route")
.setCount(10)
.setIntervalSec(1)
.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)
.setMaxQueueingTimeoutMs(600)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_HEADER)
.setFieldName("X-Sentinel-Flag")
)
);
rules.add(new GatewayFlowRule("httpbin_route")
.setCount(1)
.setIntervalSec(1)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
.setFieldName("pa")
)
);
rules.add(new GatewayFlowRule("httpbin_route")
.setCount(2)
.setIntervalSec(30)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
.setFieldName("type")
.setPattern("warn")
.setMatchStrategy(SentinelGatewayConstants.PARAM_MATCH_STRATEGY_CONTAINS)
)
);
rules.add(new GatewayFlowRule("some_customized_api")
.setResourceMode(SentinelGatewayConstants.RESOURCE_MODE_CUSTOM_API_NAME)
.setCount(5)
.setIntervalSec(1)
.setParamItem(new GatewayParamFlowItem()
.setParseStrategy(SentinelGatewayConstants.PARAM_PARSE_STRATEGY_URL_PARAM)
.setFieldName("pn")
)
);
GatewayRuleManager.loadRules(rules);
}
}