系统架构~高并发日志系统设计

对于一个项目来说,日志是必须的,一般日志的持久化方式有文件和数据库,而在多数情况下,我们都采用文件系统来实现,而对于高并发的情况下,频繁进行I/O操作,对系统的性能肯定是有影响的,这个毋庸置疑!针对这种高并发的场合,我们采用一种缓存队列的方式来处理这个Case是比较明智的,本文主要是向各位展现一下,我所设计的《高并发日志系统设计》,如在功能上有什么需要改进的地方,欢迎各位来回复。

一 项目结构图

二 项目实现代码

  /// <summary>
    /// 工作任务基类
    /// </summary>
    public abstract class JobBase
    {
        /// <summary>
        /// log4日志对象
        /// </summary>
        protected log4net.ILog Logger
        {
            get
            {
                return log4net.LogManager.GetLogger(this.GetType());//得到当前类类型(当前实实例化的类为具体子类)
            }
        }
    }
 public class ActionTimeJob : JobBase, IJob
    {

        #region Fields & Properties
        /// <summary>
        /// 锁对象
        /// </summary>
        private static object lockObj = new object();
        #endregion

        #region IJob 成员

        public void Execute(IJobExecutionContext context)
        {
            lock (lockObj)
            {
                try
                {
                    if ((System.Web.HttpRuntime.Cache["RunTime"] as Queue<Tuple<int, string>>) != null
                        && (System.Web.HttpRuntime.Cache["RunTime"] as Queue<Tuple<int, string>>).Count > 0)
                    {
                        var temp = (System.Web.HttpRuntime.Cache["RunTime"] as Queue<Tuple<int, string>>).Dequeue();
                        if (temp != null)
                        {
                            //! 超时,开始记录日志
                            global::Logger.Core.LoggerFactory.Instance.Logger_Info(
                                        string.Format("出现异常的页面:{0},页面加载需要的时间:{1}秒,异常发生时间:{2}"
                                        , temp.Item2, temp.Item1, DateTime.Now),"actionTime.log");
                        }
                    }
                }
                catch (Exception ex )
                {

                    throw ex;
                }
            }
        }

        #endregion
    }

从上面的代码中,我们可以看到,这是使用quartz组件实现的,对某个方法进行轮训调用的,下面是quartz的入口

           const string DEFAULTINTERVAL = "300";//默认为5分钟
            string user_Classroom_RJobInterval = ConfigurationManager.AppSettings["ActionRunTimeJob"]
          ?? DEFAULTINTERVAL;

            ISchedulerFactory sf = new Quartz.Impl.StdSchedulerFactory();
            IScheduler sched = sf.GetScheduler();
            //一个工作可以由多个组组成,而每个组又可以由多个trigger组成
            IDictionary<IJobDetail, IList<ITrigger>> scheduleJobs = new Dictionary<IJobDetail, IList<ITrigger>>();

            #region ActionRunTimeJob
            scheduleJobs.Add(JobBuilder.Create<ActionTimeJob>()
               .WithIdentity("job1", "group1")
               .Build(),
               new List<ITrigger>
                    {
                     (ICronTrigger)TriggerBuilder.Create()
                                                 .WithIdentity("trigger", "group1")
                                                 .WithCronSchedule(user_Classroom_RJobInterval)
                                                 .Build()
                    });

            sched.ScheduleJobs(scheduleJobs, true);
            sched.Start();
            #endregion

而何时向队列里添加信息这个功能还没有说,事实上,在MVC3里有这样一个功能,它可以向所有action上添加一些特性(过滤器,attribute),我们称它为全局过滤器,它的入口也是在global.asax里,下面添加了一个过滤器,实现的功能是当页面加载时间过长时,进行缓存队列的添加,这里默认是6秒时

    /// <summary>
    /// Action渲染页面所需要的时间
    /// </summary>
    public class ActionRenderTimeAttribute : System.Web.Mvc.ActionFilterAttribute
    {
        #region 本对象的timer不好使用
        /// <summary>
        /// 存储并发的队列
        /// </summary>
        public volatile static Queue<Tuple<int, string>> TempList = new Queue<Tuple<int, string>>();
        /// <summary>
        /// 时间戳
        /// </summary>
        static System.Timers.Timer sysTimer = new System.Timers.Timer(1000);
        /// <summary>
        /// 静态构造
        /// </summary>
        static ActionRenderTimeAttribute()
        {
            sysTimer.AutoReset = true;
            sysTimer.Enabled = true;
            sysTimer.Elapsed += sysTimer_Elapsed;
            sysTimer.Start();
        }
        /// <summary>
        /// 触发事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (TempList.Count > 0)
            {
                lock (lockObj)
                {
                    var temp = TempList.Dequeue();
                    //! 超时,开始记录日志
                    Logger.Core.LoggerFactory.Instance.Logger_Info(
                        string.Format("出现异常的页面:{0},超时时间{1}:秒,异常发生时间:{2}"
                        , temp.Item2, temp.Item1, DateTime.Now));
                }
            }
        }
        #endregion

        /// <summary>
        /// 锁对象
        /// </summary>
        static object lockObj = new object();
        /// <summary>
        /// 记录进行Action的时间
        /// </summary>
        DateTime joinTime;
        /// <summary>
        /// 进行action之前
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuting(System.Web.Mvc.ActionExecutingContext filterContext)
        {
            joinTime = DateTime.Now;
            base.OnActionExecuting(filterContext);
        }
        /// <summary>
        /// 渲染页面HTML之后
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnResultExecuted(System.Web.Mvc.ResultExecutedContext filterContext)
        {
            int outSeconds;//! 超时的秒数,默认为60000ms
            int isActionRender;//开关
            int.TryParse((System.Configuration.ConfigurationManager.AppSettings["ActionRenderTime"] ?? "6000").ToString(), out outSeconds);
            int.TryParse((System.Configuration.ConfigurationManager.AppSettings["isActionRender"] ?? "0").ToString(), out isActionRender);

            var timeSpan = (DateTime.Now - joinTime).Milliseconds;
            if (timeSpan > outSeconds && isActionRender == 1)
            {
                lock (lockObj)
                {
                    var temp = (System.Web.HttpRuntime.Cache["RunTime"] as Queue<Tuple<int, string>>) ?? new Queue<Tuple<int, string>>();
                    temp.Enqueue(new Tuple<int, string>(timeSpan, filterContext.RequestContext.HttpContext.Request.Url.AbsoluteUri));
                    System.Web.HttpRuntime.Cache.Insert("RunTime", temp);
                }
            }

            base.OnResultExecuted(filterContext);
        }

    }

下面是FilterConfig注入的代码

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new MVVM.ActionRenderTimeAttribute());
        }
    }

系统架构~高并发日志系统设计

时间: 2024-08-05 15:38:54

系统架构~高并发日志系统设计的相关文章

关于PHP高并发抢购系统设计

内容并发抢购系统注意事项高并发架构设计描述程序端核心代码实现订单流程mysql 端并发解决方案 注意事项(1)高并发环境下,对于服务器cup.内存.网络宽带使用率会瞬间暴涨,需要注意对同服务器上其他应用的影响.(项目解耦,高并发应用独立部署)(2)服务器高负载运行,容易出现死机,重启服务器场景,要提前考虑内存(redis)数据备份与恢复,防止用户抢购数据丢失.(3)高并发应用首先要注重稳定性,其次是性能上优化. (4) 一台服务器能够支持多少并发量nginx服务为例:worker_process

秒杀系统实现高并发的优化

一:先上代码,看着代码学习效率更好:https://github.com/3218870799/Seckill 二:高并发问题就是指在同一个时间点,有大量用户同时访问URL地址,比如淘宝双11都会产生高并发. 三:高并发带来的后果 服务端??导致站点服务器.DB服务器资源被占满崩溃.??数据的存储和更新结果和理想的设计不一致. 用户角度??尼玛,网站这么卡,刷新了还这样,垃圾网站,不玩了 四:阻碍服务速度的原因 1:事物行级锁的等待:java的事务管理机制会限制在一次commit之前,下一个用户

SpringCloud注册中心集群化及如何抗住大型系统的高并发访问

一.场景引入 本人所在的项目由于直接面向消费者,迭代周期迅速,所以服务端框架一直采用Springboot+dubbo的组合模式,每个服务由service模块+web模块构成,service模块通过公司API网关向安卓端暴 露restful接口,web模块通过dubbo服务向service模块获取数据渲染页面.测试环境dubbo的注册中心采用的单实例的zookeeper,随着时间的发现注册在zookeeper上的生产者和消费者越来越多,测试 人员经常在大规模的压测后发现zookeeper挂掉的现象

Go项目实战:打造高并发日志采集系统(六)

前情回顾 前文我们完成了日志采集系统的日志文件监控,配置文件热更新,协程异常检测和保活机制. 本节目标 本节加入kafka消息队列,kafka前文也介绍过了,可以对消息进行排队,解耦合和流量控制的作用,为什么一定要用kafka呢?主要原因就是在日志高并发读取后,如果直接将消息发给前端或者写入数据库,会造成崩溃或者卡死.kafka可以对消息进行排队和减轻压力,这样无论以后将这些消息录入数据库也好,传给前端分析也好,都能保证系统稳定性.代码我们也写过和测试了,只需要将之前写好的kafka读写消息代码

互联网架构“高并发”

原文地址:https://cloud.tencent.com/developer/article/1048632 一.什么是高并发 高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求. 高并发相关常用的一些指标有响应时间(Response Time),吞吐量(Throughput),每秒查询率QPS(Query Per Second),并发用户数等. 响应时间:系统对请求做出响应的时间.例如系统处理一个H

SSM实战——秒杀系统之高并发优化

一:高并发点 高并发出现在秒杀详情页,主要可能出现高并发问题的地方有:秒杀地址暴露.执行秒杀操作. 二:静态资源(页面)访问优化--CDN CDN,内容分发网络.我们把静态的资源(html/css/js)放在CDN上,以加快用户获取数据的速度. 用户访问页面时,优先从最近的CDN服务器上获取页面资源,而不是从单一的网站服务器上获取.只有CDN获取不到才会访问后端服务器. 因此,我们可以使用CDN进行网站的加速优化,把静态资源(或某些动态资源)推送到CDN站点上.(大公司自己搭建CDN网络,小公司

系统架构高可用系统设计原则01

一.也谈谈高可用"高可用性"(High Availability)简称HA,通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性.通俗来讲就是通过专业的设计保障系统相关服务能够不间断的稳定运行.度量方式:%availability=(Total Elapsed Time-Sum of Inoperative Times)/ Total Elapsed Time 可用性和系统组件的失败率相关.衡量系统设备失败率的一个指标是"失败间隔平均时间"M

Go项目实战:打造高并发日志采集系统(三)

前文中已经完成了文件的监控,kafka信息读写,今天主要完成配置文件的读写以及热更新.并且规划一下系统的整体结构,然后将之前的功能串起来形成一套完整的日志采集系统. 前情提要 上一节我们完成了如下目标1 完成kafka消息读写2 借助tailf实现文件监控,并模拟测试实时写文件以及文件备份时功能无误. 本节目标 1 编写系统结构,在主函数中加载配置2 管理配置文件,实现热更新 实现文件管理,支持热更新 golang中vipper库提供了配置文件的读取和监控功能,我们可以监控配置文件从而实现热更新

从宜人贷系统架构看互联网高并发对金融系统架构的挑战

原文:http://www.p2pquan.com/article-740-1.html 一.简介 随着互联网金融的持续火热,越来越多的银行纷纷发布了各自的互联网金融产品.但是互联网产品“高并发.大数据量”的特点却对于银行传统的核心系统架构带来了新的挑战. 1.互联网的核心技术特征 当前互联网的核心技术特征主要可以概括为:分布式,易扩展,大量低端设备,底层开源软件.分布式结构可以通过平行扩展来支撑互联网上蜂拥而至的访问客户.同时,基于客户行为分析的大数据平台也需要分布式系统来完成,其中最典型的就