本文共 3526 字,大约阅读时间需要 11 分钟。
使用场景
在许多场景下都需要对服务进行速率限制。一种常见的场景是防止来自外部服务的过度调用(如爬虫)。另一种常见的场景是调用某些收费的外部服务,但是提供了免费配额,可以使用速率限制确保只使用免费的配额。环境准备
在 Kubernetes 集群上部署 Istio 部署 Bookinfo 示例应用 配置 Bookinfo 应用各个微服务的 destinationrule 和 virtualservice使用 Istio 实现速率限制
上面使用的是 memquota handler,memquota handler 绑定在 Mixer 进程上,没有持久化,无 HA 能力,因此并不适合生产使用。可以用 redisquota handler 替代 memquota handler 实现持久化:
上面定义了一个 redisquota handler,定义的三种速率限制模式和上文的 memquota handler相同。其中 rateLimitAlgorithm 字段可以选择 ROLLING_WINDOW 或者 FIXED_WINDOW,两种算法的介绍见下文“速率限制的原理”一节。然后创建该 redisquota handler:创建 quota rule
Rule 负责通知 Mixer,哪个 instance 应该在什么时候发送给哪个 handler。编辑 quota_rule.yaml 内容如下:上面这条 rule 告诉 Mixer 使用上面创建的 handler.memquota\handler.redisquota handler,并将上面创建的 requestcount.quota instance 构建的对象传递给该 handler。然后执行如下命令创建上述 rule:有条件的速率限制
上面只使用了 dimensions 来定义速率限制的条件,还可以在 rule 中使用任意属性来定义规则。例如,在某些场景下,我们不需要对已经登录的用户进行速率限制。在 bookinfo 示例中,我们通过设置 cookie user=<username> 来识别已经登录的用户。修改 quota_rule.yaml 内容如下:然后执行如下命令修改 rule:修改后的 rule 使得当且仅当 user=<username> cookie 为空时才应用 memquota 或者 redisquota 适配器,从而保证了已登录的用户免受速率限制。以“kokokobe”用户登录,并持续刷新页面,每次都可以刷出下图所示页面。登出之后持续刷新页面,会再一次看到下图所示的 RESOURCE_EXHAUSTED:Quota is exhausted for: requestcount。速率限制的原理速率限制有 Token Bucket、Fixed Window、Rolling Window 等常见的算法实现。Token Bucket 算法每经过固定的时间间隔会产生一个 token,如果此时 bucket 没有满,则产生的 token 可以被放入 bucket 中。当请求到来时,如果此时 bucket 中有足够多的 token,则可以同时取走多个;如果此时 bucket 中 token 不够,则拒绝服务。Fixed Window 算法每个时间间隔对应一个计数器,每当有请求到来,如果此时计数器未达到配额的限定值,则计数器加 1,否则拒绝服务。当进入下一个时间间隔时,计数器失效被重置。该算法的缺点在于不能保证在任意的时间间隔内,速率都被限制在配额以下。即如果请求集中在计数器失效的时间点附近,则在该时间点附近的时间间隔内,速率最大能达到配额的两倍。Rolling Window 算法通过对上一个时间间隔请求数和当前时间间隔已处理的请求数进行加权,实现了对任意时间间隔的速率的估算。图片来自 如上图所示,在上一分钟内处理了 42 个请求,当前这一分钟已经过去了 15 秒,处理了 18 个请求,则当前这一分钟的速率可以估算为:rate = 42 ((60-15)/60) + 18 = 42 0.75 + 18 = 49.5如果使用 memquota adapter,默认使用亚秒级分辨率的 rolling window 实现速率限制。如果使用 redisquota adapter,可以配置使用 Rolling Window 算法或者 Fixed Window 算法。如果在该时间间隔内的请求数超过了 maxAmount,Mixer 会返回 RESOURCE_EXHAUSTED 信息给 Envoy,Envoy 再返回 HTTP 429 StatusTooManyRequests 给调用者。目前华为云容器引擎CCE全面支持Istio~12月12日——12月31日,华为云12.12会员日活动还有钜惠活动,云容器产品钜惠促销等你来~
点此参与~转载于:https://blog.51cto.com/13831707/2336463