Nacos+Sentinel+gateway 实现微服务限流
本文主要介绍Nacos+Sentinel+gateway 实现微服务限流
目录
一、Sentinel是什么?
Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
二、使用步骤
1.下载Sentinel
https://github.com/alibaba/Sentinel/releases
打开页面找到sentinel-dashboard打头的jar文件链接点击下载,下载完成后执行
java -jar sentinel-dashboard-1.7.0.jar
打开页面http://localhost:8080
输入账号sentinel密码sentinel即可进入控制台
2.集成Sentinel
在网关处添加Sentinel依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.2.3.RELEASE</version
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.8.5</version>
</dependency>
在网关处添加如下配置
spring
cloud
sentinel:
eager: true #这里配置true表示服务启动则与sentinel建立连接,否则需要有网关url请求才能在sentinel看到数据
transport:
port: 8850
dashboard: l27.0.0.1:8080
datasource:
flow-ds: #sentinel从nacos获取指定的流控规则 这个名字可以自定义,不重复就可以
nacos:
server-addr: 127.0.0.1:8848
dataId: flow-server
groupId: DEFAULT_GROUP
ruleType: flow # flow代表流量控制,degrade代表熔断规则
添加异常处理
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;
import java.util.Collections;
import java.util.List;
@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;
}
/**
* 初始化一个限流的过滤器
*
* @return
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
/**
* 配置限流的异常处理器
*
* @return
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SentinelFallbackHandler sentinelFallbackHandler() {
return new SentinelFallbackHandler();
}
}
import java.nio.charset.StandardCharsets;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Mono;
/**
* 自定义限流异常处理
*/
public class SentinelFallbackHandler implements WebExceptionHandler
{
private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange)
{
ServerHttpResponse serverHttpResponse = exchange.getResponse();
serverHttpResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
byte[] datas = "{\"code\": 20001,\"data\": {},\"fail\": true,\"message\": \"系统繁忙,请稍后再试\"}".getBytes(StandardCharsets.UTF_8);
DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
return serverHttpResponse.writeWith(Mono.just(buffer));
}
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex)
{
if (exchange.getResponse().isCommitted())
{
return Mono.error(ex);
}
if (!BlockException.isBlockException(ex))
{
return Mono.error(ex);
}
return handleBlockedRequest(exchange, ex).flatMap(response -> writeResponse(response, exchange));
}
private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable)
{
return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
}
}
nacos添加配置文件flow-server(json格式)
[{
"resource":"/api/user/verificationImg", //限流资源
resourceMode:0,规则是针对 API Gateway 的route(RESOURCE_MODE_ROUTE_ID)还是用户在 Sentinel 中定义的API 分组(RESOURCE_MODE_CUSTOM_API_NAME),默认是route。
"controlBehavior":0, //流控效果 (0:失败,1:预热,2:排队等待)
"count":2,//单机阀值
"grade":1,//阈值类型(阀值类型,0:线程数,1:QPS)
"limitApp":"default",//针对来源 (Sentinel可以针对调用者进行限流,填写微服务名,指定对哪个微服务进行限流 ,默认default(不区分来源,全部限制))
"clusterMode":false,//是否集群(false:否,true:是)
"strategy":"0"//流控模式(0:直接,1:关联,2:链路)
}]
3.测试
启动网关即可在控制台看到naco配置的流控规则

F5快速刷新http://127.0.0.1:8891/api/user/verificationImg
出现如下json串即限流成功
{"code": 20001,"data": {},"fail": true,"message": "系统繁忙,请稍后再试"}
并能在控制台看到当前并发的QPS

更多推荐
所有评论(0)