首页 > 代码库 > 云计算设计模式(十九)——运行重构模式

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

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


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

背景和问题


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

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

解决方案


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

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

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

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

图1 - 此模式的基本概述


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

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

问题和注意事项


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

何时使用这个模式


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

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

例子


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


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

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

注意:

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



处理RoleEnvironment.ChangingRoleEnvironment.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.ChangingRoleEnvironment.Changed的OnStart事件处理程序中的事件

注意:

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


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

private static void ConfigureFromSetting(string settingName)
{
  var value = http://www.mamicode.com/RoleEnvironment.GetConfigurationSettingValue(settingName);>


 

注意:

一些配置设置,那些用于Windows标识框架不能存储在Azure服务配置文件中,并且必须在App.configWeb.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

 

 

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