服务限流

最近更新时间: 2024-09-05 15:09:00

服务限流主要是保护服务节点或者数据节点,防止瞬时流量过大造成服务和数据崩溃,导致服务不可用。当资源成为瓶颈时,服务框架需要对请求做限流,启动流控保护机制。

限流原理

限流的原理是监控服务流量的 QPS 指标,当达到指定的阈值时进行流量控制,避免被瞬时高峰流量冲垮,从而确保服务的高可用。

TSF 限流方案采用了动态配额分配制,限流中控根据实例的历史流量记录,动态计算预测下一时刻该实例的流量,若所有实例的流量预测值都小于额定平均值(总配额/在线实例数),则以该平均值作为所有实例分配的配额;否则按预测流量的比例分配,且保证一个最小值。

TSF 目前支持在被调服务上设置限流规则,服务的限流对象(下文中称为“限流资源”)可以通过标签表达式灵活配置,常见的限流对象如当前服务、当前服务的特定 API 等,并且可以通过标签表达式区分不同的调用来源,针对不同的调用关系进行限流。一条限流规则主要包括以下几个元素:

  • 限流粒度:通过标签表达式表示被调方的限流资源调用来源

  • 限流阈值:单位时间和请求数,如果单位时间设置为1秒,则限流阈值为QPS。

  • 生效状态:限流规则是否生效。

限流使用场景

场景1:根据调用方进行限流

调用关系中包括调用方和被调用方,一个被调服务可能同时被多个服务调用。在限流规则中,限流粒度字段可以用于根据调用来源进行流量控制,举例如下:

  • 不区分调用者:限流粒度选择全局限流时,来自任何调用者的请求都将进行限流统计。如果限流资源的调用总和超过了这条规则定义的阈值,则触发限流。

  • 针对特定的调用者:限流粒度选择基于标签限流,设置系统标签为上游服务名,逻辑关系为等于,值为特定的调用服务。

  • 针对除特定调用者之外的调用方:限流粒度选择基于标签限流,设置系统标签为上游服务名,逻辑关系为不等于,值为特定的调用服务。

区分调用方除了使用上游服务名等系统标签外,还可以使用自定义标签来区分带有不同业务信息的调用。例如针对特定用户foo的调用进行限流,可以在代码中设置user参数,然后在限流规则中配置业务标签为user,逻辑关系为等于,值为foo

场景2:针对不同的资源进行限流

一个服务包含一个或多个 API,TSF 支持针对服务或者 API 进行限流。在限流规则中,限流粒度字段可以用于区分不同的限流资源,举例如下:

  • 针对当前服务:无须额外设置。

  • 针对特定的API: 限流粒度选择基于标签限流,设置系统标签为当前服务的 API Path,逻辑关系为等于,值为特定的 API Path。如果需要指定 HTTP Method,则需要再增加一条HTTP Method的系统标签来约束。

  • 针对特定API之外的API:限流粒度选择基于标签限流,设置系统标签为当前服务的 API Path,逻辑关系为不等于,值为特定的 API Path。如果需要指定 HTTP Method,则需要再增加一条HTTP Method的系统标签来约束。

使用限流功能

要使用限流功能,用户需要在客户端配置依赖项,然后在 TSF 控制台设置限流规则。

1. 配置依赖项

对于 Spring Cloud 应用,参考开发手册中的 [服务治理] 。对于 Mesh 应用,如果希望使用基于标签的限流,需要在代码中设置标签。

2. 新建限流规则

前提条件:服务列表上有“在线”状态的微服务。

  1. 登录 [TSF 控制台] 。

  2. 在左侧导航栏,单击【服务治理】。

  3. 在服务列表页,单击服务名,进入服务详情页。

  4. 选择服务限流标签页,单击【新建限流规则】。

  5. 填写限流规则信息。

  • 规则名:填写规则名。

  • 限流粒度

  • 全局限流:不区分限流来源,统计所有请求。

  • 基于标签限流:根据标签规则设置限流。

  • 单位时间:正整数,单位:秒。

  • 请求数:正整数,单位:次。

  • 生效状态:是否立即启用限流规则。

  • 描述:填写描述信息。

  1. 单击【提交】完成新建。

3. 启动限流规则

在限流规则列表中,可以修改规则的【生效状态】。 多条限流规则都是生效状态时,只要服务接收到的请求满足任意一条限流规则,就会触发限流逻辑。

4. 触发限流

假设服务提供了 /echo API,可以通过不断执行 curl /echo 来模拟限流场景。 示例:在 Demo 中 consumer-demo 服务提供了 /echo-feign/{str} API ,那么针对 consumer-demo 服务新建限流规则,限流粒度为全局限流,单位时间 2 秒,请求数 5 次。启用限流规则。 下载脚本 tsf_ratelimit.sh ,登录可以访问到 consumer-demo 的机器(consumer-demo 所在机器也可以),执行 ./tsf_ratelimit.sh <IP>:<Port> ,其中 IP 是 consumer-demo 所在机器 IP, Port 为服务监听端口 18083。脚本的作用是每 2 秒触发 10 次调用。由于调用的频率大于限流规则,正常情况下,会收到 HTTP 429 (Too Many Requests) 的状态码。

5. 查看限流效果

如果请求数达到了限流阈值,任何到达的请求都会限流模块处理。如果该服务上的配额已经消耗完,会对请求返回 HTTP 429 (Too Many Requests);否则会正常放行。用户可以在限流规则列表下方的请求数-时间图中查看到被限制的请求数或者被限制请求率-时间图中查看到被限制请求率(计算公式 被限制请求率 = 被限制的请求数 / 请求数)随时间的变化。

限制说明

等于、不等于、包含、不包含属于严格匹配,正则表达式属于模糊匹配。因此当系统标签是被调方 API PATH 时,目前仅支持使用正则表达式的逻辑关系来匹配带参数的 API 请求。

  • 当标签的逻辑关系是正则表达式,值填写/echo/.*时,可以匹配带参数的请求 /echo/test123 (其中test123是参数)。

  • 当标签的逻辑关系是等于、不等于、包含、不包含关系,值是/echo/{param}时,不能匹配带参数的请求 /echo/test123 (其中 test123 是参数)。