设计应用程序,使得它可以在不需要重新部署或者重新启动应用程序重新配置。这有助于保持可用性并减少停机时间。
一个主要目的为重要的应用,如商业和企业网站是尽量减少停机时间以及由此引发的中断给客户和用户。但是,有时有必要重新配置应用程序改变特定行为或设置,而在部署和使用。因此,它是用于该应用程序被设计成这样一种方式,以允许在运行时要应用这些配置的变化,并为应用程序,以检测所述变化并且尽快地应用它们的部件的优点。
该种要应用可能被调整记录,以协助与应用程序调试问题,交换使用不同数据存储的连接字符串,或者打开或关闭特定的部分或应用程序的功能的粒度配置变化的例子。
为实施这一模式的解决方案依赖于应用程序托管环境中可用的功能。典型地,应用程序代码将响应于由检测到的变化对应用程序配置时,主机基础设施提出的一个或多个事件。这通常是上载新的配置文件,或响应于改变通过管理门户的配置或者通过访问的API的结果。
码处理的配置变化事件可以检查变化,并将其应用到该应用程序的组件。有必要对这些部件进行检测和反应的变化,因此它们的值通常会被公开为可写的属性或方法,在事件处理程序的代码可以设置为新值,或执行。从这一点来说,该部件应使用新的值,以便在需要改变应用程序的行为发生。
如果这是不可能的部件,以应用更改在运行时,这将是必要的,重新启动该应用程序,从而当应用程序启动时再次这些更改应用。在一些托管环境中它可能会检测到这些类型的变化,并指出对环境的应用程序必须重新启动。在其他情况下,可能有必要执行该分析的设置更改,并强制必要的应用程序重新启动时的代码。
大多数环境中暴露响应配置更改引发的事件。在那些不这样做,定期检查更改配置并应用这些变化将是必要的轮询机制。它也可能有必要重新启动应用程序,如果变化不能在运行时被应用。例如,有可能以比较在预设的时间间隔一个配置文件的日期和时间,并运行代码以应用更改时的较新版本中找到。另一种方法是,其中包含一个控制中的应用程序的管理用户界面,或使一个安全端点可以从应用程序外部进行访问,其执行读取,并应用更新的配置的代码。
或者,该应用程序可以反应以在环境中的一些其他变化。例如,发生于特定的运行时错误可能会改变日志配置自动收集更多的信息,或者代码可以使用当前日期读取和应用主题,反映了季节或特殊事件。
在决定如何实现这个模式时,请考虑以下几点:
这种模式非常适合于:
这种模式可能不是合适的,如果运行时组件的设计使得它们只能在初始化时被配置,并更新这些部件的努力不能相比,重新启动应用程序和持久的一个短的停机时间是合理的。
微软 Azure 云服务的角色发现和揭露被提了两个事件,当主机环境检测变化的 ServiceConfiguration.cscfg 文件:
当取消在 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; |
} |
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(); |
} |
注意: 可以在服务配置文件中存储自定义的配置设置,在自定义配置文件,在数据库中,如在虚拟机中的 Azure SQ L数据库或 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 文件寡妇天青诊断系统,它指定的信息类型来收集和如何保持日志文件的结构。因此,它仅需要编写处理添加到服务配置文件的自定义设置的代码。你的代码应该:
例如,从你可以下载本手册的例子运行时重新配置的解决方案 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 ); |
} |
} |
} |