考虑一个由多个相互通信的 Web 服务(可能是微服务)组成的软件系统。在某个用例的过程中,客户端向外部服务 A 发送 POST Web 请求,而外部服务 A 又需要向内部服务 B 发送 POST Web 请求。
如果服务 B 当前不可用,例如返回 HTTP 503,服务 A 将执行内部重试一段时间,以尝试应对其依赖项的中断。
现在,如果重试未能解决问题,那么服务 A 的最佳实践是什么?它还应该返回 503 来指示不可用吗?或者也许是 502,因为它“充当网关”?
客户应该做什么?这很容易导致重试级联。 OTOH,许多 HTTP 客户端库(例如,Microsoft.Extensions.Http.Resilience)会在出现 any 5xx 错误时重试,所以也许这并不重要?
我希望这个问题不会被认为是基于意见的 - 当然,随着面向服务和微服务架构已经存在了一段时间,对于这种常见场景一定有一些标准模式?
(当然,理想情况下,服务 A 不应该同步依赖于服务 B - 就弹性而言,异步消息传递才是王道。但是,我们假设这是一个同步用例,并且将其重构为异步用例是不可行的由于 POST 请求具有所需的副作用,因此我们也不能仅仅通过缓存或数据复制来解决问题。)据我所知,这种情况没有事实上的标准状态代码。一般来说,以下 HTTP 状态通常被认为是可重试的状态,因为它们代表一些暂时性问题:
408(请求超时)
RetryAfter
301(永久移动)
带有
RetryAfter
502 和 504 也可以被视为此场景的有效状态代码。由于您的服务 A 充当代理,并且两个状态代码都表明在请求处理期间存在一些上游问题:
收到502无效响应
来防止级联故障。对于这种情况,建议的解决方案是使用
断路器