关于java:Spring-Cloud-Gateway-整合Sentinel实现流量控制

35次阅读

共计 4100 个字符,预计需要花费 11 分钟才能阅读完成。

大家好,我是不才陈某~

这是《Spring Cloud 进阶》第 篇文章,往期文章如下:

  • 五十五张图通知你微服务的灵魂摆渡者 Nacos 到底有多强?
  • openFeign 夺命连环 9 问,这谁受得了?
  • 阿里面试这样问:Nacos、Apollo、Config 配置核心如何选型?这 10 个维度通知你!
  • 阿里面试败北:5 种微服务注册核心如何选型?这几个维度通知你!
  • 阿里限流神器 Sentinel 夺命连环 17 问?
  • 比照 7 种分布式事务计划,还是偏爱阿里开源的 Seata,真香!(原理 + 实战)
  • Spring Cloud Gateway 夺命连环 10 问?

前一篇文章介绍了 Spring Cloud Gateway)的一些根底知识点,明天陈某就来唠一唠网关层面如何做限流?

文章目录如下:

网关如何限流?

Spring Cloud Gateway 自身自带的限流实现,过滤器是RequestRateLimiterGatewayFilterFactory,不过这种上不了台面的就不再介绍了,有趣味的能够实现下。

明天的重点是集成阿里的 Sentinel 实现网关限流,sentinel 有不懂的能够看陈某的文章:阿里限流神器 Sentinel 夺命连环 17 问?

从 1.6.0 版本开始,Sentinel 提供了 SpringCloud Gateway 的适配模块,能够提供两种资源维度的限流:

  • route 维度:即在配置文件中配置的路由条目,资源名为对应的routeId,这种属于粗粒度的限流,个别是对某个微服务进行限流。
  • 自定义 API 维度:用户能够利用 Sentinel 提供的 API 来自定义一些 API 分组,这种属于细粒度的限流,针对某一类的 uri 进行匹配限流,能够跨多个微服务。

sentinel 官网文档:https://github.com/alibaba/Se…

Spring Cloud Gateway 集成 Sentinel 实现很简略,这就是阿里的魅力,提供简略、易操作的工具,让程序员专一于业务。

新建我的项目

新建一个 gateway-sentinel9026 模块,增加如下依赖:

<!--nacos 注册核心 -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    <!--spring cloud gateway-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>

    <!--    spring cloud gateway 整合 sentinel 的依赖 -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
    </dependency>

    <!--    sentinel 的依赖 -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>

留神:这仍然是一个网关服务,不要增加 WEB 的依赖

配置文件

配置文件中次要指定以下三种配置:

  • nacos 的地址
  • sentinel 控制台的地址
  • 网关路由的配置

配置如下:

spring:
  cloud:
    ## 整合 sentinel,配置 sentinel 控制台的地址
    sentinel:
      transport:
        ## 指定控制台的地址,默认端口 8080
        dashboard: localhost:8080
    nacos:
      ## 注册核心配置
      discovery:
        # nacos 的服务地址,nacos-server 中 IP 地址: 端口号
        server-addr: 127.0.0.1:8848
    gateway:
      ## 路由
      routes:
        ## id 只有惟一即可,名称任意
        - id: gateway-provider
          uri: lb://gateway-provider
          ## 配置断言
          predicates:
            ## Path Route Predicate Factory 断言,满足 /gateway/provider/** 这个申请门路的都会被路由到 http://localhost:9024 这个 uri 中
            - Path=/gateway/provider/**

上述配置中设置了一个路由 gateway-provider,只有申请门路满足/gateway/provider/** 都会被路由到 gateway-provider 这个服务中。

限流配置

通过上述两个步骤其实曾经整合好了 Sentinel,此时拜访一下接口:http://localhost:9026/gateway…

而后在 sentinel 控制台能够看到曾经被监控了,监控的路由是gateway-provider,如下图:

此时咱们能够为其新增一个 route 维度的限流,如下图:

上图中对 gateway-provider 这个路由做出了限流,QPS 阈值为 1。

此时快速访问:http://localhost:9026/gateway…,看到曾经被限流了,如下图:

以上 route 维度的限流曾经配置胜利,小伙伴能够本人照着上述步骤尝试一下。

API 分组限流也很简略,首先须要定义一个分组,API 治理 -> 新增 API 分组,如下图:

匹配模式抉择了准确匹配(还有前缀匹配,正则匹配),因而只有这个 uri:http://xxxx/gateway/provider/port会被限流。

第二步须要对这个分组增加流控规定,流控规定 -> 新增网关流控,如下图:

API 名称那里抉择对应的分组即可,新增之后,限流规定就失效了。

陈某不再测试了,小伙伴本人入手测试一下吧 ……………

陈某这里只是简略的配置一下,至于限流规定长久化一些内容请看陈某的 Sentinel 文章,这里就不再过多的介绍了。

如何自定义限流异样信息?

从下面的演示中能够看到默认的异样返回信息是:”Block………”,这种必定是客户端不能承受的,因而须要定制本人的异样返回信息。

上面介绍两种不同的形式定制异样返回信息,开发中本人抉择其中一种。

间接配置文件中定制

开发者能够间接在配置文件中间接批改返回信息,配置如下:

spring:
  cloud:
    ## 整合 sentinel,配置 sentinel 控制台的地址
    sentinel:
      #配置限流之后,响应内容
      scg:
        fallback:
          ## 两种模式,一种是 response 返回文字提示信息,## 一种是 redirect,重定向跳转,须要同时配置 redirect(跳转的 uri)
          mode: response
          ## 响应的状态
          response-status: 200
          ## 响应体
          response-body: '{"code": 200,"message":" 申请失败,稍后重试!"}'

上述配置中 mode 配置的是 response,一旦被限流了,将会返回JSON 串。

{
    "code": 200,
    "message": "申请失败,稍后重试!"
}

重定向 的配置如下:

spring:
  cloud:
    ## 整合 sentinel,配置 sentinel 控制台的地址
    sentinel:
      #配置限流之后,响应内容
      scg:
        fallback:
          ## 两种模式,一种是 response 返回文字提示信息,一种是 redirect,重定向跳转,须要同时配置 redirect(跳转的 uri)
          mode: redirect
          ## 跳转的 URL
          redirect: http://www.baidu.com

一旦被限流,将会间接跳转到:http://www.baidu.com

编码定制

这种就不太灵便了,通过硬编码的形式,残缺代码如下:

@Configuration
public class GatewayConfig {
    /**
     * 自定义限流处理器
     */
    @PostConstruct
    public void initBlockHandlers() {BlockRequestHandler blockHandler = (serverWebExchange, throwable) -> {Map map = new HashMap();
            map.put("code",200);
            map.put("message","申请失败,稍后重试!");
            return ServerResponse.status(HttpStatus.OK)
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
                    .body(BodyInserters.fromObject(map));
        };
        GatewayCallbackManager.setBlockHandler(blockHandler);
    }
}

两种形式介绍完了,依据业务需要本人抉择适宜的形式,当然陈某更喜爱第一种,理由:约定 > 配置 > 编码

网关限流了,服务就平安了吗?

很多人认为只有网关层面做了限流,躲在身后的服务就能够居安思危了,你是不是也有这种想法?

很显然这种想法是谬误的,简单的微服务架构一个独立服务不仅仅被一方调用,往往是多方调用,如下图:

商品服务不仅仅被网关层调用,还被外部订单服务调用,这时候仅仅在网关层限流,那么商品服务还平安吗?

一旦大量的申请订单服务,比方大促秒杀,商品服务不做限流会被霎时击垮。

因而须要依据公司业务场景对本人负责的服务也要进行限流兜底,最常见的计划:网关层集群限流 + 外部服务的单机限流兜底,这样能力保障不被流量冲垮。

总结

文章介绍了 Spring Cloud Gateway 整合 Sentinel 对网关层进行限流,以及对于限流的一些思考。如有谬误之处,欢送留言斧正。

我的项目源码曾经上传 Github,公众号【码猿技术专栏】回复关键词:9528获取!

正文完
 0