Sentinel + GateWay + Nacos 实现基于推模式的接口限流(配置持久化)、自定义响应结果

Sentinel + GateWay 接口限流

一、安装Sentinel控制台

  1. 下载控制台程序,GitHub连接如下:

    sentinel-dashboard-1.8.0.jar

  2. 启动控制台:

    java -jar sentinel-dashboard-1.8.0.jar
    
  3. 访问控制台
    1)默认访问端口是8080,如果要修改,在启动时使用--server.port=port指定即可。
    java -jar sentinel-dashboard-1.8.0.jar --server.port=8081
    2)默认访问地址:http://127.0.0.1:8080/#/login
    3)访问会要求登录,账户和密码都是 sentinel
    在这里插入图片描述
    4)首次登录应该是空空如也
    在这里插入图片描述

二、引入依赖

父项目依赖:
(此处引入spring-cloud-alibaba的主要是为了通过父工程统一控制与spring-cloud-alibaba相关的依赖版本;不引入也是可以的,只是要在后续的依赖中手动指定版本)

<properties>
    <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    <spring-cloud-alibaba.version>2.1.2.RELEASE</spring-cloud-alibaba.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring-cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

网关项目依赖:

<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
</dependencies>

这里需要注意,实现网关限流,只需要引入上面这两个依赖即可,网上有很多教程依赖了很多没用或者重复的引用,这里给出这两个依赖包含的依赖包供大家参考:
在这里插入图片描述

三、配置网关

spring:
  cloud:
    sentinel:
      #心跳启动
      eager: true
      transport:
        #sentinel控制台访问路径
        dashboard: localhost:8080
        port: 8080
    gateway:
      routes:
        - id: redirect_route
          #转发地址
          uri: lb://service
          #断言,要转发的请求
          predicates:
            - Method=POST,GET
          #过滤器
          filters:
          	#把请求路径中的test替换成service
            - RewritePath=/test/(?<segment>.*), /service/$\{segment}

四、添加限流

启动网关项目和后台服务,在Sentinel控制台就可以看到网关的项目了。此时可以添加限流规则:
在这里插入图片描述
资源名:此处填网关的路由id(或者请求路径,比如 /test),资源表示请求路径或者网关路由ID。按照上面的yaml配置文件,此处我填的是redirect_route
单机阈值:每秒支持的请求次数
填好之后,便可以接口限流了:
在这里插入图片描述

五、测试

频繁请求下,Sentinel会返回如下信息:
在这里插入图片描述
至此,Sentinel接口限流完成。

Sentinel + GateWay + Nacos 实现配置持久化

上面的流控配置,是存在内存中的,一旦网关项目重启,配置就会消失,所以生产是不可能采用这种情况的。通常,需要结合注册中心使用,把流控规则放到配置中心,当规则变化时,也可以由配置中心推送到Sentinel。这里实现基于推模式的配置持久化,详请可参考官网:在生产环境中使用 Sentinel

六、网关增加依赖

<dependency>
       <groupId>com.alibaba.csp</groupId>
       <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

七、配置Nacos

spring:
  application:
    name: pms-gateway
  cloud:
    nacos:
      config:
        #这里表示使用dev命名空间
        namespace: dev
        #分组ID
        group: pms-v3.0
        #nacos服务地址
        server-addr: 10.10.62.43:8848
        #声明从配置中心中读取的配置文件格式,缺省值为properties
        file-extension: yml
      discovery:
        namespace: dev
        group: pms-v3.0
        server-addr: 10.10.62.43:8848
    sentinel:
      #心跳启动
      eager: true
      transport:
        #sentinel控制台访问路径
        dashboard: localhost:8080
      #sentinel数据源配置(从哪里获取限流规则)  
      datasource:
        ds:
          nacos:
            #读取哪个命名空间的配置(要和上面的nacos.config.namespace配置一致,否则会读不到文件。如果默认public,则可以不写)
            namespace: dev
            server-addr: 10.10.62.43:8848
            #限流规则配置文件的名称
            dataId: pms-gateway-sentinel-flow-limit
            groupId: pms-v3.0
            data-type: json
            rule-type: flow
      gateway:
        routes:
          - id: redirect_route
            #转发地址
            uri: lb://service
            #断言,要转发的请求
            predicates:
              - Method=POST,GET
            #过滤器
            filters:
              #重写url把url中的pms替换成passenger-management-system
              - RewritePath=/test/(?<segment>.*), /service/$\{segment}

我的Nacos命名空间:

在这里插入图片描述

八、添加限流规则

在Nacos的dev命名空间添加限流配置,注意Data ID和Group要和上面配置文件写的一致。
在这里插入图片描述

[
	{
		"resource":"redirect_route",
		"limitApp":"default",
		"grade":1,
		"count":1,
		"strategy":0,
		"controlBehavior":0,
		"clusterMode":"false"
	}
]

字段详情可参考官网:Sentinel流量控制
resource:资源名,即限流规则的作用对象
count: 限流阈值
grade: 限流阈值类型(QPS 或并发线程数)
limitApp: 流控针对的调用来源,若为 default 则不区分调用来源
strategy: 调用关系限流策略
controlBehavior: 流量控制效果(直接拒绝、Warm Up、匀速排队)

在这里插入图片描述

九、测试

重启gateway项目,到Sentinel的【流控规则】可以看到Nacos的配置已经同步过来了。
在这里插入图片描述

自定义响应结果

在第五步,可以看到,限流返回的是429报错,如果想自定义返回响应信息,可以通过以下方式实现:

//sentinel异常统一返回处理
package com.pci.pms.gateway.filter;

import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import com.pci.common.entity.ResponseCodeEnum;
import com.pci.pms.gateway.entity.CommonResponse;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import static org.springframework.web.reactive.function.BodyInserters.fromObject;

@Component
public class SentinelExceptionHandler implements BlockRequestHandler {

    @Override
    public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
        CommonResponse<String> resp = new CommonResponse<>();
        int status = 200;
        //限流响应
        if (throwable instanceof FlowException) {
            resp.setCode(10001);
            resp.setMessage("提示:系统繁忙,请稍后再试");
            status = 429;
        }
        //服务降级响应
        else if (throwable instanceof DegradeException) {
        }
        //热点参数限流响应
        else if (throwable instanceof ParamFlowException) {
        }
        //触发系统保护规则响应
        else if (throwable instanceof SystemBlockException) {
        }
        //授权规则不通过响应
        else if (throwable instanceof AuthorityException) {
        }
        //返回固定响应信息
        ServerHttpResponse response = serverWebExchange.getResponse();
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return ServerResponse.status(status).contentType(MediaType.APPLICATION_JSON_UTF8).body(fromObject(JSONObject.toJSONString(resp)));
    }

}

//响应类
package com.pci.pms.gateway.entity;
import lombok.Data;
@Data
public class CommonResponse<T> {

    /**
     * 响应码
     */
    private String code;

    /**
     * 响应消息
     */
    private String message;

    /**
     * 响应数据
     */
    private T data;
}

在这里插入图片描述

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值