抄的日志

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

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

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

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

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

时间: 2024-11-04 17:10:18

抄的日志的相关文章

zabbix_agent反复报警-日志显示“first network error”的问题

1.问题的展现 在zabbix上有那么几个 IP 反复地报错"Zabbix agent on XXXX is unreachable for 10 minutes",用telnet测试客户端端口没问题,正常.过上那么或几分钟或几十分钟,就消失了,然后一会就又报警,这样下来机器的数据曲线是断断续续的,影响虽不大,不过挺烦人.SA上去也不仔细看,把服务一重启也不管有没有解决问题.      后来我自己上去,查看服务端日志.除了说"某个Key 的数据无法获得,超时而失败的"

iBatis使用log4j2输出日志

原文链接这里 iBatis是一个老项目,2.3.4.726版本发布之后,项目改名为MyBatis,项目主页目前为http://mybatis.github.io/. 我从08年开始接触iBatis,一直使用2.3.4.726版本,直至当前的项目.iBatis恰到好处的满足了项目组在ORM.SQL维护方面的需求,所以也一直懒得换成其它同类开源软件,比如MyBatis. 最近参与新的项目开发,一切都要从零开始.为了节省时间,我直接把原项目中数据库相关操作的代码拿过来使用,发现遇到一个问题.新项目基于

JAVA中自定义日志输出到指定文件

虽然JAVA日志包提供的功能已经很方便,但是假如我们有新的需求如:将日志文件保存到我们希望的位置并在日志文件名中添加日期且保存指定时间内的日志文件:按照自己希望的格式输出日志内容.对于这些需求我们只要扩展java.util.logging.StreamHandler(Handler的子类),java.util.logging.Formatter创建自定义的处理器及格式化器即可以实现.下面是个例子,它分别创建了Handler及Formatter的子类,以便实现将日志文件保存到我们需要的位置,及在日

用Linux自带的Logrotate来管理日志

Logrotate是由cron控制,cron在规定的时间执行 " logrotate  /etc/logrotate.conf "命令.将对象日志进行转储,删除,压缩等操作... 这是logrotate日志轮替工具的一段官方简介: The logrotate utility is designed to simplify the administration of log files on a system which generates a lot of log files. Log

crontab 移动日志-超越昨天的自己系列(12)

linux上定时执行某些脚本是管理服务器的时候比较常用的场景,比如定时检查进程是否存在,定时启动或关闭进程,定时检查日志删除日志等. 当我打开google百度crontab时长篇大论的一大堆,详细解释的一大堆,各种抄来抄去,现在觉得资源多了未必是好事. 假设是定时执行shell,来移动log文件 找到个网上的脚本: #!/bin/bash log_path="" #此处定义你的日志文件夹路径 expried_time=7 #此处定义你的日志过期时间,如7天 function mvLog

用 Linux自带的logrotate 来管理日志

大家可能都有管理日志的需要,比如定时压缩日志,或者当日志超过一定大小时就自动分裂成两个文件等.最近就接到这样一个小任务.我们的程序用的是C语言,用log4cpp的library来实现日志记录.但是问题是log4cpp并不支持当日志超过一定大小时自动分裂的功能,只能从头覆盖之前的日志,但这显然不是我们想要的.经过一番搜索,我发现其实Linux自带的logrotate命令就能够实现这样的功能. 这是logrotate的一段简介: The logrotate utility is designed t

Java多线程知识小抄集(三)

本文主要整理博主遇到的Java多线程的相关知识点,适合速记,故命名为"小抄集".本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆. 51. SimpleDateFormat非线程安全 当多个线程共享一个SimpleDateFormat实例的时候,就会出现难以预料的异常. 主要原因是parse()方法使用calendar来生成返回的Date实例,而每次parse之前,都会把calendar里的相关属性清除掉.问题是这个calendar是

Java多线程知识小抄集(二)

本文主要整理博主遇到的Java多线程的相关知识点,适合速记,故命名为"小抄集".本文没有特别重点,每一项针对一个多线程知识做一个概要性总结,也有一些会带一点例子,习题方便理解和记忆. 1-26请参考<Java多线程知识小抄集(一)> 27. ConcurrentHashMap ConcurrentHashMap是线程安全的HashMap,内部采用分段锁来实现,默认初始容量为16,装载因子为0.75f,分段16,每个段的HashEntry 28. 线程安全的非阻塞队列 非阻塞

python(13)---发邮件、写日志、操作redis数据库

一.写邮件 import yagmail user = '[email protected]' password = 'rtcxbuejmqrdgjcd' #不是qq密码,是邮件授权码 在qq邮箱,设置--账户--开启POP3/SMTP服务,获得授权码 m=yagmail.SMTP(host='smtp.qq.com',user=user,password=password) #host-- 163邮箱用 tp.163.com m.send(to=['[email protected]','xx