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


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

     

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

    创建一个工具类: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.静态构造函数在引用静态字段之前会被调用。

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

  • 相关阅读:
    Mysql支持的数据类型
    JavaScript 原型中的哲学思想
    99%的人都理解错了HTTP中GET与POST的区别
    Let's Encrypt,站点加密之旅
    说说cglib动态代理
    说说Java代理模式
    RESTful API 编写指南
    RESTful 架构风格概述
    Centos 6 搭建安装 Gitlab
    超详细的阿里字节Spring面试技术点总结(建议收藏)
  • 原文地址:https://www.cnblogs.com/key1309/p/3402859.html
Copyright © 2020-2023  润新知