C# 波利+;作为结果返回错误的API服务
我正在使用一个web API,如果查询一个不存在的数据,它将返回代码404;如果数据格式不正确或者存在其他问题,它将返回其他错误。这将导致HttpRequestException 现在我在考虑一个细节。我在HttpClient连接上使用Polly,以确保在出现通信问题时重试 在这种情况下,它是否会像预期的那样工作,或者在服务器抛出错误(如“未找到”或“错误请求”)时,Polly是否会继续重试 我正在这样配置它C# 波利+;作为结果返回错误的API服务,c#,.net,asp.net-core,polly,C#,.net,Asp.net Core,Polly,我正在使用一个web API,如果查询一个不存在的数据,它将返回代码404;如果数据格式不正确或者存在其他问题,它将返回其他错误。这将导致HttpRequestException 现在我在考虑一个细节。我在HttpClient连接上使用Polly,以确保在出现通信问题时重试 在这种情况下,它是否会像预期的那样工作,或者在服务器抛出错误(如“未找到”或“错误请求”)时,Polly是否会继续重试 我正在这样配置它 services.AddHttpClient<OntraportHttpClie
services.AddHttpClient<OntraportHttpClient>()
.AddTransientHttpErrorPolicy(p =>
p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));
services.AddHttpClient()
.AddTransientTTPerorPolicy(p=>
p、 WaitAndRetryAsync(3,=>TimeSpan.Fromms(600));
您有一点误解,400错误请求或404未找到不会导致HttpRequestException
除非你明确地打电话
将检查以下各项:
- 408超时
- 5xx服务器错误
- HttpRequestException
ensureccessstatuscode
方法
更新:添加删除用例 用例 假设我们有一个REST服务,它公开了给定资源的删除功能(通过特定URL和DELETE HTTP谓词寻址) 从消费的角度来看,这种移除可能会在以下三种不同状态中的一种状态下结束:
- 成功
- 已经做了
- 失败
HttpRequestException
)。如果数据库中断,并且服务能够检测到,那么它可以快速故障并返回5XX响应,或者尝试故障转移。如果有太多未决请求,那么服务可以考虑节流它们,并使用背压来卸载负载。它可能返回429(请求太多)以及相应的重试后的标题
永久性错误,如服务已永久关闭或TLS 1.3下主动拒绝网络连接尝试,需要人工干预才能修复
幂等性
当我们谈论重试模式时,我们需要考虑以下内容:
- 潜在引入的可观察影响是可接受的
- 该操作可以重新进行,没有任何不可逆的副作用
- 与承诺的可靠性相比,引入的复杂性可以忽略不计
第二个标准通常称为幂等性。它说,如果您使用相同的输入多次调用方法/端点,那么它应该返回相同的输出,而不会产生任何副作用
如果可以将服务的删除功能视为幂等项,则不存在已完成的状态。如果你叫它100次,那么它应该总是返回“是的,那已经过去了”。因此,考虑到这一点,在幂等删除的情况下,返回204或404可能是有意义的
弹性策略
每当我们谈论战略时,对我来说,这意味着一系列弹性政策。如果前一个政策无法“解决”问题,那么后一个政策将尝试这样做(因此存在政策升级)
服务器端:您可以使用Bulk head策略控制最大并发调用数,但如果超过阈值,则可以开始限制请求
客户端:您可以为每个单独的请求设置一个超时,并且可以在临时/暂时失败的情况下应用重试策略。您还可以为所有重试尝试定义全局超时。或者,如果服务被视为超负荷或故障,您可以应用断路器来监控连续故障,并在给定的时间段内退出
我的2美分是在客户端应用一个单一的弹性策略,这可能不足以拥有一个强健的弹性系统。可能需要几个策略(双方)才能为有问题的时段建立通信协议。我确实调用了EnsureResccessStatusCode,这会是个问题吗?@EtienneCharland,这取决于具体情况。例如,如果您使用DELETE
调用端点,则404是绝对有效的响应。因此,在这种情况下,重试是没有意义的。在我看来,同样的情况也适用于坏请求,如果您发布的负载包含无效/格式错误的数据,那么重试不会改变响应状态。因此,我要问这个问题。在这种情况下,Polly会让它重试404删除吗?这将给我留下两个选项,一个是避免调用EnsureAccessStatusCode并以另一种方式返回响应代码,另一个是以不同的方式配置Polly?@EtienneCharland我用删除用例扩展了我的答案。请检查一下。