asp.net-core - 基于请求条件的断路器
问题描述
我需要设置断路器策略,以便它仅针对某些特定请求断开电路。
我有一种网关A调用 API B,后者又调用C或D。我正在 A 中设置断路器策略。到达 A 的初始请求有一个参数,稍后用于决定是调用C还是D,比如说http://gateway.A.com?usageParam=C
。我想以这样的方式配置断路器,该电路可以为C和D单独打开。我的意思是,如果D失败,调用 withusageParam=D
应该立即失败,但usageParam=C
应该仍然可以正常进行,反之亦然。
解决方案
简单地说,断路器只能有一个状态。其中之一:Closed
, Open
, Half-Open
.
您应该将 CB 视为代理。如果下游系统被认为是健康的,它允许每个请求通过它。如果 CB 检测到瞬时故障(通过检查响应(如果有)),那么它将通过拒绝所有请求来缩短执行。
因此,如果您想区分下游系统的健康状况C
,D
那么您需要两个 CB(每个一个)。这允许您分别允许或拒绝针对不同子系统的传出请求。
选项 A
您可以将两个 CB 放在 serviceA
中。在这里,您可以注册两个命名的 HttpClient,它们装饰有不同的断路器:
private IAsyncPolicy<HttpResponseMessage> GetCBPolicy()
=> HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(2, TimeSpan.FromSeconds(1));
...
services.AddHttpClient("CService", c => {
c.BaseAddress = new Uri(BServiceBasePath);
...
})
.AddPolicyHandler(GetCBPolicy());
services.AddHttpClient("DService" c => {
c.BaseAddress = new Uri(BServiceBasePath);
...
})
.AddPolicyHandler(GetCBPolicy());
但是您必须手动进行路由,如下所示:
if(!Context.Request.Query.TryGetValue("usageParam", out var usage))
return;
HttpClient client = usage switch
{
"C" => _clientFactory.CreateClient("CService"),
"D" => _clientFactory.CreateClient("DService"),
_ => throw new NotSupportedException("..."),
};
选项 B
您可以将两个 CB 放在 serviceB
中。在这里,您可以注册两个类型化的 HttpClient,它们装饰有不同的断路器:
private IAsyncPolicy<HttpResponseMessage> GetCBPolicy()
=> HttpPolicyExtensions
.HandleTransientHttpError()
.CircuitBreakerAsync(2, TimeSpan.FromSeconds(1));
...
services.AddHttpClient<ICService, CService>()
.AddPolicyHandler(GetCBPolicy());
services.AddHttpClient<IDService, DService>()
.AddPolicyHandler(GetCBPolicy());
推荐阅读
- javascript - 在 React Redux Saga 中,API 在循环中被多次调用
- java - 使用 OpenJDK 11 读取带有蓝色棱镜(java 模式)的表时出错
- cocoa - PDFDocument 可能存在的编码问题
- node.js - 使用nodejs和rest api调用和express进行异步处理-序列错误
- python - Ansible 和 Opennebula:这个模块需要 pyone 才能工作
- android - 具有 Android 架构导航的动态功能模块之间的 startActivityForResult()
- python-3.x - 在 Python 中将十六进制数据转换为可读字符串
- wordpress - 将 API 请求重定向到子域 htaccess
- selenium - 当单独运行 appium 测试脚本时,它们运行良好,但是当它们一起运行时,它们会抛出错误
- r - R6 传递一个 self$FUN 作为参数