Move configuration information out of the application deployment package to a centralized location. This pattern can provide opportunities for easier management and control of configuration data, and for sharing configuration data across applications and application instances.
将配置信息从应用程序部署包中移动到集中位置。这种模式可以提供更容易的管理和控制配置数据的机会,并在应用程序和应用实例之间共享配置数据。
The majority of application runtime environments include configuration information that is held in files deployed with the application, located within the application folders. In some cases it is possible to edit these files to change the behavior of the application after it has been deployed. However, in many cases, changes to the configuration require the application to be redeployed, resulting in unacceptable downtime and additional administrative overhead.
应用程序运行时环境中的大多数包括在应用程序部署的文件中部署的配置信息,位于应用程序文件夹中的。在某些情况下,它可以编辑这些文件,以改变应用程序后,它已被部署的行为。然而,在许多情况下,结构的变化要求应用程序被重新部署,而导致不可接受的停机时间和额外的管理费用。
Local configuration files also limit the configuration to a single application, whereas in some scenarios it would be useful to share configuration settings across multiple applications. Examples include database connection strings, UI theme information, or the URLs of queues and storage used by a related set of applications.
本地配置文件还限制了单个应用程序的配置,而在某些情况下,在多个应用程序中共享配置设置是有用的。例子包括数据库连接字符串,用户界面主题信息,或相关的应用程序使用的队列和存储的网址。
Managing changes to local configurations across multiple running instances of the application, especially in a cloud-hosted scenario, may also be challenging. It may result in instances using different configuration settings while the update is being deployed.
管理的应用程序的多个运行实例,特别是在云托管的情况下,本地配置的变化,也可能是具有挑战性的。这可能会导致在使用不同配置设置的情况下,而更新正在部署的情况下使用。In addition, updates to applications and components may require changes to configuration schemas. Many configuration systems do not support different versions of configuration information.
此外,对应用程序和组件的更新可能需要更改配置模式。许多配置系统不支持不同版本的配置信息。
Store the configuration information in external storage, and provide an interface that can be used to quickly and efficiently read and update configuration settings. The type of external store depends on the hosting and runtime environment of the application. In a cloud-hosted scenario it is typically a cloud-based storage service, but could be a hosted database or other system.
存储在外部存储的配置信息,并提供一个接口,可用于快速和有效地读取和更新配置设置。外部存储类型取决于应用程序的托管和运行时环境。在云托管的情况下,它通常是基于云的存储服务,但可以是托管的数据库或其他系统。
The backing store chosen for configuration information should be fronted by a suitable interface that provides consistent and easy to use access in a controlled way that enables reuse. Ideally, it should expose the information in a correctly typed and structured format. The implementation may also need to authorize users’ access in order to protect configuration data, and be flexible enough to allow multiple versions of the configuration (such as development, staging, or production, and multiple release versions of each one) to be stored.
存储支持,选择配置信息应该是通过适当的接口,提供一致的和容易在一个可控制的方式,使再利用访问。理想情况下,它应该在正确的类型和结构化的格式中公开信息。实施还可能需要授权用户访问以保护配置数据,并具有足够的灵活性,以便允许多个版本的配置(如开发、分期、或生产,以及每一个版本的多个版本)被存储。
Note:
Many built-in configuration systems read the data when the application starts up, and cache the data in memory to provide fast access and to minimize the impact on application performance. Depending on the type of backing store used, and the latency of this store, it might be advantageous to implement a caching mechanism within the external configuration store. For more information about implementing caching, see the Caching Guidance.
许多内置的配置系统在应用程序启动时读取数据,并将数据缓存在内存中以提供快速访问,并将其应用性能的影响降到最低。根据所使用的支持存储类型和该存储的延迟,它可能有利于在外部配置存储区内实现缓存机制。有关实现缓存的更多信息,参见缓存指南。
Figure 1 shows an overview of this pattern. 图1显示了该模式的概述。
Figure 1 - An overview of the External Configuration Store pattern with optional local cache 图1 -一个可选的本地缓存的外部配置存储模式的概述
Consider the following points when deciding how to implement this pattern:
在决定如何实现这个模式时,考虑以下几点:
This pattern is ideally suited for:这种模式非常适合于:
In a Microsoft Azure hosted application, a typical choice for storing configuration information externally is to use Azure storage. This is resilient, offers high performance, and is replicated three times with automatic failover to offer high availability. Azure tables provide a key/value store with the capability to use a flexible schema for the values. Azure blob storage provides a hierarchical container-based store that can hold any type of data in individually named blobs.
在一个微软Azure的托管应用程序中,一个典型的存储配置信息的选择是使用Azure的存储。这是有弹性的,提供高性能,并重复三次自动故障转移提供高可用性。Azure表提供了一个键/值存储,使用灵活的模式为值的能力。Azure的BLOB存储提供了一个分层的基于容器的存储可以保存任何类型的数据在单独命名的斑点。
The following example shows how a configuration store can be implemented over Azure blob storage to store and expose configuration information. The BlobSettingsStore class abstracts blob storage for holding configuration information, and implements the ISettingsStore interface shown in the following code.
下面的示例演示如何配置存储可以在Azure Blob存储实现存储和暴露的配置信息。的BlobSettingsStore类文摘的BLOB存储用于保存配置信息,并实现了在下面的代码所示的ISettingsStore接口。
Note:
This code is provided in the ExternalConfigurationStore.Cloud project in the ExternalConfigurationStore solution. This solution is available for download with this guidance.
本代码是在externalconfigurationstore提供。在externalconfigurationstore解云项目。此解决方案是可供下载的指南。
public interface IsettingsStore { string Version { get; } Dictionary<string, string> FindAll(); void Update(string key, string value); }
This interface defines methods for retrieving and updating configuration settings held in the configuration store, and includes a version number that can be used to detect whether any configuration settings have been modified recently. When a configuration setting is updated, the version number changes. The BlobSettingsStore class uses the ETag property of the blob to implement versioning. The ETag property of a blob is updated automatically each time the blob is written.
此接口定义了在配置存储中检索和更新配置设置的方法,并且包括可用于检测最近已修改的任何配置设置的版本号。当配置设置更新时,版本号更改。的blobsettingsstore类使用BLOB的ETag属性来实现版本控制。一个blob ETag属性自动更新每次滴写。
Note:
Note that, by design, this simple solution exposes all configuration settings as string values rather than typed values.
请注意,通过设计,这个简单的解决方案将所有配置设置为字符串值,而不是类型值。
The ExternalConfigurationManager class provides a wrapper around a BlobSettingsStore object. An application can use this class to store and retrieve configuration information. This class uses the Microsoft Reactive Extensions library to expose any changes made to the configuration through an implementation of the IObservable interface. If a setting is modified by calling the SetAppSetting method, the Changed event is raised and all subscribers to this event will be notified.
externalconfigurationmanager类提供的包裹一blobsettingsstore对象。一个应用程序可以使用这个类来存储和检索配置信息。这类使用微软反应扩展库暴露了配置通过对iobservable接口的一个实现的任何变化。如果设置是通过调用setappsetting方法改性,提高了事件和所有用户对该事件将被通报。
Note that all settings are also cached in a Dictionary object inside the ExternalConfigurationManager class for fast access. The SetAppSetting method updates this cache, and the GetSetting method that an application can use to retrieve a configuration setting reads the data from the cache (if the setting is not found in the cache, it is retrieved from the BlobSettingsStore object instead).
请注意,所有的设置也缓存在字典对象里面的externalconfigurationmanager类快速访问。的setappsetting方法更新缓存,和getsetting方法,应用程序可以使用检索配置设置读取缓存中的数据(如果设置不在缓存中,发现它是从blobsettingsstore对象代替)。
The GetSettings method invokes the CheckForConfigurationChanges method to detect whether the configuration information in blob storage has changed by examining the version number and comparing it with the current version number held by the ExternalConfigurationManager object. If one or more changes have occurred, the Changed event is raised and the configuration settings cached in the Dictionary object are refreshed. This is an application of the Cache-Aside pattern.
getsettings方法调用checkforconfigurationchanges法来检测是否在Blob存储配置信息已通过审查的版本号与当前版本号的对象比较externalconfigurationmanager举行了。如果发生了一个或多个更改,则将更改事件和在字典对象中缓存的配置设置更新。这是一个应用程序缓存的预留模式。
The following code sample shows how the Changed event, the SetAppSettings method, the GetSettings method, and the CheckForConfigurationChanges method are implemented
下面的代码示例演示如何改变事件的setappsettings方法的getsettings方法和checkforconfigurationchanges方法的实施
public class ExternalConfigurationManager : IDisposable { // An abstraction of the configuration store. private readonly ISettingsStore settings; private readonly ISubject<KeyValuePair<string, string>> changed; ... private Dictionary<string, string> settingsCache; private string currentVersion; ... public ExternalConfigurationManager(ISettingsStore settings, ...) { this.settings = settings; ... } ... public IObservable<KeyValuePair<string, string>> Changed { get { return this.changed.AsObservable(); } } ... public void SetAppSetting(string key, string value) { ... // Update the setting in the store. this.settings.Update(key, value); // Publish the event. this.Changed.OnNext( new KeyValuePair<string, string>(key, value)); // Refresh the settings cache. this.CheckForConfigurationChanges(); } public string GetAppSetting(string key) { ... // Try to get the value from the settings cache. // If there is a miss, get the setting from the settings store. string value; if (this.settingsCache.TryGetValue(key, out value)) { return value; } // Check for changes and refresh the cache. this.CheckForConfigurationChanges(); return this.settingsCache[key]; } ... private void CheckForConfigurationChanges() { try { // Assume that updates are infrequent. Lock to avoid // race conditions when refreshing the cache. lock (this.settingsSyncObject) { { var latestVersion = this.settings.Version; // If the versions differ, the configuration has changed. if (this.currentVersion != latestVersion) { // Get the latest settings from the settings store and publish the changes. var latestSettings = this.settings.FindAll(); latestSettings.Except(this.settingsCache).ToList().ForEach( kv => this.changed.OnNext(kv)); // Update the current version. this.currentVersion = latestVersion; // Refresh settings cache. this.settingsCache = latestSettings; } } } catch (Exception ex) { this.changed.OnError(ex); } } }
Note:
The ExternalConfigurationManager class also provides a property named Environment. The purpose of this property is to support varying configurations for an application running in different environments, such as staging and production.
An ExternalConfigurationManager object can also query the BlobSettingsStore object periodically for any changes (by using a timer). The StartMonitor and StopMonitor methods illustrated in the code sample below start and stop the timer. The OnTimerElapsed method runs when the timer expires and invokes the CheckForConfigurationChanges method to detect any changes and raise the Changed event, as described earlier.
一个externalconfigurationmanager对象也可以查询blobsettingsstore对象定期更改(使用定时器)。startmonitor和stopmonitor方法在下面的代码示例说明了启动和停止计时器。的ontimerelapsed方法运行计时器过期时,调用checkforconfigurationchanges法检测任何改变和提高了的事件,如前所述。
public class ExternalConfigurationManager : IDisposable { ... private readonly ISubject<KeyValuePair<string, string>> changed; private readonly Timer timer; private ISettingsStore settings; ... public ExternalConfigurationManager(ISettingsStore settings, TimeSpan interval, ...) { ... // Set up the timer. this.timer = new Timer(interval.TotalMilliseconds) { AutoReset = false; }; this.timer.Elapsed += this.OnTimerElapsed; this.changed = new Subject<KeyValuePair<string, string>>(); ... } ... public void StartMonitor() { if (this.timer.Enabled) { return; } lock (this.timerSyncObject) { if (this.timer.Enabled) { return; } this.keepMonitoring = true; // Load the local settings cache. this.CheckForConfigurationChanges(); this.timer.Start(); } } public void StopMonitor() { lock (this.timerSyncObject) { this.keepMonitoring = false; this.timer.Stop(); } } private void OnTimerElapsed(object sender, EventArgs e) { Trace.TraceInformation( "Configuration Manager: checking for configuration changes."); try { this.CheckForConfigurationChanges(); } finally { ... // Restart the timer after each interval. this.timer.Start(); ... } } ... }
The ExternalConfigurationManager class is instantiated as a singleton instance by the ExternalConfiguration class shown below.
externalconfigurationmanager类实例化为通过以下所示的externalconfiguration类单独实例。
public static class ExternalConfiguration { private static readonly Lazy<ExternalConfigurationManager> configuredInstance = new Lazy<ExternalConfigurationManager>( () => { var environment = CloudConfigurationManager.GetSetting("environment"); return new ExternalConfigurationManager(environment); }); public static ExternalConfigurationManager Instance { get { return configuredInstance.Value; } } }
The following code is taken from the WorkerRole class in the ExternalConfigurationStore.Cloud project. It shows how the application uses the ExternalConfiguration class to read and update a setting.
下面的代码是在externalconfigurationstore从workerrole.Cloud项目。它显示了如何应用程序使用externalconfiguration类来读取和更新设置。
public override void Run() { // Start monitoring for configuration changes. ExternalConfiguration.Instance.StartMonitor(); // Get a setting. var setting = ExternalConfiguration.Instance.GetAppSetting("setting1"); Trace.TraceInformation("Worker Role: Get setting1, value: " + setting); Thread.Sleep(TimeSpan.FromSeconds(10)); // Update a setting. Trace.TraceInformation("Worker Role: Updating configuration"); ExternalConfiguration.Instance.SetAppSetting("setting1", "new value"); this.completeEvent.WaitOne(); }
The following code, also from the WorkerRole class, shows how the application subscribes to configuration events.
下面的代码,也从workerrole类,展示了如何应用订阅配置事件。
public override bool OnStart() { ... // Subscribe to the event. ExternalConfiguration.Instance.Changed.Subscribe( m => Trace.TraceInformation("Configuration has changed. Key:{0} Value:{1}", m.Key, m.Value), ex => Trace.TraceError("Error detected: " + ex.Message)); ... }
The following pattern may also be relevant when implementing this pattern:
This pattern has a sample application associated with it. You can download the "Cloud Design Patterns – Sample Code" from the Microsoft Download Center at http://aka.ms/cloud-design-patterns-sample.
External Configuration Store Pattern 外部配置存储模式
原文:http://www.cnblogs.com/zsy/p/5422977.html