限制用户

时间:2017-07-27 08:44:31

标签: azure parallel-processing rate-limiting azure-api-management

我想限制我的产品:

  • starter:没有并行调用(只允许同步调用)
  • premium:10个并行调用(允许带限制的异步调用)

api网关背后的服务需要一些时间,所以有些人想要进行异步调用以获得更多结果。

我从azure中发现的唯一限制是费率和配额限制。但它们的限制是每次调用,我需要并行调用。

我想到了这个逻辑:

<inbound>
<http-call>
send user id to a azure function, that increases the counter for the user, returns the current counter
</http-call>
<when>
compare counter value with the product limit (x = 0 for starter or x <= 10 for premium)
if true route to the service, if false generate a "too many requests" response
</when>
</inbound>

<outbound>
<http-call>
decrease the counter
</http-call>
</outbound>

我不确定这是否是最好的逻辑,因为函数需要时间来更新值。有没有办法保存某种&#34;共享变量&#34;,每个请求都可以访问api管理中的计数器,而不是外部函数?

1 个答案:

答案 0 :(得分:0)

我找到了一种缓存方式(我认为缓存功能是全局的,但它没有得到证实。你只需要一个缓存的数组,user-id作为键并重视并行请求的数量):

<inbound>
        <set-variable name="user-id" value="@(context.User.Id)" />
        <!--Look for user-counter for this user in the cache -->
        <cache-lookup-value key="@("user-counter-" + context.Variables["user-id"])" variable-name="user-counter" />
        <choose>
            <!-- check the limit -->
            <when condition="@(context.Variables.ContainsKey("user-counter"))">
                <choose>
                    <!-- -->
                    <when condition="@((int)context.Variables["user-counter"] > 0)">
                        <return-response>
                            <set-status code="429" reason="TOO MANY REQUESTS" />
                            <set-body>too many parallel requests</set-body>
                        </return-response>
                    </when>
                    <when condition="@((int)context.Variables["user-counter"] <= 0)">
                        <cache-store-value key="@("user-counter-" + context.Variables["user-id"])" value="@((int)context.Variables["user-counter"] + 1)" duration="100000" />
                    </when>
                </choose>
            </when>
            <!-- If we don’t find it in the cache, create it with the value 1 -->
            <when condition="@(!context.Variables.ContainsKey("user-counter"))">
                <cache-store-value key="@("user-counter-" + context.Variables["user-id"])" value="0" duration="100000" />
            </when>
        </choose>
</inbound>

<outbound>
        <base />
        <!-- remove user-counter -->
        <cache-lookup-value key="@("user-counter-" + context.Variables["user-id"])" variable-name="user-counter-old" />
        <cache-store-value key="@("user-counter-" + context.Variables["user-id"])" value="@((int)context.Variables["user-counter-old"] - 1)" duration="100000" />
</outbound>
相关问题