一种嵌入式操作系统异步日志记录的实现方法与流程

文档序号:25420247发布日期:2021-06-11 21:31阅读:129来源:国知局
一种嵌入式操作系统异步日志记录的实现方法与流程

本发明涉及通信的技术领域,具体地,涉及一种嵌入式操作系统异步日志记录的实现方法。



背景技术:

每个大型应用项目都包含一套日志记录系统,日志记录是开发过程中的重要组成部分,它提供了有关应用程序运行的精确上下文信息,日志可以保存在永久存储介质中,以供以后参考和研究。然而很多业务系统,尤其是实时业务系统,需要打印详细的上下文和参数来追踪问题;如果在日志记录之前就对报文进行格式化,会非常影响日志输出的性能,可能会使应用程序变慢,进而加重系统负担。log4j是基于java的日志记录工具,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。但是日志形成优化方面一般。logback在log4j的基础上重写了部分内核代码,在一些关键路径上性能提升了10倍以上,初始化内存加载的时间也更小了。在数据吞吐量和延迟方面实现了一定的提升。但仍然无法满足实时系统的实时要求。

针对上述中的相关技术,发明人认为存在有在多线程环境下,吞吐量偏低的问题,因此,需要提出一种技术方案以改善上述技术问题。



技术实现要素:

针对现有技术中的缺陷,本发明的目的是提供一种嵌入式操作系统异步日志记录的实现方法。

根据本发明提供的一种嵌入式操作系统异步日志记录的实现方法,包括如下步骤:

步骤1:创建日志记录执行线程,日志输出语句与业务逻辑语句在不同线程中运行;

步骤2:创建并发线程间数据交换的通讯框架,不同的日志输出会创建不同的执行线程;

步骤3:创建日志输出执行线程,日志事件根据日志的配置在单独的线程中执行日志写入操作。

优选地,所述步骤1中的日志输出语句与业务逻辑语句在不同线程中运行,有专门的线程用于进行日志输出操作,处理业务逻辑的主线程执行后续业务逻辑。

优选地,所述步骤2包括如下步骤:

步骤2.1:框架内部核心数据结构队列为ringbuffer,设计为无锁环形队列;

步骤2.2:并发线程对环形队列的访问采用cas的无锁策略方法;

步骤2.3:使用缓存行填充的方法来解决多个变量共享同一个缓存行的性能问题。

优选地,所述步骤2.1中的无锁环形队列首尾相连,对列循环使用,使用数组来保存。

优选地,所述步骤2.2中的并发线程间通讯看成是生产者和消费者模型。

优选地,所述用户线程为生产者,日志输出执行线程为消费者,单个生产者和单个消费者,生产者和消费者各自维护自己的指针,不需要加锁。

优选地,所述生产者为一个,消费者为多个,消费者控制自己的指针,依次读取各自序号对应的数据,不需要加锁。

优选地,所述生产者为多个,多个线程共用一个写指针,采用cas的方法。

优选地,所述步骤2.3中的内存的访问速度低于cpu的运行速度,在内存和cpu之间,加入cache,cpu访问cache中的数据,cache未命中,访问内存中的数据。

优选地,所述步骤3中的日志输出是文件或者网络数据包;采用线程池的方法,线程池在日志输出之前创建完成。

与现有技术相比,本发明具有如下的有益效果:

1、本发明中提到的方法能够大幅提高日志记录的吞吐量,以log4j和logback框架作为比较对象,测试不同线程数量的日志吞吐量。

2、本发明的响应时间明显改善,响应时间是指记录日志所花费的时间,时间越短、日志记录延迟越小。该时间等于服务时间和等待时间的总和,等待时间是指日志记录事件等待服务执行的时间。该时间在服务高峰期会明显增大,所以不应忽略掉。以log4j和logback框架作为比较对象,测试一定负载下的响应延迟时间。

附图说明

通过阅读参照以下附图对非限制性实施例所作的详细描述,本发明的其它特征、目的和优点将会变得更明显:

图1为本发明异步日志记录逻辑框图;

图2为本发明日志吞吐量测试结果条形图;

图3为本发明响应时间测试结果数据图;

具体实施方式

下面结合具体实施例对本发明进行详细说明。以下实施例将有助于本领域的技术人员进一步理解本发明,但不以任何形式限制本发明。应当指出的是,对本领域的普通技术人员来说,在不脱离本发明构思的前提下,还可以做出若干变化和改进。这些都属于本发明的保护范围。

本发明提供一种嵌入式操作系统异步日志记录的实现方法的实施过程主要是初始化的过程,初始化包含三个部分:创建环形队列用于接收用户发送的日志事件;创建日志事件处理线程,用于从环形队列中获取日志事件并处理;创建线程池用于根据日志配置处理日志的具体输出过程,包括网络、文件等。初始化完成后,用户首先创建日志记录对象,然后配置该对象,最后根据需要完成日志信息的记录功能。

本发明包括如下步骤:

步骤1:创建日志记录执行线程。日志输出语句与程序的业务逻辑语句往往在同一个线程运行,即当输出日志时,必须等待日志输出语句执行完毕后,才能执行后面的业务逻辑语句。本方法中,日志输出语句与业务逻辑语句并不是在同一个线程中运行,而是有专门的线程用于进行日志输出操作,处理业务逻辑的主线程不用等待即可执行后续业务逻辑。

步骤2:创建并发线程间数据交换的通讯框架。每个用户线程都会调用日志api接口,不同的日志输出会创建不同的执行线程,该通讯框架可以抽象为生产者和消费者模型。用户线程为生产者,日志输出执行线程为消费者。

其中,步骤2包括如下步骤:

步骤2.1:框架内部核心数据结构队列为ringbuffer,设计为无锁环形队列。意味着首尾相连,对列可以循环使用,使用数组来保存。环形队列的生命周期通常是永生的,减少了内存动态申请和释放的压力。环形队列没有尾指针,只维护一个指向数组中的下一个可用元素的序号。因为环形队列不控制是否需要重叠,所以不需要删除队列中的数据,直到有新的数据覆盖。数组结构的保存对cpu缓存是友好的,也就是说在硬件级别,数组中的元素是会被预加载的,因此在访问数组中的元素中,cpu无需每次去内存加载数组中的下一个元素。

步骤2.2:并发线程对环形队列的访问采用cas的无锁策略方法,该方法针对并发线程间大数据交换的场景能有效提升数据的吞吐量。并发线程间通讯可以看成是生产者和消费者模型。

1.当单个生产者和单个消费者时,由于生产者和消费者各自维护自己的指针,所以不需要加锁。

2.当有一个生产者和多个消费者时,每个消费者各自控制自己的指针,依次读取各自序号对应的数据,也不需要加锁。

3.当有多个生产者时,多个线程共用一个写指针,对于这种情况我们采用cas的方法来保证多线程的写安全。cas操作包含3个操作数:cas,功能描述为:取地址a的值与b比较,如果相等,则将c赋值给地址a,否则更新a和b的值,重新执行cas操作,直到赋值成果。cas是由硬件实现的轻量级指令,同时cpu保证了次操作的原子性。

通过cas实现多生产者、多消费者对环形队列的并发访问。cas相当于乐观锁,该方法避免了由于锁竞争、线程切换等带来的性能损失。能有效提升并发线程间数据通讯的吞吐量。

步骤2.3:使用缓存行填充的方法来解决多个变量共享同一个缓存行的性能问题。内存的访问速度远远低于cpu的运行速度,在内存和cpu之间,加入cache,cpu首先访问cache中的数据,cache未命中,才访问内存中的数据。cache是以缓存行为单位存储的,当多个线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能。

下面代码缓存行填充的方法,就是实例变量前后各加7个long形变量,用空间换时间。

步骤3:创建日志输出执行线程,日志事件会根据日志的配置在单独的线程中执行日志写入操作。日志输出可能是文件,也可能是网络数据包。该步骤采用线程池的方法,线程池在日志输出之前创建完成,避免了日志输出时动态创建线程对日志系统性能的影响。另外,日志输出可能会遇到硬件速率的瓶颈问题,线程池可以保证不同配置的日志输出互不影响。

本领域技术人员知道,除了以纯计算机可读程序代码方式实现本发明提供的系统及其各个装置、模块、单元以外,完全可以通过将方法步骤进行逻辑编程来使得本发明提供的系统及其各个装置、模块、单元以逻辑门、开关、专用集成电路、可编程逻辑控制器以及嵌入式微控制器等的形式来实现相同功能。所以,本发明提供的系统及其各项装置、模块、单元可以被认为是一种硬件部件,而对其内包括的用于实现各种功能的装置、模块、单元也可以视为硬件部件内的结构;也可以将用于实现各种功能的装置、模块、单元视为既可以是实现方法的软件模块又可以是硬件部件内的结构。

以上对本发明的具体实施例进行了描述。需要理解的是,本发明并不局限于上述特定实施方式,本领域技术人员可以在权利要求的范围内做出各种变化或修改,这并不影响本发明的实质内容。在不冲突的情况下,本申请的实施例和实施例中的特征可以任意相互组合。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1