代码改变世界

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

2017-04-27 14:41  tlnshuju  阅读(176)  评论(0编辑  收藏  举报

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


设计应用程序,使得能够在不须要又一次部署或者又一次启动应用程序又一次配置。这有助于保持可用性并降低停机时间。

背景和问题


一个主要目的为重要的应用。如商业和企业站点是尽量降低停机时间以及由此引发的中断给客户和用户。

可是。有时有必要又一次配置应用程序改变特定行为设置,而在部署使用。因此是用于该应用程序设计成这样一种方式,以同意在执行时要应用这些配置的变化,为应用程序。以检測所述变化而且尽快地应用它们的部件的长处。

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

解决方式


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



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

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



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

图1 - 此模式的基本概述


大多数环境中暴露响应配置更改引发的事件那些不这样做定期检查更改配置并应用这些变化将是必要的轮询机制

可能有必要又一次启动应用程序,假设变化不能在执行时被应用。

比如有可能以比較预设的时间间隔一个配置文件的日期和时间。并执行代码以应用更改的较新版本号中找到。还有一种方法是,当中包括一个控制中的应用程序的管理用户界面或使一个安全端点能够从应用程序外部进行訪问其执行读取,并应用更新的配置的代码。



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

问题和注意事项


在决定怎样实现这个模式时,请考虑下面几点
配置设置必须存储在部署的应用程序之外。使得它们能够在不须要整个包被又一次部署更新。典型设置被存储在配置文件里或者在外部存储库中。如一个数据库网络存储訪问执行时配置机制。应严格控制以及使用时严格审核
假设托管的基础设施不会自己主动检測配置更改的事件。揭露这些事件相应用程序代码您必须实现一种替代机制来检測和应用更改

能够是通过轮询机制或者通过暴露交互式控制端点发起更新过程。


假设您须要实现一个轮询机制考虑怎样常常检查更新的配置应该发生轮询间隔将意味着变化可能不被应用了一段时间。的间隔可能会产生不利影响,通过吸收现有的计算和I / O资源的操作。
•假设是应用程序的多个实例附加的考虑因素,这取决于怎样变化进行检測。假设改变是通过宿主基础结构引发的事件自己主动检測到,这些变化可能不被同一时候应用的全部实例进行检測。意味着。某些情况下,将要使用的原始配置一个周期。而有些则使用新的设置

假设该更新是通过轮询机制检測到,这必须保持一致性通信改变全部实例。


一些配置的变化可能要求应用程序又一次启动甚至要求托管server又一次启动。必须确定这些类型的配置设置和运行每个对应的操作

比如,要求应用程序又一次启动的变化可能会自己主动运行此操作,或者它可能是管理员负责发起又一次启动在适当的时间时。应用过大的负荷应用程序能够处理的其它实例的负载。
更新并确认他们是成功的,而更新的应用程序实例正在运行正确将更新应用到全部实例之前分阶段部署计划

由此,可以防止错误发生应用程序的总的中断更新须要又一次启动或应用程序又一次启动。特别是在应用程序有一个显著启动或热身的时候,用一个分阶段部署的方式,以防止多个实例脱机在同一时间
•考虑怎样将回滚造成的问题配置更改导致申请失败。比如应该可以滚动等待轮询间隔,以检測所述变化背部的变化马上取代。
•考虑怎样配置设置的位置可能会影响应用程序的性能比如,你应该处理将发生,假设使用外部存储不可用错误。当应用程序启动时,或配置更改将被应用比方用一个默认的配置或通过本地缓存的设置在server和重用这些值重试訪问远程数据存储。


快速缓存能够帮助降低延迟,假设一个组件须要多次訪问配置设置。

然而。当配置改变时。应用程序代码将须要无效缓存设置。该组件必须使用更新后的设置。


何时使用这个模式


这样的模式很适合于
•应用程序,而您必须避免一切不必要的停机时间同一时候仍然可以将更改应用到应用程序配置


环境,揭露事件自己主动提出的主要配置更改时通常。这是当检測到一个新的配置文件或者更改了现有的配置文件
•应用的地方,往往配置更改变化能够应用于组件。而不要求应用程序又一次启动。无需托管server必须又一次启动。

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

样例


微软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事件处理程序中的事件

注意:

能够在服务配置文件存储自己定义的配置设置自己定义配置文件在数据库中,如在虚拟机中的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.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