使用windows服務和MSMQ和進行日志管理(解決高並發問題)


首先,建立一個windows服務項目

image

然后進行設計視圖

image 

在工作區空白處右屬,添加一個安裝項目

image

然后就可以寫我們的代碼了,我們的服務需要實時監視MSMQ的隊列中有沒有記錄,如果有,就向數據庫中插入

核心代碼如下

/// <summary>
/// 接收來自MSMQ的消息,並保存到數據庫
/// </summary>
public class MessageQueueService
{
    public static bool blnStopThread;
    public static string exTemp = string.Empty;

    public MessageQueueService()
    {
        //
        // TODO: 在此處添加構造函數邏輯
        //
    }

    public static void Start()
    {
        string queuePath = ".\\Private$\\zzl";
        IsQueueExists(queuePath);
        MessageQueue myQueue = new MessageQueue(queuePath);

        myQueue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Log) });

        do
        {
            try
            {
                // Receive and format the message.
                Message myMessage = myQueue.Receive(); //當消息隊列空時,線程會掛起
                Log log = (Log)myMessage.Body;

                if (log == null) return;

                Save(log);//保存到數據庫,此處略詳細代碼
            }
            catch (System.Exception ex)
            {
                //異常處理
                //……
            }
        } while (blnStopThread == false);
    }

    private static void IsQueueExists(string path)
    {
        if (!MessageQueue.Exists(path))
        {
            MessageQueue.Create(path);
        }
    }

  

private static void Save(Log entity)
      {
          using (SqlConnection sqlconn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["conn"].ToString()))
          {
              using (SqlCommand sqlcomm = new SqlCommand(
                  "INSERT INTO [Web_Logs]([LogID],[FromURL],[ExeSQL],[FromSystem],[HttpMethod],[OccurTime],[info]) VALUES (@LogID,@FromURL,@ExeSQL,@FromSystem,@HttpMethod,@OccurTime,@Info);"
                  , sqlconn))
              {
                  SqlParameter parameter = new SqlParameter("@ExceptionID", SqlDbType.VarChar, 36);
                  parameter.Value = Guid.NewGuid().ToString();
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@LogID", SqlDbType.VarChar, 36);
                  parameter.Value = entity.ID;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@FromURL", SqlDbType.VarChar, 200);
                  parameter.Value = string.Empty;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@ExeSQL", SqlDbType.VarChar, 1000);
                  parameter.Value = string.Empty;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@FromSystem", SqlDbType.Int);
                  parameter.Value = 1;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@HttpMethod", SqlDbType.VarChar, 50);
                  parameter.Value = string.Empty;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@Info", SqlDbType.VarChar, 50);
                  parameter.Value = entity.Info;
                  sqlcomm.Parameters.Add(parameter);

                  parameter = new SqlParameter("@OccurTime", SqlDbType.DateTime);
                  parameter.Value = entity.OccerTime;
                  sqlcomm.Parameters.Add(parameter);

                  sqlconn.Open();
                  sqlcomm.ExecuteNonQuery();
                  sqlconn.Close();
              }
          }
      }

public class Log
{
    public string ID { get; set; }

    public string Info { get; set; }

    public DateTime OccerTime { get; set; }

    public void PrintAll()
    {
        Console.WriteLine("{0}  {1}  {2}", ID, Info, OccerTime);
    }
}

 

為了使服務實時對MSMQ進行監控,需要我們在服務中使用一個定時事件,代碼如下:

當然在程序初始化時,需要為一個System.Timers.Timer類型進行相應的初始化工作

     

      this.timer1 = new System.Timers.Timer();
      this.timer1.Start();
      this.timer1.Interval = 1000;
      this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(this.timer1_Elapsed);

 這個WINDOWS服務我們已經添加完成,現在需要做的就是MSMQ部分了,事實上windows服務這塊主要是從MSMQ中得到消息,而在MSMQ這塊主要是向MSMQ去寫入消息,微軟的MSMQ完全支持復雜類型,也就是說你可以將一個類對象寫到MSMQ中

    /// <summary>
    /// 日志實體
    /// 可以被序列化
    /// </summary>
    [Serializable()]
    public sealed class Log
    {
        public string ID { get; set; }

        public string Info { get; set; }

        public DateTime OccerTime { get; set; }
    }

    /// <summary>
    /// MSMQ消息功能密封類
    /// 向消息隊列中寫入日志信息
    /// </summary>
    public sealed class MSMQLog
    {
        private static object sync = new object();
        private static object syncWrite = new object();
        static volatile MessageQueue writer = null;

        private static MessageQueue MSQWriter
        {
            get
            {
                if (writer == null)
                {
                    lock (sync)
                    {
                        if (writer == null)
                        {
                            string queuePath = ".\\Private$\\zzl";
                            IsQueueExists(queuePath);
                            writer = new MessageQueue(queuePath);
                        }
                    }
                }
                return writer;
            }
        }

        private static void IsQueueExists(string path)
        {
            if (!MessageQueue.Exists(path))
            {
                MessageQueue.Create(path);
            }
        }

        public static void Write(Log log)
        {
            lock (syncWrite)
            {
                MSQWriter.Send(log);
            }
        }
    }

 

 

 

當需要調用它時,可以這樣:

image

 

安裝與卸載windows服務的方法:

     installutil工具在目錄:系統盤:\WINDOWS\Microsoft.NET\Framework\v4.0.30319下,運行cmd,輸入

  C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil xxxx.exe 回車,即可完成windows服務的安裝。

  卸載則為輸入 C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\installutil /u xxxx.exe 回車。

 

本例經過自己實驗,已經成功,當若干客戶端同時進行某種操作時,可以同時寫入數據庫中,這就是我要說的,進行window服務和MSMQ技術實現高並發的解決方案


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM