ack route: %s", route));
if (cause instanceof BlockException) {
return new BlockResponse(429, "Sentinel block exception", route);
} else {
return new BlockResponse(500, "System Error", route);
}
}
}
3.1.4 同时,我们需要将3个Sentinel的Filter注入Spring,配置类如下:
代码清单:Alibaba/sentinel-springcloud-high/zuul_server/src/main/java/com/springcloud/zuul_server/config/ZuulConfig.java
***
@Configuration
public class ZuulConfig {
@Bean
public ZuulFilter sentinelZuulPreFilter() {
// We can also provider the filter order in the constructor.
return new SentinelZuulPreFilter();
}
@Bean
public ZuulFilter sentinelZuulPostFilter() {
return new SentinelZuulPostFilter();
}
@Bean
public ZuulFilter sentinelZuulErrorFilter() {
return new SentinelZuulErrorFilter();
}
/**
* 注册 ZuulFallbackProvider
*/
@PostConstruct
public void doInit() {
ZuulBlockFallbackManager.registerProvider(new ZuulFallbackProvider());
}
}
最终,启动前需要配置JVM启动参数,增加-Dcsp.sentinel.app.type=1
,来告诉Sentinel控制台我们启动的服务是为 API Gateway 类型。
3.1.5 测试
顺次启动子工程provider_server、consumer_fallback、zuul_server,打开浏览器访问:http://localhost:18080/consumer/helloByFeign ,然后我们打开Sentinel控制台,查看zuul_server服务,如图:
我们定制限流策略,依旧是QPS为1,我们再次刷新http://localhost:18080/consumer/helloByFeign 页面,这时,页面上已经可以正产限流了,限流后显示的内容为:
{"code":429, "message":"Sentinel block exception", "route":"consumer-route"}
这里注意,定义限流的是资源,千万不要定义错地方,限流定义如图:
3.2 Spring Cloud Gateway
从 1.6.0 版本开始,Sentinel 提供了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:
- route 维度:即在 Spring 配置文件中配置的路由条目,资源名为对应的 routeId
- 自定义 API 维度:用户可以利用 Sentinel 提供的 API 来自定义一些 API 分组
3.2.1 创建子工程gateway_server
工程依赖pom.xml如下:
代码清单:Alibaba/sentinel-springcloud-high/gateway_server/pom.xml
***
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
3.2.2 配置文件application.yml如下:
代码清单:Alibaba/sentinel-springcloud-high/gateway_server/src/main/resources/application.yml
***
server:
port: 28080
spring:
application:
name: spring-cloud-gateway-server
cloud:
nacos:
discovery:
server-addr: 192.168.44.129:8848
sentinel:
transport:
dashboard: localhost:8080
port: 8720
gateway:
enabled: true
discovery:
locator:
lower-case-service-id: true
routes:
- id: consumer_server
uri: lb://spring-cloud-consumer-fallback
predicates:
- Method=GET
3.2.3 全局配置类GatewayConfig.java如下:
同上一小节介绍的Zuul,这里我们同样需要将两个Sentinel有关Spring Cloud Gateway的Filter注入Spring:SentinelGatewayFilter
和SentinelGatewayBlockExceptionHandler
,这里因为在Sentinel v1.6.0版本才加入Spring Cloud Gateway的支持,很多地方还不是很完善,异常处理SentinelGatewayBlockExceptionHandler
目前只能返回一个异常信息,在我们的系统中无法和上下游很好的结合,这里笔者自己重新实现了SentinelGatewayBlockExceptionHandler
,并命名为JsonSentinelGatewayBlockExceptionHandler
,返回参数定义成为JSON,这里不再注入Sentinel提供的SentinelGatewayBl