sentinel+spring-cloud+sentinel-dashboard动态限流控制
添加spring-cloud-sentinel依赖包
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- spring cloud begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.7.2</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-parameter-flow-control</artifactId>
<version>1.7.2</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.7.0</version>
<exclusions>
<exclusion>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- spring cloud end -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency>
</dependencies>
配置文件
base:
config:
nacos:
hostname: localhost
port: 8848
spring:
application:
name: gateway-service
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: ${base.config.nacos.hostname}:${base.config.nacos.port}
sentinel:
transport:
dashboard: localhost:8080
gateway:
discovery:
locator:
enabled: true
routes:
- id: AUTHORIZE-SERVICE
uri: lb://authorize-service
predicates:
- Path=/authorize/**
filters:
- StripPrefix=1
- id: PARTNER-SERVICE
uri: lb://partner-service
predicates:
- Path=/partner/**
filters:
- StripPrefix=1
- id: MALL-SERVICE
uri: lb://mall-service
predicates:
- Path=/mall/**
filters:
- StripPrefix=1
server:
port: 8888
logging:
level:
org.springframework.cloud.gateway: debug
management:
endpoints:
web:
exposure:
include: "*"
flow:
count: 10
spring-cloud-gateway接入流控
@Configuration
public class GatewayConfiguration {
private final List<ViewResolver> viewResolvers;
private final ServerCodecConfigurer serverCodecConfigurer;
@Value("${flow.count}")
private int count;
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();
}
/**
* 根据请求的url,分组定义流控的资源,比如/mall/** 归到mall_api中
* 这样可以针对一组的请求url,来细粒度的进行流控
*/
private void initCustomizedApis() {
Set<ApiDefinition> definitions = new HashSet<>();
ApiDefinition api1 = new ApiDefinition("mall_api")
.setPredicateItems(new HashSet<ApiPredicateItem>() {{
add(new ApiPathPredicateItem().setPattern("/mall/**")
.setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));
}});
definitions.add(api1);
GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
/**
* sentinel也可以根据配置文件中的routes-ID进行流控
* 比如AUTHORIZE-SERVICE是配置文件中的一个route_id
*/
private void initGatewayRules() {
Set<GatewayFlowRule> rules = new HashSet<>();
rules.add(new GatewayFlowRule("AUTHORIZE-SERVICE")
.setCount(count)
.setIntervalSec(1)
);
GatewayRuleManager.loadRules(rules);
}
}
启动sentinel-dashboard控制台
下载控制台的jar:
链接: sentinel-dashboard.
启动sentinel-dashboard
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
访问sentinel-dashboard
http://localhost:8080/#/dashboard/home
输入用户名/密码 sentinel/sentinel
访问项目接口,dashboard查看QPS
查看簇点链路
可以看到刚才配置的资源
动态调整流控参数
我们设置每秒只有1个请求能通过
保存后在流控规则列表中可以看到我们刚刚保存的规则
POSTMAN进行流控测试
当我们快速点击请求时,网关就会显示请求被sentinel block了,这样当有大量的请求过来的时候,我们就能通过sentienl来保证应用的稳定
一个具有注脚的文本。[^2]
除了网关,其它的服务的流控
其它的微服务也可以通过配置流控规则进行每个url的细粒度的流控,操作上跟网关一样,只要配置接入sentinel-dashboard,就能加以控制。
自此,sentinel就能保证应用的高可用性。