Spring-Cloud-Gateway 集成 sentinel

原创
2019/03/13 17:07
阅读数 2.6K

由于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版本以后对此进行进一步的集成方式,通过注解或者其他配置方式来实现。

大家还是期待吧

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部