云计算设计模式(十八)——重试模式

简介: 云计算设计模式(十八)——重试模式 启用应用程序来处理预期的,暂时的失败时,它会尝试连接到由透明的重试操作了以前失败的期望,失败的原因是瞬时的服务或网络资源。

云计算设计模式(十八)——重试模式


启用应用程序来处理预期的暂时的失败时,它会尝试连接到透明的重试操作以前失败期望,失败的原因是瞬时的服务或网络资源这种模式可以提高应用程序的稳定性。

背景和问题


通信的应用程序在云中运行的元素必须是可能发生这样的环境中瞬时故障敏感这些故障包括网络连接的过程中出现时,一个服务忙碌的瞬时损失的组件和服务中,服务临时不可用超时。

这些故障一般是自校正的,如果经过一个合适的延迟被重复触发一个故障动作很可能是成功的。例如,数据库服务,它正在处理大量并发请求可以实现节流策略,暂时拒绝,直到它的工作量有所缓和任何进一步的请求。试图访问该数据库的应用程序可能无法连接,但如果它经过一个合适的延迟再次尝试可能会成功。

解决方案


在云中,瞬时故障的情况并不少见和应用应该被设计为优雅透明地处理它们,减少的影响,这种故障可能对应用程序正在执行业务任务。

如果一个应用程序检测到故障时,它试图将请求发送到远程服务它可以通过使用以下策略处理失败
如果故障指示故障不是瞬时的或不太成功,如果重复例如所造成的无效提供凭据的认证失败不可能成功的,无论多少次未遂),应用程序中止操作和报告一个合适的异常。
如果报道具体故障不寻常的罕见的,可能是由于反常的情况,如网络数据包成为损坏,同时它被发送。这种情况下,应用程序可以再次立即重试失败的请求,因为相同的故障是不可能被重复请求将可能是成功的。
如果故障是由一种更加普遍的连接,或“忙”的失败,网络或服务可能需要在短期内同时连接问题纠正或工作积压被清除应用程序应该等待请求重试一个合适的时间

对于比较常见的短暂故障重试期间,应选择以传播从应用程序尽可能均匀的多个实例的请求。可以减少繁忙的业务持续过载的可能性。如果一个应用程序的多个实例不断轰击重试请求的服务,则可能需要该服务更长的时间来恢复。

如果请求仍然失败,应用程序可以等待进一步的时期,再次尝试如果需要的话这个过程可以重复而增加重试的延迟,直到请求某一最大数目已经尝试都失败了。延迟时间可以逐步增加,使用的定时策略,如指数回退,取决于故障的性质可能性,这将在这段时间内被校正。

图1示出了这种模式。如果尝试后预定数量请求不成功,应用程序应将故障为异常,并相应地处理它

图1 - 使用重试模式调用托管服务的操作


应用程序应该所有试图访问远程服务,实现重试政策配套上面列出的策略之一的代码。发送到不同的服务请求会受到不同的政策,有的供应商提供封装这种方法库。这些库通常执行的政策参数化的,应用程序开发人员可以指定,如重试次数重试之间的时间项的值

检测故障和重试失败的操作都应该记录这些故障详细信息的应用程序的代码。这个信息可能是有用的运算符。如果一个服务被频繁报道为不可用或忙往往是因为该服务已耗尽其资源则可以减少与这些故障发生时通过换算该服务的频率例如,如果数据库服务正在不断超载,可能是有利的分区数据库负载分散到多个服务器。

注意:

微软Azure提供了重试模式的广泛支持模式与实践瞬态故障处理块允许应用程序通过一系列的重试策略来处理许多Azure服务瞬态故障微软实体框架版本6提供了用于重新尝试数据库操作此外,许多在Azure Service Bus和Azure存储的API透明地执行重试逻辑

问题和注意事项


在决定如何实现这个模式时,您应考虑以下几点:
重试政策应进行调整,以满足应用故障性质业务需求它可能是更好一些非关键操作失败而不是重试几次,并影响应用程序的吞吐量。例如试图访问远程服务的交互式Web应用程序,这可能是更好的重试之后重试之间只有一个短的延迟数量较少失败并显示一个适当的消息给用户(例如,请稍后“),再次尝试阻止应用程序变得反应迟钝对于批处理应用程序可以是更合适的,以增加重试尝试的次数尝试之间指数增加的延迟
尝试之间最小的延迟大量的重试高攻击重试的政策可能会进一步降低正在接近运行容量的占用。此重试策略可能会影响应用程序的响应,如果它不断地在尝试执行失败的操作,而不是做有用功
•如果一个显著次数的重试请求仍然失败,则可能是更好的应用程序,以防止进一步的请求将要在相同的资源一个周期,并简单地立即报告故障期限届满后,该应用程序可以暂时允许通过一个或多个请求,看看他们是否成功。对于这一策略的详细信息,请参阅断路器格局。
在由它实现了一个重试策略可能需要为幂等的应用程序调用的服务的操作例如发送到服务的请求可以被接收处理成功,但是由于瞬时故障可能无法发送响应,指示该处理已完成。然后在应用程序重试逻辑可能试图重复没有接收到所述第一请求的假定该请求。
•一个请求到服务失败可能由于各种原因提出不同的异常根据故障的性质。一些例外可指示故障,可以非常迅速地得到解决,而另一些可能表明该故障持续时间更长可能是有益的重试策略,调整基于所述异常的类型的重试尝试之间的时间
•考虑如何重试的操作事务的一部分,会影响整体交易的一致性可能是有用的微调对于事务性操作重试政策,最大限度地取得成功的机会,并减少需要撤消所有交易步骤。
•确保所有重试代码是完全针对各种故障条件下进行测试检查它不会严重影响应用程序的性能或可靠性导致在服务和资源的过度负荷产生竞态条件瓶颈。
•实现只在一个失败的操作方面了解重试逻辑例如,如果包含的重试策略任务调用另一个任务还包含一个重试策略这个额外的重试的可加长的延迟的处理。它可能是更好的配置的低级任务失败快速并报告失败返回调用它的任务的原因。然后这个更高级别的任务可以决定如何处理是根据它自己的策略失效
记录所有的连接故障,提示了重试,使潜在的问题与该应用程序,服务或资源可以被识别是很重要的
•研究是最有可能发生于一个服务或资源发现,如果它们有可能是持久终端故障。如果是这样的话,它可能是更好地处理该故障为异常。该应用程序可以报告记录该异常,然后试图通过调用另一个服务,持续或者(如果有一个可用的通过提供降级功能。关于如何检测和处理持久故障的更多信息,请参阅断路器格局。

何时使用这个模式

使用这种模式
当一个应用程序可能会经历短暂的故障,因为它与远程服务进行交互,或访问远程资源这些故障预计将是短暂的并重复以前没有能够成功后续尝试的请求。

这种模式可能不适合
当故障很可能是持久的,因为可能会影响应用程序的响应性。该应用程序可以简单地是浪费时间和资源试图重复请求最有可能失败
•对于处理故障瞬时故障应用程序的业务逻辑引起错误的内部的异常。
作为一种替代解决系统中的可扩展性问题如果一个应用程序有频繁的“忙”的故障,这是通常指示被访问的服务或资源应相应加大

例子


实施例说明重试模式的实现OperationWithBasicRetryAsync方法如下所示,通过TransientOperationAsync方法异步调用外部服务该方法的细节特定于服务,并从样本代码被省略

private int retryCount = 3;
...

public async Task OperationWithBasicRetryAsync()
{
  int currentRetry = 0;

  for (; ;)
  {
    try
    {
      // Calling external service.
      await TransientOperationAsync();
                    
      // Return or break.
      break;
    }
    catch (Exception ex)
    {
      Trace.TraceError("Operation Exception");

      currentRetry++;

      // Check if the exception thrown was a transient exception
      // based on the logic in the error detection strategy.
      // Determine whether to retry the operation, as well as how 
      // long to wait, based on the retry strategy.
      if (currentRetry > this.retryCount || !IsTransient(ex))
      {
        // If this is not a transient error 
        // or we should not retry re-throw the exception. 
        throw;
      }
    }

    // Wait to retry the operation.
    // Consider calculating an exponential delay here and 
    // using a strategy best suited for the operation and fault.
    Await.Task.Delay();
  }
}

// Async method that wraps a call to a remote service (details not shown).
private async Task TransientOperationAsync()
{
  ...
}


调用此方法的声明被包裹在一个循环一个try/ catch块中封装如果调用TransientOperationAsync方法成功,没有抛出异常for循环退出如果TransientOperationAsync方法失败,catch块检查失败的原因,并且如果被认为是一个瞬时错误代码等待一个短暂的延时,然后重试该操作。

在for循环还跟踪该操作已经尝试的次数,并且如果代码失败三次异常被认为是持久。如果该异常不是暂时的,或者长久的catch处理抛出的异常此异常退出for循环,应捕获调用该OperationWithBasicRetryAsync方法的代码

IsTransient方法如下所示,检查是否有特定的一组是相关的,其中所述代码运行环境的异常。一过异常的定义可以根据被访问的资源,并其上执行操作环境的不同而不同。

private bool IsTransient(Exception ex)
{
  // Determine if the exception is transient.
  // In some cases this may be as simple as checking the exception type, in other 
  // cases it may be necessary to inspect other properties of the exception.
  if (ex is OperationTransientException)
    return true;

  var webException = ex as WebException;
  if (webException != null)
  {
    // If the web exception contains one of the following status values 
    // it may be transient.
    return new[] {WebExceptionStatus.ConnectionClosed, 
                  WebExceptionStatus.Timeout, 
                  WebExceptionStatus.RequestCanceled }.
            Contains(webException.Status);
  }

  // Additional exception checking logic goes here.
  return false;
}


 

本文翻译自MSDN: http://msdn.microsoft.com/en-us/library/dn589788.aspx
目录
相关文章
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
4月前
|
存储 安全 JavaScript
云计算浪潮中的网络安全之舵探索Node.js中的异步编程模式
【8月更文挑战第27天】在数字化时代的风帆下,云计算如同一片广阔的海洋,承载着企业与个人的数据梦想。然而,这片海洋并非总是风平浪静。随着网络攻击的波涛汹涌,如何确保航行的安全成为了每一个船员必须面对的挑战。本文将探索云计算环境下的网络安全策略,从云服务的本质出发,深入信息安全的核心,揭示如何在云海中找到安全的灯塔。
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1月前
|
人工智能 边缘计算 云计算
2024.11|云计算行业的商业模式创新方法及实践
截至2024年,全球云计算行业迈入全新阶段,从IaaS到大规模AI模型平台,技术与商业模式不断创新。本文分析全球最新技术进展,探讨云计算商业模式创新策略与实践,解析云服务厂商如何通过技术革新实现价值最大化,推动企业数字化与智能化转型。重点讨论AI与云计算的深度融合、边缘计算与去中心化发展、平台化与生态系统建设,以及数据安全与绿色云计算等关键议题。
91 30
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
42 1
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
32 3
|
3月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
下一篇
DataWorks