App配置也可以單點化

       在分佈式服務站點體系中,應用程序配置往往都是隨程序發佈包走,在線上運營的過程中,未有自動化部署工具的情況下,靠人力來部署上百臺應用服務器,非同一般。即便通過自動化工具來完成配置更新與部署,多少還是要煩勞運維人員。於是乎,我們可以通過配置項的單點化來實現:通過在DB端完成數據配置,各應用系統共享配置項,數據、配置更新依賴緩存及時刷新即可。

       如有特殊需求,需要對單臺服務器做配置區分,則可以通過增加APP配置的優先級來調整實現本地、DB端配置的順序。       實現方式間接明瞭,下面給出示例:
1、Cache配置數據


        /// <summary>
        /// 獲取配置表中數據並緩存
        /// </summary>
        /// <returns></returns>
        public static List<InitialParamEntity> GetList()
        {
            WebLog.WriteStart("Get Parameter List...");
            List<InitialParamEntity> list = null;
            try
            {
                string key = Consts.Keys.GET_PARA_INIT_INFO;

                if (HttpContext.Current == null || HttpContext.Current.Cache[key] == null)
                {
                    list = ParameterDA.GetList();
                    CacheHelper.Store(key, list);
                }

                list = CacheHelper.GetCache<List<InitialParamEntity>>(key);
            }
            catch (System.Exception ex)
            {
                WebLog.WriteStart("Get Parameter Exception:" + ex.GetObjectDetails("|"));
            }

            return list;
        }
    /// <summary>
    /// Summary description for InitialParamEntity
    /// </summary>
    public class InitialParamEntity
    {
        /// <summary>
        /// 參數類型
        /// </summary>
        public string ParaType
        {
            get;
            set;
        }

        /// <summary>
        /// 參數名
        /// </summary>
        public string ParaKey
        {
            get;
            set;
        }

        /// <summary>
        /// 參數值
        /// </summary>
        public string ParaValue
        {
            get;
            set;
        }
    }

2、緩存刷新(略)

在HttpHandler中配置緩存刷新Path,通過該Path以及對應的刷新參數,完成對應緩存或全緩存的刷新

3、配置項處理

建立配置類,繼承IConfigurationSectionHandler, 在Global入口處調用Init方法完成數據初始化

public class MyConfig : IConfigurationSectionHandler
    {
        private MyConfig() { }

        #region read appsettings

        #region 不同參數類型
        
        #region 默認配置

        public static string GetConfig(string key)
        {
            string config = GetConfig<string>(key);
            if (String.IsNullOrEmpty(config))
            {
                return string.Empty;
            }
            return config;
        }

        public static T GetConfig<T>(string key)
        {
            return GetConfig<T>(key, default(T));
        }

        public static T GetConfig<T>(string key,T defaultValue)
        {
            if (Params == null || Params.Count == 0)
                return defaultValue;

            string parValue = Params.Get(key);

            if (!String.IsNullOrEmpty(parValue))
            {
                return (T)Convert.ChangeType(parValue, typeof(T));
            }

            return defaultValue;
        }

        #endregion

        #region Url 跳轉

        /// <summary>
        /// 用戶獲取根據類型獲得URL跳轉地址
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetMap<T>(string key)
        {
            if (MapPath == null || MapPath.Count == 0)
                return default(T);

            string parValue = MapPath.Get(key);

            if (!String.IsNullOrEmpty(parValue))
            {
                return (T)Convert.ChangeType(parValue, typeof(T));
            }

            return default(T);
        }

        public static string GetMap(string key)
        {
            return GetMap<string>(key);
        }

        #endregion

        #endregion

        public static string GetRadomConfig(string key, string defaultValue)
        {
            return GetRadomConfig<string>(key, defaultValue);
        }

        public static T GetRadomConfig<T>(string key, T defaultValue)
        {
            string result = GetConfig(key);
            string[] tempRet = result.Split(';');
            Random random = new Random();
            int index = random.Next(0, tempRet.Length);
            result = tempRet[index];
            return (T)Convert.ChangeType(result, typeof(T));
        }

        /// <summary>
        /// 隨機取一個值
        /// </summary>
        /// <returns></returns>
        private static string GetRadomConfig(string value)
        {
            string[] serverList = value.Split(',');
            if (serverList.Length == 0) throw new ArgumentException("請求參數異常");

            int len = serverList.Length;
            if (len > 1)
            {
                Random rd = new Random((int)(DateTime.Now.Ticks));
                int rdNum = rd.Next(len);
                return serverList[rdNum];
            }
            return serverList[0];
        }
        #endregion

        #region Public attribute

        private static NameValueCollection _mapPath;
        public static NameValueCollection MapPath
        {
            get { return _mapPath; }
        }

        private static NameValueCollection _params;
        public static NameValueCollection Params
        {
            get { return _params; }
        }

        [Config(Key = "PayOrdersConnectionString", DefaultValue = "")]
        private static string payOrdersConnectionString;
        /// <summary>
        /// 新的訂單庫
        /// </summary>
        public static string PayOrdersConnectionString
        {
            get
            {
                return payOrdersConnectionString;
            }
        }

        #endregion

        #region internal
        static void SetField(Action<FieldInfo, ConfigAttribute> action)
        {
            Type type = typeof(MerchantConfig);
            FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);
            foreach (FieldInfo field in fields)
            {
                ConfigAttribute configAttr = (ConfigAttribute)Attribute.GetCustomAttribute(field, typeof(ConfigAttribute));
                if (configAttr != null)
                {
                    action(field, configAttr);
                }
            }
        }

        static void SetParamsValue(FieldInfo field, ConfigAttribute configAttr)
        {
            foreach (string s in Params.AllKeys)
            {
                if (string.Compare(s, configAttr.Key, true) == 0)
                {
                    field.SetValue(null, Convert.ChangeType(Params[configAttr.Key], configAttr.ValueType));
                }
            }
        }

        static void SetFieldDefault(FieldInfo field, ConfigAttribute configAttr)
        {
            field.SetValue(null, Convert.ChangeType(configAttr.DefaultValue, configAttr.ValueType));
        }

        internal static void UserDefinedCreate(NameValueCollection settings, NameValueCollection mapPath)
        {
            if (settings != null)
            {
                //Config配置,優先級高於數據庫配置
                NameValueCollection rewriterSettings = (NameValueCollection)System.Configuration.ConfigurationManager.GetSection("MyParamSettings");

                if (rewriterSettings != null)
                {
                    foreach (string key in rewriterSettings.Keys)
                    {
                        //!string.IsNullOrEmpty(rewriterSettings[key]), 允許空字符
                        if (rewriterSettings[key] != null)
                        {
                            if (settings[key] != null)
                            {
                                WebLog.WriteStart("數據庫:" + key + ":" + settings[key]);
                                WebLog.WriteStart("Config:" + key + ":" + rewriterSettings[key]);
                                settings[key] = rewriterSettings[key];
                            }
                            else if (mapPath[key] != null)
                            {
                                WebLog.WriteStart("數據庫:" + key + ":" + mapPath[key]);
                                WebLog.WriteStart("Config:" + key + ":" + rewriterSettings[key]);
                                mapPath[key] = rewriterSettings[key];
                            }
                        }
                    }
                }

                _mapPath = mapPath;
                _params = settings;

                SetField(SetParamsValue);
            }
            else
            {
                SetField(SetFieldDefault);
            }
        }

        /// <summary>
        /// 獲取數據庫配置數據:初始化Config,生成靜態XML配置文件
        /// </summary>
        public static void Init(List<InitialParamEntity> list)
        {
            NameValueCollection mapPath = new NameValueCollection();
            NameValueCollection setting = new NameValueCollection();

            foreach (InitialParamEntity param in list)
            {
                if (param.ParaType != null && param.ParaType.ToUpper() == "MAPPATH")
                {
                    mapPath.Add(param.ParaKey, param.ParaValue);
                }
                else
                {
                    setting.Add(param.ParaKey, param.ParaValue);
                }

                WebLog.WriteStart(param.ParaKey + ", " + param.ParaValue);
            }

            UserDefinedCreate(setting, mapPath);
        }

        #endregion

        #region IConfigurationSectionHandler 成員

        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            //調用自定義的初始化函數
            System.Diagnostics.Debug.WriteLine("config is modified------");
            NameValueCollection settings;

            try
            {
                System.Diagnostics.Debug.WriteLine("-------- Begin read configuration file");
                NameValueSectionHandler baseHandler = new NameValueSectionHandler();
                settings = (NameValueCollection)baseHandler.Create(parent, configContext, section);
            }
            catch
            {
                settings = null;
            }

            return settings;
        }

        #endregion
    }

    #region 默認值屬性類
    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
    internal class ConfigAttribute : Attribute
    {
        private object defaultValue;
        private string key;
        private Type valueType = typeof(string);

        public object DefaultValue
        {
            get { return defaultValue; }
            set { defaultValue = value; }
        }

        public string Key
        {
            get { return key; }
            set { key = value; }
        }

        public Type ValueType
        {
            get { return valueType; }
            set { valueType = value; }
        }
    }
    #endregion

4、提升單臺機器配置優先級

<section name="MyParamSettings" type="System.Configuration.NameValueSectionHandler,System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

  <MyParamSettings>
    <!-- 優先級高於數據庫配置項 -->
    <add key="IFunctionService" value="http://www.baiduc.om" />
  </MyParamSettings>

5、配置項應用

        MyConfig.GetConfig("IFunctionService")
        MyConfig.GetConfig<string>("IFunctionService")
        MyConfig.GetConfig<int>("IFunctionService")




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章