云计算设计模式(十九)——运行重构模式

云计算设计模式(十九)——运行重构模式

设计应用程序,使得它可以在不需要重新部署或者重新启动应用程序重新配置。这有助于保持可用性并减少停机时间。

背景和问题

一个主要目的为重要的应用,如商业和企业网站是尽量减少停机时间以及由此引发的中断给客户和用户。但是,有时有必要重新配置应用程序改变特定行为或设置,而在部署和使用。因此,它是用于该应用程序被设计成这样一种方式,以允许在运行时要应用这些配置的变化,并为应用程序,以检测所述变化并且尽快地应用它们的部件的优点。

该种要应用可能被调整记录,以协助与应用程序调试问题,交换使用不同数据存储的连接字符串,或者打开或关闭特定的部分或应用程序的功能的粒度配置变化的例子。

解决方案

为实施这一模式的解决方案依赖于应用程序托管环境中可用的功能。典型地,应用程序代码将响应于由检测到的变化对应用程序配置时,主机基础设施提出的一个或多个事件。这通常是上载新的配置文件,或响应于改变通过管理门户的配置或者通过访问的API的结果。

码处理的配置变化事件可以检查变化,并将其应用到该应用程序的组件。有必要对这些部件进行检测和反应的变化,因此它们的值通常会被公开为可写的属性或方法,在事件处理程序的代码可以设置为新值,或执行。从这一点来说,该部件应使用新的值,以便在需要改变应用程序的行为发生。

如果这是不可能的部件,以应用更改在运行时,这将是必要的,重新启动该应用程序,从而当应用程序启动时再次这些更改应用。在一些托管环境中它可能会检测到这些类型的变化,并指出对环境的应用程序必须重新启动。在其他情况下,可能有必要执行该分析的设置更改,并强制必要的应用程序重新启动时的代码。

图1示出了本模式的概述。

图1 - 此模式的基本概述

大多数环境中暴露响应配置更改引发的事件。在那些不这样做,定期检查更改配置并应用这些变化将是必要的轮询机制。它也可能有必要重新启动应用程序,如果变化不能在运行时被应用。例如,有可能以比较在预设的时间间隔一个配置文件的日期和时间,并运行代码以应用更改时的较新版本中找到。另一种方法是,其中包含一个控制中的应用程序的管理用户界面,或使一个安全端点可以从应用程序外部进行访问,其执行读取,并应用更新的配置的代码。

或者,该应用程序可以反应以在环境中的一些其他变化。例如,发生于特定的运行时错误可能会改变日志配置自动收集更多的信息,或者代码可以使用当前日期读取和应用主题,反映了季节或特殊事件。

问题和注意事项

在决定如何实现这个模式时,请考虑以下几点:
•配置设置必须存储在部署的应用程序之外,使得它们可以在不需要整个包被重新部署更新。典型的设置被存储在配置文件中,或者在外部存储库中,如一个数据库或网络存储。访问运行时配置机制,应严格控制,以及使用时的严格审核。
•如果托管的基础设施不会自动检测配置更改的事件,揭露这些事件对应用程序代码,您必须实现一种替代机制来检测和应用更改。这可以是通过轮询机制,或者通过暴露交互式控制或端点发起更新过程。
•如果您需要实现一个轮询机制,考虑如何经常检查更新的配置应该发生。长轮询间隔将意味着变化可能不被应用了一段时间。短的间隔可能会产生不利影响,通过吸收现有的计算和I
/ O资源的操作。
•如果是应用程序的多个实例,附加的考虑因素,这取决于如何变化进行检测。如果改变是通过由宿主基础结构引发的事件自动检测到,这些变化可能不被同时应用的所有实例进行检测。这意味着,某些情况下,将要使用的原始配置为一个周期,而有些则使用新的设置。如果该更新是通过轮询机制检测到,这必须以保持一致性通信改变到所有实例。
•一些配置的变化可能要求应用程序重新启动,甚至要求托管服务器重新启动。您必须确定这些类型的配置设置和执行的每一个相应的操作。例如,要求应用程序重新启动的变化可能会自动执行此操作,或者它可能是管理员负责发起重新启动在适当的时间时,应用过大的负荷和应用程序可以处理的其他实例下是不的负载。
•更新并确认他们是成功的,而更新的应用程序实例正在执行正确,将更新应用到所有实例之前的分阶段部署计划。由此,能够防止应发生错误的应用程序的总的中断。凡更新需要重新启动或应用程序的重新启动,特别是在应用程序有一个显著启动或热身的时候,用一个分阶段部署的方式,以防止多个实例脱机在同一时间。
•考虑如何将回滚造成的问题配置更改,或导致申请失败。例如,它应该能够滚动的等待轮询间隔,以检测所述变化背部的变化立即代替。
•考虑如何配置设置的位置可能会影响应用程序的性能。例如,你应该处理将发生,如果您使用外部存储不可用的错误,当应用程序启动时,或配置更改将被应用,比如用一个默认的配置或通过本地缓存的设置在服务器和重用这些值而重试访问远程数据存储。
•高速缓存可以帮助减少延迟,如果一个组件需要多次访问配置设置。然而,当配置改变时,应用程序代码将需要无效缓存设置,该组件必须使用更新后的设置。

何时使用这个模式

这种模式非常适合于:
•应用程序,而您必须避免一切不必要的停机时间,同时仍然能够将更改应用到应用程序配置。
•环境,揭露事件自动提出的主要配置更改时。通常,这是当检测到一个新的配置文件,或者更改了现有的配置文件。
•应用的地方,往往配置更改和变化可以应用于组件,而不要求应用程序重新启动,或无需托管服务器必须重新启动。

这种模式可能不是合适的,如果运行时组件的设计使得它们只能在初始化时被配置,并更新这些部件的努力不能相比,重新启动应用程序和持久的一个短的停机时间是合理的。

例子

微软Azure云服务的角色发现和揭露被提了两个事件,当主机环境检测变化的ServiceConfiguration.cscfg文件:

•RoleEnvironment.Changing。引发此事件被检测到的结构变化后,但在此之前它被施加到该应用程序。你可以处理查询的变化,并取消运行时重新配置的活动。如果取消了变化,网页或辅助角色将自动以使新配置被应用程序使用的重新启动。
•RoleEnvironment.Changed。引发此事件后,应用程序的配置得到了应用。可以处理该事件来查询所应用的改变。

当取消在RoleEnvironment.Changing事件改变要表示到Azure,一个新的设置不能被应用于该应用程序正在运行时,并且它必须以使用新的值被重新启动。有效地,你会取消更改只有在您的应用程序或组件无法反应在运行时改变,需要重新启动才能使用新的值。

注意:

欲了解更多信息,请参阅RoleEnvironment.Changing事件并使用RoleEnvironment.Changing事件MSDN上。

处理RoleEnvironment.Changing和RoleEnvironment.Changed事件,你通常会添加一个自定义处理该事件。例如,从你可以下载本手册的例子运行时重新配置的解决方案的Global.asax.cs类下面的代码显示了如何添加一个名为RoleEnvironment_Changed到事件处理链中的自定义函数。这是从实施例的的Global.asax.cs文件。

注意:

这种模式的例子是,在RuntimeReconfiguration解决方案的RuntimeReconfiguration.Web项目。

protected void Application_Start(object sender, EventArgs e)
{
  ConfigureFromSetting(CustomSettingName);
  RoleEnvironment.Changed += this.RoleEnvironment_Changed;
}

 

在Web或工作的角色,你可以在处理RoleEnvironment.Changing事件的作用的OnStart事件处理程序中使用类似的代码。这是从实施例的WebRole.cs文件。

public override bool OnStart()
{
  // Add the trace listener. The web role process is not configured by web.config.
  Trace.Listeners.Add(new DiagnosticMonitorTraceListener());

  RoleEnvironment.Changing +=   this.RoleEnvironment_Changing;
  return base.OnStart();
}

 

要注意的是,在网页的角色的情况下,所述的OnStart事件处理程序中从Web应用程序本身的单独进程中运行。这就是为什么你通常会处理在Global.asax文件中RoleEnvironment.Changed事件处理程序,让您可以更新您的Web应用程序的运行时配置,而RoleEnvironment.Changing事件中的角色本身。在辅助角色的情况下,您可以订阅双方RoleEnvironment.Changing和RoleEnvironment.Changed的的OnStart事件处理程序中的事件。

注意:

可以在服务配置文件中存储自定义的配置设置,在自定义配置文件,在数据库中,如在虚拟机中的Azure
SQL数据库或SQL Server,或者在天青blob和表存储。您需要创建一个可以访问自定义配置设置和应用程序内设置组件的属性,这些适用于应用程序通常代码。

例如,下面的自定义函数读取设置,其名称作为参数传递,从Azure的服务配置文件中的值,然后将它应用到一个名为SomeRuntimeComponent运行时组件的当前实例。这是从实施例的的Global.asax.cs文件

private static void ConfigureFromSetting(string settingName)
{
  var value = RoleEnvironment.GetConfigurationSettingValue(settingName);
  SomeRuntimeComponent.Instance.CurrentValue = value;
}

 

注意:

一些配置设置,如那些用于Windows标识框架,不能存储在Azure服务配置文件中,并且必须在App.config或Web.config文件。

在Azure中,一些配置的变化检测,并自动应用。这包括在Diagnostics.wadcfg文件寡妇天青诊断系统,它指定的信息类型来收集和如何保持日志文件的结构。因此,它仅需要编写处理添加到服务配置文件的自定义设置的代码。你的代码应该:
•从更新的配置应用自定义设置您的应用程序在运行时的相应组件,使他们的行为体现了新的配置。
•取消改变,以指示到Azure新的值不能在运行时应用,该应用程序必须按顺序重新开始对要应用的变化。

例如,从你可以下载本手册的例子运行时重新配置的解决方案WebRole.cs类下面的代码显示了如何使用RoleEnvironment.Changing事件取消所有设置的更新,除了可应用于那些在运行时,不需要重新启动。此示例允许在运行时应用无需重新启动应用程序(使用此设置将能够读取新的值,并相应地在运行时改变其行为的组成部分)更改为“CustomSetting”的设置。任何其他更改的配置将自动使网页或工作的角色重新启动。

private void RoleEnvironment_Changing(object sender,
                               RoleEnvironmentChangingEventArgs e)
{
  var changedSettings = e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                                 .Select(c => c.ConfigurationSettingName).ToList();
  Trace.TraceInformation("Changing notification. Settings being changed: "
                         + string.Join(", ", changedSettings));

  if (changedSettings
    .Any(settingName => !string.Equals(settingName, CustomSettingName,
                               StringComparison.Ordinal)))
  {
    Trace.TraceInformation("Cancelling dynamic configuration change (restarting).");

    // Setting this to true will restart the role gracefully. If Cancel is not
    // set to true, and the change is not handled by the application, the
    // application will not use the new value until it is restarted (either
    // manually or for some other reason).
    e.Cancel = true;
  }
  Else
  {
    Trace.TraceInformation("Handling configuration change without restarting. ");
  }
}

 

注意:

这种方法证明了好的做法,因为它确保了更改应用程序代码不知道任何设置(因此不能确保它可以在运行时应用)将导致重新启动。如果更改任何一个被取消,该角色将被重新启动。

然后可以检测到并应用于应用程序的组件的新的配置后已被接受由Azure的框架更新未在RoleEnvironment.Changing事件处理程序取消。例如,在该示例解决方案的Global.asax文件以下代码处理RoleEnvironment.Changed事件。它检查每个配置设置,并且当它找到名为“CustomSetting”的设置,调用一个函数(前面所示),该应用新的设置,以在应用程序中的适当组件。

private void RoleEnvironment_Changed(object sender,
                               RoleEnvironmentChangedEventArgs e)
{
  Trace.TraceInformation("Updating instance with new configuration settings.");

  foreach (var settingChange in
           e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>())
  {
    if (string.Equals(settingChange.ConfigurationSettingName,
                      CustomSettingName,
                      StringComparison.Ordinal))
    {
      // Execute a function to update the configuration of the component.
      ConfigureFromSetting(CustomSettingName );
    }
  }
}

 

需要注意的是,如果你不取消配置的变化,但不将新值应用到您的应用程序组件,那么更改将不会生效的下一次重新启动应用程序之前。这可能会导致不可预测的行为,尤其是当所述宿主角色实例由Azure的自动重启在其日常维护操作,在该点的新的设定值将被应用的一部分。

本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn589785.aspx

 

 

时间: 2024-10-25 12:54:53

云计算设计模式(十九)——运行重构模式的相关文章

设计模式 ( 十九 ) 模板方法模式Template method(类行为型)

设计模式 ( 十九 ) 模板方法模式Template method(类行为型) 1.概述 在面向对象开发过程中,通常我们会遇到这样的一个问题:我们知道一个算法所需的关键步骤,并确定了这些步骤的执行顺序.但是某些步骤的具体实现是未知的,或者说某些步骤的实现与具体的环境相关. 例子1:银行业务办理流程 在银行办理业务时,一般都包含几个基本固定步骤: 取号排队->办理具体业务->对银行工作人员进行评分. 取号取号排队和对银行工作人员进行评分业务逻辑是一样的.但是办理具体业务是个不相同的,具体业务可能

云计算设计模式(九)——联合身份模式

云计算设计模式(九)--联合身份模式 验证委托给外部身份提供者.这种模式可以简化开发,最大限度地减少对用户管理的要求,并提高了应用程序的用户体验. 背景和问题 用户通常需要使用由提供,并通过与它们有商业关系的不同组织主持的多个应用程序一起工作.但是,这些用户可能被迫使用特定的(和不同的)的凭证,每一个.这可以: •原因脱节的用户体验.用户经常忘记登录凭据时,他们有很多不同的的. •暴露安全漏洞.当用户离开公司的帐户,必须立即取消设置.这是很容易忽略这在大型组织中. •复杂的用户管理.管理员必须管

设计模式 ( 十二 ) 职责链模式(Chain of Responsibility)(对象行为)

 设计模式(十二)职责链模式(Chain of Responsibility)(对象行为型) 1.概述        你去政府部门求人办事过吗?有时候你会遇到过官员踢球推责,你的问题在我这里能解决就解决,不能解决就推卸给另外个一个部门(对象).至于到底谁来解决这个问题呢?政府部门就是为了可以避免屁民的请求与官员之间耦合在一起,让多个(部门)对象都有可能接收请求,将这些(部门)对象连接成一条链,并且沿着这条链传递请求,直到有(部门)对象处理它为止. 例子1:js的事件浮升机制 例子2: 2.问题

设计模式之九(模版方法模式)

原文:设计模式之九(模版方法模式) 前言 模版方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模版方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 结构图 代码实现  AbstractClass是抽象类,其实也就是一抽象类,定义并实现了一个模版方法,这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现.顶级逻辑也有可能调用一些具体方法. public abstract class AbstractCla

云计算设计模式(二)——断路器模式

云计算设计模式(二)--断路器模式 处理故障连接到远程服务或资源时,可能需要耗费大量的时间.这种模式可以提高应用程序的稳定性和灵活性. 背景和问题 在分布式环境中,如在云,其中,应用程序执行访问远程资源和服务的操作,有可能对这些操作的失败是由于瞬时故障,如慢的网络连接,超时,或者被过度使用的资源或暂时不可用.这些故障一般之后的短时间内纠正自己,和一个强大的云应用应该准备使用的策略来处理它们,例如,通过重试模式进行说明. 但是,也可以是其中的故障是由于那些不容易预见的突发事件的情况下,这可能需要更

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

设计模式 ( 十五 ) 中介者模式Mediator(对象行为型) 1.概述 在面向对象的软件设计与开发过程中,根据"单一职责原则",我们应该尽量将对象细化,使其只负责或呈现单一的职责,即将行为分布到各个对象中. 对于一个模块或者系统,可能由很多对象构成,而且这些对象之间可能存在相互的引用,在最坏的情况下,每一个对象都知道其他所有的对象,这无疑复杂化了对象之间的联系.虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性,大量的相互连接使得一个对象似

Java设计模式(十九)----备忘录模式

备忘录模式 一. 概念 二. 结构 三. 分类 1."白箱"备忘录模式的实现 2."黑箱"备忘录模式的实现 3."多重"检查点 4."自述历史"模式 引子 我们在编程的时候,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状 态.比如,我们使用Eclipse进行编程时,假如编写失误(例如不小心误删除了几行代码),我们希望返回删除前的状态,便可以使用Ctrl+Z来进行返 回.下象棋的时候,可以反悔.这时我们便可以使用备忘

设计模式(九)外观模式Facade(结构型)

设计模式--外观模式Facade(结构型): 1. 概述      外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性. 例子1:一个电源总开关可以控制四盏灯.一个风扇.一台空调和一台电视机的启动和关闭.该电源总开关可以同时控制上述所有电器设备,电源总开关即为该系统的外观模式设计. 2. 问题 为了降低复杂性,常常将系统划分为若干个子系统.但是如何做到各个系统之间的通信和相互依赖关系达到最小呢? 3. 解决

传统设计模式(九)迭代器模式

关于迭代器模式,我们所需要知道的第一件事情就是它依赖于一个名为迭代器的接口.一旦我们有了这个接口,就可以为各种那个对象集合实现迭代器:数组.列表.散列表. 项目实例我们就拿用户角色模块来举例 背景 1.某用户作为应用管理员获取一组关于管理角色的arraylist权限组 2.该用户作为应用开发者获取一组关于开发角色的数组形式的权限组 ... /// <summary> /// 迭代器接口 /// </summary> public interface RoleIterator { /