如果用户ID仅存储在请求正文的实体中,如何为每个用户设置.NET 7 C#速率限制器?

3

有一个API可以接受具有先前未知ID的实体。我需要配置速率限制器,以便具有相同ID的实体进入队列。我已经想出如何创建窗口和队列。如何为每个ID创建单独的队列?

实体是一个JSON文件。 ID在文件内部。

以下内容已编写,但这形成了一个队列:

services.AddRateLimiter(options => options
            .AddFixedWindowLimiter(policyName: "UserPolicy", options =>
            {
                options.PermitLimit = 1;
                options.Window = TimeSpan.FromSeconds(10);
                options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
                options.QueueLimit = 3;
            }));
1个回答

3
你可以尝试使用PartitionedRateLimiter。以下是类似的示例(未经测试):
builder.Services.AddRateLimiter(options =>
{
    options.AddPolicy("myRateLimiter1", context =>
    {
        var request = context.Request;
        var partitionKey = "";
        if (request.Method == HttpMethods.Post && request.ContentLength > 0)
        {
            request.EnableBuffering();
            var buffer = new byte[Convert.ToInt32(request.ContentLength)];
            request.Body.Read(buffer, 0, buffer.Length);
            //get body string here...
            var requestContent = Encoding.UTF8.GetString(buffer);
            // get partition key here... partitionKey = ... 
            request.Body.Position = 0;  //rewinding the stream to 0
        }
        return RateLimitPartition.GetFixedWindowLimiter(
            partitionKey: partitionKey,
            factory: partition => new FixedWindowRateLimiterOptions
            {
                PermitLimit = 1,
                Window = TimeSpan.FromSeconds(10),
                QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
                QueueLimit = 3
            });
    });
});

虽然我建议考虑通过其他方式(标题)传递ID,或者在处理程序/BL级别解决限制器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接