zoukankan      html  css  js  c++  java
  • 用队列解决高并发 之 记录日志

    用队列解决高并发 之 记录日志

     

            在高并发量的情况下,有多种平时不会出现的问题会导致用户等待,下面我们用日志记录为例来说明一种解决方案——队列。

    创建一个工具类:LogCommon    如下:

    namespace Heima8Web.Common
    {
        public class LogCommon
        {
            public static Queue<string> LogQueue = new Queue<string>();             //实例化一个队列

            static LogCommon()          //日志写入文件的方法在类的静态构造函数中实现,这样,在队列被调用的时候,会自动调用此方法
            {
       
                string strFileName = HttpContext.Current.Request.MapPath("/App_Data/Log/" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt");           //在新开启的线程以外获取文件路径(每一个请求对应一个线程,到新的线程里去以后,就不能获得到当前上下文了)
       
                //开启线程池来写日志
                ThreadPool.QueueUserWorkItem(a =>
                    {
                        while (true)
                        {
                            string ex = string.Empty;
                            
                            lock ("Itcast-DotNet-AspNet-Glable-LogLock")
                            {
                                if (LogQueue.Count > 0)   //如果队列中有数据,将其出队列
                                {
                                    ex = LogQueue.Dequeue();
                                }
                                else
                                {
                                    Thread.Sleep(30);        //如果没有数据,让线程睡30毫秒,之后进入下一轮循环
                                    continue;
                                }
                            }
          
                             //创建流,将日志写入到文件中
                            using (FileStream fs = new FileStream(strFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                            {
                                using (StreamWriter writer = new StreamWriter(fs,Encoding.Default))
                                {
                                    writer.Write(ex.ToString());
                                }
                            }
                        }

                    });


            }


            public static void WriteLog(string str)                //将日志写入到队列中的方法
            {
                lock ("Itcast-DotNet-AspNet-Glable-LogLock")
                {
                    LogQueue.Enqueue(str);
                }
            }


        }
    }

    ------------ 

    在 HttpApplication 管道的 Application_Error中注册事件,
    即在 global 文件的 Application_Error事件中写如下代码:

      protected void Application_Error(Object sender, EventArgs e)
      {
               
                     Exception ex = Server.GetLastError();      //拿到错误消息
              
                     Common.LogCommon.WriteLog(ex.ToString());  //将错误消息加到队列里面去

      }

    =========================================================

    注:在调用 Common.LogCommon.WriteLog 方法的时候,静态构造函数LogCommon()会被自动调用,因为

    C#在使用静态构造函数时的几个原则:
       1.静态构造函数在创建类的实例之前会被调用,因此在所有实例构造函数之前会被调用。
       2.静态构造函数在创建类的第一个实例之前会被调用。
       3.静态构造函数在引用静态字段之前会被调用。

    在新开启的线程里面是获取不到当前上下文的

  • 相关阅读:
    python中字典排序,列表中的字典排序
    Python模块:operator简单介绍
    java 物理资源回收 finally与try
    Eclipse相对路径
    java Lambda
    java 匿名内部类
    java File类
    java单例类
    java 创建子类
    jvm运行时数据区域
  • 原文地址:https://www.cnblogs.com/key1309/p/3402859.html
Copyright © 2011-2022 走看看