在上面的屏幕上选择操作 /api/Order/GetOrderByCustomerWithRetry/(customerCode) 它应该展开,然后单击 Try it out 按钮。之后,您应该会看到以下屏幕,您需要在其中输入客户代码的值并单击执行按钮。
如上所示,单击执行后,我们根据为客户代码输入的值获得了正确客户名称的成功响应。
但是订单服务中的 GetOrderByCustomerWithRetry 操作正在对客户服务进行 HTTP 调用,该调用会随机返回错误,因此让我们检查日志,看看在客户服务中对 GetCustomerNameWithTempFailure 的 HTTP 调用期间发生了什么
正如我们在上面日志的屏幕截图中看到的,当我们从订单服务调用客户服务时,第一次调用返回了一个错误,但由于我们已经配置了重试策略并且它被重试,并且在第一次重试时客户服务返回成功响应并带有正确的客户名称根据客户代码的价值。因此,通过在订单服务中使用重试策略,我们能够处理客户服务中的临时故障。
超时策略根据 name 的定义,此策略建议您需要在设置的时间限制内没有来自其他服务的响应的情况下终止请求。
考虑从订单服务到客户服务的 HTTP 请求被延迟的场景。来自客户服务的此错误可能永无止境,因为客户服务可能正在等待来自慢速/挂起数据库的响应或来自第三方服务的响应,并且客户服务尚未为这些调用实现超时。
要处理延迟响应,您需要添加逻辑以在设定的时间限制过后对客户服务的请求超时,以确保订单服务不会无休止地等待客户服务的响应,因为它会使线程永远忙碌。这种无休止的等待也会对订单服务产生级联效应,并可能耗尽订单服务服务器上的所有可用资源。
按照这个超时逻辑,订单服务会向客服请求客户名称,如果客服在设定的时限内没有得到响应,那么订单服务假设现在没有机会得到客户的成功响应服务,因此它终止或超时请求并采取适当的行动并返回响应。
要模拟客户服务响应的延迟,请将以下操作方法添加到客户服务中。此方法在 2 分钟延迟后返回响应。为了实现这种行为,我们使用了 Thread 类中的 sleep 方法,该方法在指定的时间内停止线程执行。
所以这个客户服务操作方法 GetCustomerNameWithDelay 将延迟响应 2 分钟以订购服务。
[HttpGet] [Route("GetCustomerNameWithDelay/{customerCode}")] public ActionResult<string> GetCustomerNameWithDelay(int customerCode) { Thread.Sleep(new TimeSpan(0, 2, 0)); if (_customerNameDict != null && _customerNameDict.ContainsKey(customerCode)) { return _customerNameDict[customerCode]; } return "Customer Not Found"; }要在 ASP.NET Core 中使用 Polly 实现超时逻辑,我们需要声明 TimeoutPolicy 类型的对象并定义策略,如下面的代码所示
private static TimeoutPolicy _timeoutPolicy; public OrderController(ILogger<OrderController> logger, IHttpClientFactory httpClientFactory) { _timeoutPolicy = Policy.Timeout(20, TimeoutStrategy.Pessimistic); }上面的代码示例将创建一个超时策略,该策略将等待响应 20 秒,在 20 秒后,它将假定不可能成功响应并且将超时请求,即应放弃执行委托或函数。
ASP.NET Core 中 Polly 中的超时策略支持乐观和悲观超时。建议尽可能使用乐观超时,因为它消耗的资源较少。
乐观 - 假设您执行的委托支持取消,并且委托通过抛出异常来表达该超时
悲观 - 认识到在某些情况下您可能需要执行没有内置超时的委托,并且不接受取消,即调用者停止等待底层委托完成