• 【Azure API 管理】APIM如何实现对部分固定IP进行访问次数限制呢?如60秒10次请求


    问题描述

    使用Azure API Management, 想对一些固定的IP地址进行访问次数的限制,如被限制的IP地址一分钟可以访问10次,而不被限制的IP地址则可以无限访问?

     

    ChatGPT 解答

    最近ChatGPT爆火,所以也把这个问题让ChatGPT来解答,然后人工验证它的回答正确与否?

    根据对APIM Policy的文档参考, choose 和 rate-limit 策略组合理论上的确可以实现要求, 接下来就让我们实际验证:

     

    验证步骤

    1)在API的Inbound 策略中添加 choose策略

    (策略具体内容,见文末)

    2) 测试验证,连续对该API访问10次以上,得到429 Too Many Requests错误

    3)以上证明,ChatGPT针对这个问题的解答是正确的!

     

    工程师解答

    在参考ChatGPT给出的 choose + rate limit 组合后,我们也发现另一个选项。使用 rate-limit-by-key 策略实现对特定IP的速率限制。

    • rate-limit-by-key 策略https://docs.azure.cn/zh-cn/api-management/api-management-access-restriction-policies#LimitCallRateByKey , 可以对调用速率进行限制,使指定时段的调用不超出指定的数目,避免单个密钥的 API 使用量暴增。 密钥的值可以是任意字符串,通常使用策略表达式来提供密钥。 可以添加可选增量条件,指定在决定是否到达限制值时应该进行计数的请求。 超过此调用速率时,调用方会收到 429 Too Many Requests 响应状态代码。

    在官方文档中给出的示例中,是针对所有的IP(context.Request.IpAddress)都进行了10次/60秒请求的限制,而本示例中则特指“某些固定IP”限制。那么如何来完成这个需求呢?

    答案 就在“rate-limit-by-key 策略”的说明中,”可以添加可选增量条件,指定在决定是否到达限制值时应该进行计数的请求”, 所以,只要可选增量条件(increment-condition) 的值根据输入的IP地址动态赋值True/False, 就能完美匹配以上要求。

     

    理论推断,只需要实现如下逻辑,即可以实现终极需求“想对一些固定的IP地址进行访问次数的限制,如被限制的IP地址一分钟可以访问10次,而不被限制的IP地址则可以无限访问?

    只需两步:

    1)通过设置一个变量(set-variable) 值,用C#代码来计算变量值,在赋值语句中,预先定义一个IP限制列表,通过 contains 检查当前请求IP是否在列表中,返回True or False 。True表示当前请求的IP需要速率限制, 否则,不需要。

    2) 然后,在rate-limit-by-key 的 increment-condition条件中使用上一步参数值,进行判断是否计入限制

    验证步骤

    1)在API的 Inbound 策略中添加 rate-limit-by-key策略

    (策略具体内容,见文末)

     

    2)验证在30秒,访问5次以上后,同样得到429 Too Many Requests错误

     

    3) 当在请求Headers中添加Ocp-Apim-Trace: true 和 Ocp-Apim-Subscription-Key: {订阅Key}后,可以查看请求在APIM中执行的日志跟踪。可以查看rate-limit-by-key 策略的执行情况.

     

    总结

    想实现固定IP地址访问次数的限制,至少有如下两种解决方案。

    方案一:Choose + rate-limit 策略组合

    复制代码
    
    <policies>
        <inbound>
            <base />
            <set-variable name="IsCountIpLimit" value="@{
                    string ipAddress =context.Request.IpAddress; 
    
                    List cidrList = new List(){
                        "167.xxx. xxx.135",
                        "167.xxx. xxx.136",
                        "167.xxx. xxx.137"
                    };
                    return cidrList.Contains(ipAddress);
                    }" />
            <choose>
                <when condition="@((bool)context.Variables["IsCountIpLimit"])">
                    <rate-limit calls="10" renewal-period="60" />
                when>
            choose>
        inbound>
        <backend>
            <base />
        backend>
        <outbound>
            <base />
        outbound>
        <on-error>
            <base />
        on-error>
    policies>
    复制代码

     

    方案二:rate-limit-by-key策略

    复制代码
    
    <policies>
        <inbound>
            <base />
            <set-variable name="IsCountIpLimit" value="@{
                    string ipAddress =context.Request.IpAddress; 
    
                    List limitIPs = new List(){
                        "167.xxx. xxx.135",
                        "167.xxx. xxx.136",
                        "167.xxx. xxx.137"
                    };
    
                    return limitIPs.Contains(ipAddress);
                    }" />
            <rate-limit-by-key calls="5" renewal-period="30" counter-key="@(context.Request.IpAddress)" increment-condition="@(context.Response.StatusCode >= 200 && context.Response.StatusCode < 300 && (bool)context.Variables["IsCountIpLimit"])" />
        inbound>
        <backend>
            <base />
        backend>
        <outbound>
            <base />
        outbound>
        <on-error>
            <base />
        on-error>
    policies>
    复制代码

     

     

    参考资料

    choose策略https://docs.azure.cn/zh-cn/api-management/api-management-advanced-policies#choose 

    rate-limit策略https://docs.azure.cn/zh-cn/api-management/api-management-access-restriction-policies#LimitCallRate ,

    rate-limit-by-key 策略https://docs.azure.cn/zh-cn/api-management/api-management-access-restriction-policies#LimitCallRateByKey 

     

  • 相关阅读:
    数据结构与算法-(10)---列表(List)
    [Gym 102423]-Elven Efficiency | 思维
    Windows下安装RabbitMQ
    java项目接口重复提交解决方案
    java计算机毕业设计社区二手交易平台前台源码+系统+数据库+lw文档+mybatis+运行部署
    【BOOST C++ 12 函数式编程】(4) Boost.Ref
    【Spring源码】18. factory-method创建对象关键函数详解:instantiateUsingFactoryMethod()
    热门Java开发工具IDEA入门指南——IntelliJ IDEA概述(中)
    精心整理16条MySQL使用规范,减少80%问题,推荐分享给团队
    由一个项目引起智能工厂及数字工厂的灵魂拷问
  • 原文地址:https://www.cnblogs.com/lulight/p/17350768.html