由于sentinel 默认不支持spring-cloud-gateway,从官方的github上能看到部分回帖会在1.5版本中考虑对它进行支持。
但是对于目前sentinel 来说可以从硬编码的方式进行和gateway 进行集成。虽然官方对于目前zuul是支持的,但是毕竟,spring cloud 已经放弃了zuul,
另起炉灶,自己去说实现网关。所以在大局势下,还是选了spring-cloud-gateway。
spring-cloud-gateway 默认是有spring webflux 来处理的,所以当你导入了 spring-web 相关的jar后会发生冲突,无法启动,但是对于sentinel 来说,默认是需要servlet进行支持,否则在通过gateway 的全局过滤器进行实现的时候会报错。所以在pom里。我们需要进行serlvet-api进行引入。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${alibaba.sentinel.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
为什么要写全局的过滤器,因为这样可以会直接作用到网关全局请求上,避免了编码带来的一些复杂的工作,同时,毕竟请求入口是网关,我们要对每一个请求进行监控和相关处理。
@Component
public class SentinelGatewayFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
// TODO Auto-generated method stub
return -1;
}
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain chain) {
String resource = serverWebExchange.getRequest().getPath().toString();
this.initFlowRules(resource);
Entry entry = null;
try {
ContextUtil.enter(resource);
entry = SphU.entry(resource, EntryType.IN, 1, serverWebExchange.getRequest().getQueryParams().values());
return chain.filter(serverWebExchange);
} catch (BlockException e) {
if (!BlockException.isBlockException(e)) {
Tracer.trace(e);
}
e.printStackTrace();
} finally {
if (entry != null) {
entry.exit();
}
ContextUtil.exit();
}
serverWebExchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
return serverWebExchange.getResponse().setComplete();
}
private void initFlowRules(final String resource){
List<FlowRule> rules = new ArrayList<FlowRule>();
// 限流
FlowRule rule = new FlowRule();
rule.setResource(resource);
rule.setCount(5);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
通过 component注解,这样gateway就会自动进行过滤器注入扫描。特此整个集成完毕。
虽然目前对于sentinel 只有通过这一种方式进行集成,但是相信未来阿里会在1.5版本以后对此进行进一步的集成方式,通过注解或者其他配置方式来实现。
大家还是期待吧