如何在Apigee中基于client.ip实现条件化Spike Arrest限流
实现Apigee信任IP跳过Spike Arrest/Quota的条件化执行
要实现仅对非信任IP执行限流规则,你需要结合Apigee的KVM(键值对存储)、JavaScript Policy和步骤条件判断来完成,具体步骤如下:
1. 存储信任IP列表
在Apigee环境级创建一个KVM(键值对存储),用来维护信任IP列表:
- KVM名称:比如
TrustedIPs - 添加键
trusted_ips,值为逗号分隔的IP/CIDR地址(例如192.168.1.1,10.0.0.0/24,172.16.0.5)
2. 添加LookupKVM Policy
创建一个LookupKVM Policy(命名为LookupTrustedIPs),用于从KVM中读取信任IP列表:
<LookupKVM name="LookupTrustedIPs"> <Scope>environment</Scope> <Key>trusted_ips</Key> <VariablePrefix>trusted</VariablePrefix> </LookupKVM>
3. 添加IP校验JavaScript Policy
创建一个JavaScript Policy(命名为CheckTrustedIP),判断当前请求的client.ip是否在信任列表中(支持精确IP和CIDR范围匹配):
var clientIp = context.getVariable('client.ip'); var trustedIps = context.getVariable('trusted.trusted_ips').split(','); var isTrusted = false; trustedIps.forEach(function(ipEntry) { var ip = ipEntry.trim(); // 精确IP匹配 if (ip === clientIp) { isTrusted = true; return; } // CIDR范围匹配 if (ip.includes('/')) { var [cidrIp, prefixStr] = ip.split('/'); var prefix = parseInt(prefixStr, 10); if (isIpInCidr(clientIp, cidrIp, prefix)) { isTrusted = true; return; } } }); // 设置标记变量,供后续步骤判断 context.setVariable('is_trusted_ip', isTrusted); // 辅助函数:将IP转换为整数 function ipToInt(ip) { return ip.split('.').reduce((int, octet) => (int << 8) + parseInt(octet, 10), 0) >>> 0; } // 辅助函数:判断IP是否在CIDR范围内 function isIpInCidr(targetIp, cidrIp, prefix) { var targetInt = ipToInt(targetIp); var cidrInt = ipToInt(cidrIp); var mask = -1 << (32 - prefix); return (targetInt & mask) === (cidrInt & mask); }
4. 修改PreFlow添加条件判断
更新你的PreFlow,先执行信任IP校验步骤,再给Spike Arrest/Quota步骤添加条件,仅当is_trusted_ip为false时执行:
<PreFlow name="PreFlow"> <Request> <!-- 读取信任IP列表 --> <Step> <Name>LookupTrustedIPs</Name> </Step> <!-- 判断当前IP是否为信任IP --> <Step> <Name>CheckTrustedIP</Name> </Step> <!-- 仅非信任IP执行Spike Arrest --> <Step> <Name>SpikeArrest.SpikeArrest</Name> <Condition>!is_trusted_ip</Condition> </Step> <!-- 同样逻辑应用到Quota --> <Step> <Name>Quota.Quota</Name> <Condition>!is_trusted_ip</Condition> </Step> </Request> <Response/> </PreFlow>
5. 确认Spike Arrest配置
你的Spike Arrest配置已经正确设置了按client.ip分组限流,无需额外修改:
<SpikeArrest name="SpikeArrest.SpikeArrest"> <Rate>20PS</Rate> <UseEffectiveCount>true</UseEffectiveCount> <Identifier ref="client.ip"/> </SpikeArrest>
补充说明
- 如果不需要CIDR范围匹配,可以删除JavaScript中的CIDR校验逻辑,只保留精确IP匹配,简化代码。
- KVM支持环境级/组织级/代理级,根据你的维护需求选择合适的Scope。
- Quota的条件化执行逻辑和Spike Arrest完全一致,只需给Quota步骤添加相同的
<Condition>即可。
内容的提问来源于stack exchange,提问作者pity-the-fool
相关产品推荐
相关产品推荐

