ASP.NET Core中使用Polly Bulkhead策略并发放行不符合预期问题
问题根因
你遇到的不符合预期的表现核心是浏览器端的同域请求并发限制导致,和Polly策略本身、服务端配置无关:
- 主流Chrome、Edge等浏览器默认对同一域名下的请求,最多同时发起6个并发连接,完全相同URL的GET请求还会有额外的排队优化,超出限制的请求会在浏览器本地队列暂存,不会立刻发送到服务端。
- 不带随机参数测试时,14个请求只有前6个会立刻发往服务端,剩下8个在浏览器排队等待,所以出现请求失败速度慢的表现。你拿到的6个200刚好匹配浏览器的并发上限,其中部分请求实际是前一批被拒绝、后续浏览器重新发送后刚好赶上策略空位才执行成功的。
- 追加随机参数后,浏览器认为每个请求URL都不同,不会触发同URL排队逻辑,14个请求会一次性全部发往服务端,Polly策略立刻放行4个、拒绝剩下10个,完全符合你的配置预期。
注意事项
- 确认
PolicyManager在DI容器中为单例注册:必须使用AddSingleton<IPolicyManager, PolicyManager>(),如果注册为Scoped或Transient,每个请求都会创建独立的Bulkhead策略,完全无法起到限流作用。 - 当前代码未捕获Polly的
BulkheadRejectedException,策略拒绝请求时会直接抛出异常,默认返回500状态码。如果需要自定义拒绝响应,可以在接口中捕获异常,或者搭配Fallback策略使用:
// 组合Fallback策略示例 var combinedPolicy = Policy.WrapAsync( Policy.Handle<BulkheadRejectedException>() .FallbackAsync(async (ctx, ct) => { // 自定义拒绝逻辑 context.Response.StatusCode = 429; await context.Response.WriteAsync("请求过多,请稍后重试"); }), _policyManager.BulkheadPolicy );
- 服务端接口压测不要使用浏览器fetch脚本,建议使用Postman、JMeter、ab等专业压测工具,可以完全规避浏览器端的并发限制、缓存等干扰因素,得到准确的测试结果。
内容的提问来源于stack exchange,提问作者Trần Nam Trung
相关产品推荐
相关产品推荐

