public static class LogManager { /// <summary> /// 构造函数 /// </summary> static LogManager() { Start(); } #region 队列方法 /// <summary> /// 日志队列 /// </summary> private static Queue<Log> ListQueue = new Queue<Log>(); class Log { public string Msg { get; set; } } public static void WriteLog(string msg) { Log log = new Log() { Msg = msg }; ListQueue.Enqueue(log); } private static void Start()//启动 { Thread thread = new Thread(threadStart); thread.IsBackground = true; thread.Start(); } private static void threadStart() { while (true) { if (ListQueue.Count > 0) { try { ScanQueue(); } catch (Exception ex) { throw; } } else { //没有任务,休息3秒钟 Thread.Sleep(3000); } } } //要执行的方法 private static void ScanQueue() { while (ListQueue.Count > 0) { try { //从队列中取出 Log log = ListQueue.Dequeue();
//执行日志记录操作 具体项目具体实现方式不一样 //function(); } catch (Exception ex) { throw; } } } #endregion }
最近在排查线上异常问题是发现,记录日志的方式是直接记录到数据库中,应用中调用的方式为直接sql语句执行插入操作.由于调用的地方越来越多,有时候还会有大批量的定时任务也需要记录日志,随会偶尔爆出并发执行的问题,数据库执行遇到阻塞时还会影响应用的执行.
所以进行了简单的修改,将日志打印方式改为先存储到内部队列然后通过队列有序出队的方式单线程操作记录数据库,这样就避免了多任务同时操作引起的数据库阻塞的问题也不会丢失日志