多Azure APIM跨区域高可用部署下如何实现全局速率限制?
跨多实例Azure APIM实现全局速率限制的解决方案
要解决多APIM实例下全局限流的问题,核心是让所有实例共享同一调用计数源,以下是两种可行的落地方案:
方案一:基于Azure Redis Cache的分布式计数限流
通过外部共享缓存统一存储客户端的调用计数,让两个APIM实例共用同一计数基准,实现全局限流。
实现步骤
- 部署Azure Redis Cache实例,确保两个APIM服务都能通过网络访问该缓存(配置VNet peering或防火墙规则)
- 在APIM的API或产品级别添加以下策略,替换
<redis-cache-name>和<redis-access-key>为实际信息:
<!-- 定义客户端唯一标识,这里用订阅ID作为示例,可替换为IP、自定义头字段等 --> <set-variable name="clientId" value="@(context.Subscription.Id)" /> <!-- 从Redis读取当前调用计数 --> <cache-lookup-value key="@(context.Variables.GetValueOrDefault<string>("clientId"))" cache-ref="<redis-cache-name>" variable-name="currentCount" /> <!-- 判断是否达到限流阈值 --> <choose> <when condition="@(context.Variables.GetValueOrDefault<int?>("currentCount") >= 2)"> <return-response> <set-status code="429" reason="Too Many Requests" /> <set-header name="Retry-After" exists-action="override"> <value>60</value> </set-header> </return-response> </when> <otherwise> <!-- 计数初始化或递增 --> <set-variable name="newCount" value="@(context.Variables.GetValueOrDefault<int?>("currentCount") ?? 0 + 1)" /> <!-- 将新计数存入Redis,设置1分钟过期(匹配限流窗口) --> <cache-store-value key="@(context.Variables.GetValueOrDefault<string>("clientId"))" value="@(context.Variables.GetValueOrDefault<int>("newCount"))" cache-ref="<redis-cache-name>" duration="60" /> </otherwise> </choose>
优缺点
- 优点:限流粒度灵活(可基于订阅、IP、自定义标识),支持复杂计数逻辑
- 缺点:需额外维护Redis实例,增加运维成本和部署复杂度
方案二:基于Azure Front Door的入口层全局限流
将Front Door作为流量统一入口,所有请求先经过Front Door再转发到两个APIM实例,直接在Front Door层面配置全局速率限制。
实现步骤
- 部署Azure Front Door,配置后端池包含两个APIM实例,设置轮询负载均衡规则
- 在Front Door的规则引擎中添加速率限制规则:
- 选择速率限制条件,设置限制为2次/分钟
- 选择客户端标识(可基于IP、自定义头如订阅密钥等)
- 配置超出限制时返回429状态码
优缺点
- 优点:配置简单,无需修改APIM策略,Front Door自带高可用和全球分发能力
- 缺点:限流粒度依赖Front Door支持的标识维度,复杂场景灵活性不如Redis方案
内容的提问来源于stack exchange,提问作者Shuvan
相关产品推荐
相关产品推荐

