Discuz!NT3.1 資料庫讀寫分離 程式碼

chenbin01234發表於2010-05-24

Discuz!NT 3.1版本為專案使用者專門開發了負載均衡、資料庫讀寫分離、分散式快取和檢測工具一系列套件,為超大型社群建設提供了完美的技術解決方案。但在標準版中沒有實現讀寫分離的.在此為標準版實現了資料讀寫分離
   1. 第一步 實現資料庫負載均衡類
     /// <summary>
    ///  負載均衡排程介面
    /// </summary>
    public interface ILoadBalanceScheduling
    {
        /// <summary>
        /// 獲取應用當前負載均衡排程演算法下的快照連結資訊
        /// </summary>
        /// <returns></returns>
        DbSnapInfo GetConnectDbSnap();
    }
    以上是Discuz!NT 3.1中提供的:讀資料庫 的負載均衡排程介面 (注:在標準版中少了Discuz.EntLib.dll)接下來我們來實現上面介面
   using System;
   using System.Collections.Generic;
   using System.Text;
   using Discuz.Config;
   using DCG = Discuz.Common.Generic;
   namespace Discuz.EntLib
  {
          public class DBLoadBalanceScheduling : ILoadBalanceScheduling
         {
                 /// <summary>
                 /// 鎖物件
                 /// </summary>
                private static object m_lockHelper = new object();

                #region ILoadBalanceScheduling 成員
               public DbSnapInfo GetConnectDbSnap()
              {
                      lock (m_lockHelper)
                     {
                             DbSnapAppConfig snapConfigs = DbSnapConfigs.GetConfig();

                             if (DbSnapConfigs.GetEnableSnapList().Count <= 0)
                                          throw new NotImplementedException();

                              return DBLoadBalanceManager.GetDbSnapInfo();
                     }
               }
               #endregion
        }

    class DBLoadBalanceManager
    {
        /// <summary>
        /// 鎖物件
        /// </summary>
        private static object m_lockHelper = new object();

        private static DCG.List<DbSnapInfo> enableSnapList = null;

        private static int i = -1;

        public static DbSnapInfo GetDbSnapInfo()
        {
            lock (m_lockHelper)
            {
                DbSnapAppConfig snapConfigs = DbSnapConfigs.GetConfig();

                enableSnapList = DbSnapConfigs.GetEnableSnapList();

                int count = enableSnapList.Count;

                while (true)
                {
                    i = (i + 1) % count;

                    int cw = enableSnapList[i].Weight;

                    if (i == 0)
                    {
                        cw = cw - GetGcd();

                        if (cw <= 0)
                        {
                            cw = GetMax();

                            if(cw == 0)
                                throw new NotImplementedException();
                               
                        }
                    }

                    if (enableSnapList[i].Weight >= cw)
                        return enableSnapList[i];
                }

            }
        }

        private static int GetMax()
        {
            int max = 0;

            foreach (DbSnapInfo info in enableSnapList)
            {
                if (max <= info.Weight)
                {
                    max = info.Weight;
                }
            }

            return max;
        }

        private static int GetMin()
        {
             int min = 0;

            for (int i = 0; i < enableSnapList.Count; i++)
            {
                if (i == 0)
                {
                    min = enableSnapList[i].Weight;
                }

                if (min > enableSnapList[i].Weight)
                {
                    min = enableSnapList[i].Weight;
                }
            }

            return min;
        }

        private static int GetGcd()
        {
            int gcd = 1;

            int min = GetMin();

            for (int i = min; i <= 2; i--)
            {
                if (GetMod(i))
                {
                    gcd = i;
                    break;
                }
            }

            return gcd;
        }
        /// <summary>
        /// 是否能被所有權重整除
        /// </summary>
        /// <param name="num"></param>
        /// <returns>能true,不能false</returns>
        private static bool GetMod(int num)
        {
            bool flag = true;

            foreach (DbSnapInfo info in enableSnapList)
            {
                if (0 != (info.Weight % num))
                {
                    flag = false;
                    break;
                }
            }
            return flag;
        }
    }
   }
   可以在Discuz!NT 3.1中新增一個Discuz.EntLib類庫專案 並新增一個DBLoadBalanceScheduling.cs檔案並加上面程式碼
   2.第二步新增資料庫負載均衡config檔案
   由於Discuz!NT 3.1中需要dbsnap.config檔案,所以需要在"專案路徑/web/config/"下新增“dbsnap.config”檔案,內容如下:
   <?xml version="1.0"?>
<DbSnapAppConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AppDbSnap>true</AppDbSnap>
  <WriteWaitTime>6</WriteWaitTime>
  <LoadBalanceScheduling>DBLoadBalanceScheduling</LoadBalanceScheduling>
  <RecordeLog>false</RecordeLog>
  <DbSnapInfoList>
    <DbSnapInfo>
      <SouceID>0</SouceID>
      <Enable>true</Enable>
      <DbconnectString>第一個資料連線串</DbconnectString>
      <Weight>1</Weight>
    </DbSnapInfo>
    <DbSnapInfo>
      <SouceID>1</SouceID>
      <Enable>true</Enable>
      <DbconnectString>第一個資料連線串</DbconnectString>
      <Weight>1</Weight>
    </DbSnapInfo>
  </DbSnapInfoList>
</DbSnapAppConfig>
完成以上操作便可以在Discuz!NT 3.1中實現讀寫分離和讀資料庫的負載均衡

相關文章