前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用windows服务和MSMQ和进行日志管理(解决高并发问题)

使用windows服务和MSMQ和进行日志管理(解决高并发问题)

作者头像
跟着阿笨一起玩NET
发布2018-09-19 16:44:57
1.6K0
发布2018-09-19 16:44:57
举报
文章被收录于专栏:跟着阿笨一起玩NET

首先,建立一个windows服务项目

然后进行设计视图

在工作区空白处右属,添加一个安装项目

然后就可以写我们的代码了,我们的服务需要实时监视MSMQ的队列中有没有记录,如果有,就向数据库中插入

核心代码如下

代码语言:javascript
复制
/// <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类型进行相应的初始化工作

代码语言:javascript
复制
      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中

代码语言:javascript
复制
    /// <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);
            }
        }
    }

当需要调用它时,可以这样:

安装与卸载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技术实现高并发的解决方案

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2012-02-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档