在 ASP.NET 核心中使用时 Polly Bulkhead 出现意外行为
Polly Bulkhead unexpected behavior when using in ASP.NET Core
这是我的舱壁政策:
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
它应该只允许 4 个并发任务 execute/wait 执行。
但是,我最终得到了 6 个任务,这些任务能够通过舱壁政策运行。
这是我的控制器操作:
[HttpGet("bulkhead")]
public async Task<object> Bulkhead()
{
Console.WriteLine(DateTime.UtcNow);
var bhCount = _policyManager.BulkheadPolicy.BulkheadAvailableCount;
var queueCount = _policyManager.BulkheadPolicy.QueueAvailableCount;
// The policy is used here
await _policyManager.BulkheadPolicy.ExecuteAsync(async (context) =>
{
await Task.Delay(10000);
}, new Context());
return new
{
bhCount,
queueCount
};
}
在我的浏览器中,我使用这个脚本模拟了 14 个并发任务:
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead')
.then(result=>console.log(result));
}
应该只产生 4 个 200OK
响应。但是,我最终收到了 6 200OK
条回复。
我 运行 多次测试并得到相同的结果。有没有人知道为什么相同的行为适用于控制台应用程序?我在这里错过了什么吗?非常感谢。
更新 1:
这是我的IPolicyManager
界面
public interface IPolicyManager
{
AsyncBulkheadPolicy BulkheadPolicy { get; }
}
public class PolicyManager : IPolicyManager
{
public PolicyManager()
{
Init();
}
public AsyncBulkheadPolicy BulkheadPolicy { get; private set; }
private void Init()
{
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
}
}
更新 2:
当我发送固定请求(固定 URL)时,它失败得非常慢,但是当我在请求中附加一个 运行dom 参数时,结果符合预期(快速失败,只有 4 个请求可以继续).
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead?count=' + i)
.then(result=>console.log(result));
}
事实证明,浏览器的行为并不像预期的那样。我编写了一个执行相同任务的控制台应用程序并且运行良好:快速失败并且一次只能处理 4 个请求。
所以我可以确认这不是 Polly 或 ASP.NET Core 的问题。
可能跟浏览器的缓存机制有关(我用的是Edge):https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
这是我的舱壁政策:
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
它应该只允许 4 个并发任务 execute/wait 执行。
但是,我最终得到了 6 个任务,这些任务能够通过舱壁政策运行。
这是我的控制器操作:
[HttpGet("bulkhead")]
public async Task<object> Bulkhead()
{
Console.WriteLine(DateTime.UtcNow);
var bhCount = _policyManager.BulkheadPolicy.BulkheadAvailableCount;
var queueCount = _policyManager.BulkheadPolicy.QueueAvailableCount;
// The policy is used here
await _policyManager.BulkheadPolicy.ExecuteAsync(async (context) =>
{
await Task.Delay(10000);
}, new Context());
return new
{
bhCount,
queueCount
};
}
在我的浏览器中,我使用这个脚本模拟了 14 个并发任务:
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead')
.then(result=>console.log(result));
}
应该只产生 4 个 200OK
响应。但是,我最终收到了 6 200OK
条回复。
我 运行 多次测试并得到相同的结果。有没有人知道为什么相同的行为适用于控制台应用程序?我在这里错过了什么吗?非常感谢。
更新 1:
这是我的IPolicyManager
界面
public interface IPolicyManager
{
AsyncBulkheadPolicy BulkheadPolicy { get; }
}
public class PolicyManager : IPolicyManager
{
public PolicyManager()
{
Init();
}
public AsyncBulkheadPolicy BulkheadPolicy { get; private set; }
private void Init()
{
BulkheadPolicy = Policy
.BulkheadAsync(maxParallelization: 2,
maxQueuingActions: 2, onBulkheadRejectedAsync: (context) =>
{
Console.WriteLine("Rejected");
return Task.CompletedTask;
});
}
}
更新 2: 当我发送固定请求(固定 URL)时,它失败得非常慢,但是当我在请求中附加一个 运行dom 参数时,结果符合预期(快速失败,只有 4 个请求可以继续).
for (var i = 0; i < 14; i++) {
fetch('https://localhost:44313/api/Bulkheads/bulkhead?count=' + i)
.then(result=>console.log(result));
}
事实证明,浏览器的行为并不像预期的那样。我编写了一个执行相同任务的控制台应用程序并且运行良好:快速失败并且一次只能处理 4 个请求。 所以我可以确认这不是 Polly 或 ASP.NET Core 的问题。 可能跟浏览器的缓存机制有关(我用的是Edge):https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching