- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我编写了一个基于重试的弹性策略和一个断路器策略。现在工作正常,但其行为存在问题。
我注意到当断路器处于半开
时,onBreak()
事件再次被执行以关闭电路,触发了一次额外的重试对于重试策略(这是健康验证
之外的半开
状态)。
让我一步一步解释:
我已经为重试和断路器定义了两个强类型策略:
static Policy<HttpResponseMessage> customRetryPolicy;
static Policy<HttpResponseMessage> customCircuitBreakerPolicy;
static HttpStatusCode[] httpStatusesToProcess = new HttpStatusCode[]
{
HttpStatusCode.ServiceUnavailable, //503
HttpStatusCode.InternalServerError, //500
};
重试策略以这种方式工作:每个请求重试两 (2) 次,每次重试之间等待五 (5) 秒。如果内部断路器断开,不得重试。仅重试 500 和 503 Http 状态。
customRetryPolicy = Policy<HttpResponseMessage>
//Not execute a retry if the circuit is open
.Handle<BrokenCircuitException>( x =>
{
return !(x is BrokenCircuitException);
})
//Stop if some inner exception match with BrokenCircuitException
.OrInner<AggregateException>(x =>
{
return !(x.InnerException is BrokenCircuitException);
})
//Retry if status are:
.OrResult(x => { return httpStatusesToProcess.Contains(x.StatusCode); })
// Retry request two times, wait 5 seconds between each retry
.WaitAndRetry( 2, retryAttempt => TimeSpan.FromSeconds(5),
(exception, timeSpan, retryCount, context) =>
{
System.Console.WriteLine("Retrying... " + retryCount);
}
);
断路器策略以这种方式工作:允许连续最多三 (3) 次故障,然后打开电路三十 (30) 秒。开路仅适用于 HTTP-500。
customCircuitBreakerPolicy = Policy<HttpResponseMessage>
// handling result or exception to execute onBreak delegate
.Handle<AggregateException>(x =>
{ return x.InnerException is HttpRequestException; })
// just break when server error will be InternalServerError
.OrResult(x => { return (int) x.StatusCode == 500; })
// Broken when fail 3 times in a row,
// and hold circuit open for 30 seconds
.CircuitBreaker(3, TimeSpan.FromSeconds(30),
onBreak: (lastResponse, breakDelay) =>{
System.Console.WriteLine("\n Circuit broken!");
},
onReset: () => {
System.Console.WriteLine("\n Circuit Reset!");
},
onHalfOpen: () => {
System.Console.WriteLine("\n Circuit is Half-Open");
});
最后,这两个策略以这种方式嵌套:
try
{
customRetryPolicy.Execute(() =>
customCircuitBreakerPolicy.Execute(() => {
//for testing purposes "api/values", is returning 500 all time
HttpResponseMessage msResponse
= GetHttpResponseAsync("api/values").Result;
// This just print messages on console, no pay attention
PrintHttpResponseAsync(msResponse);
return msResponse;
}));
}
catch (BrokenCircuitException e)
{
System.Console.WriteLine("CB Error: " + e.Message);
}
我期望的结果是什么?
看图片:
我正在尝试理解这种行为。为什么当断路器打开第二次、第三次、...、N 次时,还要执行一次额外的重试?
我已经查看了重试的机器状态模型和断路器策略,但我不明白为什么要执行此额外的重试。
断路器的流程: https://github.com/App-vNext/Polly/wiki/Circuit-Breaker#putting-it-all-together-
重试策略的流程: https://github.com/App-vNext/Polly/wiki/Retry#how-polly-retry-works
这真的很重要,因为等待重试的时间(本例为 5 秒),最后,这对于高并发来说是浪费时间。
任何帮助/指导,将不胜感激。非常感谢。
最佳答案
与 Polly.Context您可以在两个策略之间交换信息(在您的情况下:重试和断路器)。上下文基本上是一个 Dictionary<string, object>
.
所以,诀窍是在 onBreak
上设置一个键然后在 sleepDurationProdiver
中使用该值.
让我们从内部断路器策略开始:
static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
return Policy<HttpResponseMessage>
.HandleResult(res => res.StatusCode == HttpStatusCode.InternalServerError)
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(2),
onBreak: (dr, ts, ctx) => { ctx[SleepDurationKey] = ts; },
onReset: (ctx) => { ctx[SleepDurationKey] = null; });
}
Open
状态 2 秒,然后过渡到 HalfOpen
durationOfBreak
在上下文中设置一个键值(value)Closed
state ( onReset
) 它删除这个值现在,让我们继续重试策略:
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return Policy<HttpResponseMessage>
.HandleResult(res => res.StatusCode == HttpStatusCode.InternalServerError)
.Or<BrokenCircuitException>()
.WaitAndRetryAsync(4,
sleepDurationProvider: (c, ctx) =>
{
if (ctx.ContainsKey(SleepDurationKey))
return (TimeSpan)ctx[SleepDurationKey];
return TimeSpan.FromMilliseconds(200);
},
onRetry: (dr, ts, ctx) =>
{
Console.WriteLine($"Context: {(ctx.ContainsKey(SleepDurationKey) ? "Open" : "Closed")}");
Console.WriteLine($"Waits: {ts.TotalMilliseconds}");
});
}
BrokenCircuitException
时Open
状态),则它会在 200 毫秒后返回Open
状态),则它返回上下文中的值
onRetry
中向控制台打印一些值仅用于调试目的最后让我们连接策略并测试它
const string SleepDurationKey = "Broken";
static HttpClient client = new HttpClient();
static async Task Main()
{
var strategy = Policy.WrapAsync(GetRetryPolicy(), GetCircuitBreakerPolicy());
await strategy.ExecuteAsync(async () => await Get());
}
static Task<HttpResponseMessage> Get()
{
return client.GetAsync("https://httpstat.us/500");
}
Get
异步方法handledEventsAllowedBeforeBreaking
是2输出
Context: Closed
Waits: 200
Context: Open
Waits: 2000
Context: Open
Waits: 2000
Context: Open
Waits: 2000
handledEventsAllowedBeforeBreaking
是3输出
Context: Closed
Waits: 200
Context: Closed
Waits: 200
Context: Open
Waits: 2000
Context: Open
Waits: 2000
handledEventsAllowedBeforeBreaking
是4输出
Context: Closed
Waits: 200
Context: Closed
Waits: 200
Context: Closed
Waits: 200
Context: Open
Waits: 2000
关于c# - 使用 Polly.Net 的嵌套重试和断路器策略的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69534878/
创建使用.NET框架的asp.net页面时,访问该页面的客户端是否需要在其计算机上安装.NET框架? IE。用户访问www.fakesite.com/default.aspx,如果他们没有安装框架,他
我阅读了很多不同的博客和 StackOverflow 问题,试图找到我的问题的答案,但最后我找不到任何东西,所以我想自己问这个问题。 我正在构建一个应用程序,其中有一个长时间运行的工作线程,它执行一些
已锁定。这个问题及其答案是locked因为这个问题是题外话,但却具有历史意义。目前不接受新的答案或互动。 我一直想知道为什么微软为这样一个伟大的平台选择了一个如此奇怪的、对搜索引擎不友好的名称。他们就
.Net Framework .Net .NET Standard的区别 1、.NET Framework 在未来.NET Framework或许成为过去时,目前还是有很多地方在使用的。这一套
如果有选择的话,您会走哪条路? ASP.NET Webforms + ASP.NET AJAX 或 ASP.NET MVC + JavaScript Framework of your Choice
我有一个 Web 服务,它通过专用连接通过 https 使用第三方 Web 服务,我应用了 ServicePointManager.ServerCertificateValidationCallbac
为什么我应该选择ASP.NET Web Application (.NET Framework)而不是ASP.NET Core Web Application (.NET Framework)? 我在
我在网络上没有找到任何关于包含 .NET Standard、.NET Core 和 .NET Framework 项目的 .NET 解决方案的公认命名约定。 就我而言,我们在 .NET 框架项目中有以
.NET Compact 是 .NET 的完美子集吗? 假设我考虑了屏幕大小和其他限制并避免了 .NET Compact 不支持的类和方法,或者 .NET Compact 是一个不同且不兼容的 GUI
我已经阅读了所有我能找到的关于 connectionManagement 中的 maxconnection 设置的文章:即 http://support.microsoft.com/kb/821268
我现在正在使用asp.net mvc,想知道使用内置的Json或 Json.Net哪个是更好的选择,但我不确定一个人是否比另一个人有优势。 另外,如果我确实选择沿用Json.Net的路线,那么我应该选
在 Visual Studio 中,您至少可以创建三种不同类型的类库: 类库(.NET Framework) 类库(.NET 标准) 类库(.NET Core) 虽然第一个是我们多年来一直使用的,但我
.NET 和 ASP.NET 之间有什么区别?它们有什么关系? 最佳答案 ASP.Net 基于 .Net 框架构建,提供有关 Web 开发的附加功能。 你可以去看看wikipedia article
在安装更高版本(3.0)之前,我需要安装.net框架1.1和2.0吗?或者单独安装 3.0 框架就足够了,并为在早期框架版本上编写的软件提供支持?谢谢 ,丽然 最佳答案 不,您不必安装以前的框架。 我
我正在开发一个项目,人们可以“更新”类别,例如更改类别的名称。我收到以下消息 This is called after clicking update 按钮 with the SQL statemen
.NET 类 System.Net.CookieContainer 线程安全吗? --更新:交 key 答复-- 是否有任何方法可以确保异步请求期间修改的变量(即 HttpWebRequest.Coo
我正在使用 JScript.NET 在我编写的 C# WinForms 应用程序中编写脚本。它工作得很好,但我只是尝试在脚本中放置一些异常处理,但我无法弄清楚如何判断我的 C# 代码抛出了哪种类型的异
我需要你的帮助, 比如我有一个小数类型的变量,我想这样取整。 例如 3.0 = 3 3.1 = 4 3.2 = 4 3.3 = 4 3.4 = 4 3.5 = 4 3.6 = 4 3.7 = 4 3.
我使用过这样的代码:http://msdn.microsoft.com/en-us/library/dw70f090.aspx在 ASP.NET 中工作之前访问数据库(2-3 年前)。我没有意识到我正
自 ConfigurationManager .NET Standard 中不存在,检索正在执行的程序集的应用程序设置的最佳方法是什么,无论是 web.config或 appSettings.{env
我是一名优秀的程序员,十分优秀!