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.静态构造函数在引用静态字段之前会被调用。

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

  • 相关阅读:
    SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)
    SpringCloud系列一:SpringCloud的简介和架构
    SpringBoot系列十二:SpringBoot整合 Shiro
    SpringBoot系列十一:SpringBoot整合Restful架构(使用 RestTemplate 模版实现 Rest 服务调用、Swagger 集成、动态修改日志级别)
    SpringBoot系列十:SpringBoot整合Redis
    SpringBoot系列九:SpringBoot服务整合(整合邮件服务、定时调度、Actuator监控)
    SpringBoot系列八:SpringBoot整合消息服务(SpringBoot 整合 ActiveMQ、SpringBoot 整合 RabbitMQ、SpringBoot 整合 Kafka)
    SpringBoot系列七:SpringBoot 整合 MyBatis(配置 druid 数据源、配置 MyBatis、事务控制、druid 监控)
    SpringBoot系列六:SpringBoot整合Tomcat
    SpringBoot系列五:SpringBoot错误处理(数据验证、处理错误页、全局异常)
  • 原文地址:https://www.cnblogs.com/key1309/p/3402859.html
Copyright © 2011-2022 走看看