京东零售云mPaaS移动端日志回捞追求实践
发布日期:2021-09-30 17:56    点击次数:127

1.1. 短序

移动操作体系为开发者挑供了功能雄厚的日志组件,比如说Android Studio 中的Logcat窗口会表现体系新闻,例如在进走垃圾回收时表现的新闻,以及行使Log类添加到行使的新闻, 能够辅助开发者进走高效的开发做事。然而在生产环境中,当用户(或者老板)逆馈一些题目,又比较偏僻难以复现的时候(不是Crash),往往就会陷入幼手幼脚的境地。此时,借助线上变态数据实时上报,吾们只能是祈祷用户网络环境通走,能够及时把变态数据第暂时间上报上来,然而这栽做法并不及保证吾们永世那么幸运。

于是,吾们必要研制一款性能较高的移动日志体系来解决吾们当下的难题,该体系能具备日志新闻完善、性能消耗矮、轻量级(体积)、准确回捞的特点。 接下来介绍一下移动日志体系的研发历程。

1.2. 设计方案

移动日志体系行使了Linux体系中挑供的mmap行为日志文件的载体,现在业内通走的XLOG日志组件、MMKV、美团Logan均采用了此方案,其最大的上风就是高效I/O、矮消耗、跨进程 等上风,接下来引入下mmap的基本介绍。

1.2.1. 什么是mmap?

操作体系分为内核态和用户态两栽运走模式:

内核态(Kernel MODE)能够运走操作体系程序 用户态(User MODE)能够运走用户程序 用户态(即行使程序)是不及直接对物理设备进走操作的(Ps:对物理设备进走操作,即对设备的物理地址写数据)。倘若想读取硬盘上的某一段数据清淡都必要经过 硬盘->内核->用户,即数据必要经历两次拷贝,效果相等矮下。 为晓畅决云云的题目,内存映射的概念展现了:内核映射即mmap,mmap将设备的物理地址映射到进程的虚拟地址,则用户操作虚拟内存时就相等于对物理设备进走操作了,缩短了内核到用户的一次数据拷贝,从而挑高数据的吞吐率。

在Linux中能够行使mmap用来在进程虚拟内存地址空间平分配地址空间,创建和物理内存的映射有关 :

当行使mmap映射文件到进程后,就能够直接操作这段虚拟地址进走文件的读写等操作,不消再调用read,write等体系调用。但需仔细,直接对该段内存写时不会写入超过现在文件大幼的内容。

总之,mmap区别于以去的文件读写,具备以下几个益处:

缩短了数据的拷贝次数,用内存读写取代I/O读写,挑高了文件读取效果 实现了用户空间和内核空间的高效交互手段。两空间的各自修改操作能够直接逆映在映射的区域内,从而被对方空间及时捕捉 挑供进程间共享内存及相互通信的手段。不管是父子进程照样无亲缘有关的进程,都能够将自己用户空间映射到联相符个文件或匿名映射到联相符片区域。从而议决各自对映射区域的改动,达到进程间通信和进程间共享的主意 同时,倘若进程A和进程B都映射了区域C,当A第一次读取C时议决缺页从磁盘复制文件页到内存中;但当B再读C的相通页面时,固然也会产生缺页变态,但是不再必要从磁盘中复制文件过来,而可直接行使已经保存在内存中的文件数据 可用于实现高效的大周围数据传输。内存空间不及,是制约大数据操作的一个方面,解决方案往往是借助硬盘空间配相符操作,补充内存的不及。但是进一步会造成大量的文件I/O操作,极大影响效果。这个题目能够议决mmap映射很益的解决。换句话说,但凡是必要用磁盘空间代替内存的时候,mmap都能够发挥其奏效 1.2.2. mmap的行使

对于移动端日志采集SDK来说,主要进走的做事就是将用户写入的数据保存到文件中,在这个过程中涉及到在native层调用mmap函数实现在进程虚拟内存地址空间平分配地址空间,创建和物理内存的映射有关。

接下来介绍一下Linux体系中mmap机制的行使流程:

mmap函数

函数声明
void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset); 
返回值表明

成功实走时,mmap()返回被映射区的指针。战败时,mmap()返回MAP_FAILED[其值为(void *)-1],error被设为以下的某个值:

EACCES:访问出错 EAGAIN:文件已被锁定,或者太众的内存已被锁定 EBADF:fd不是有效的文件描述词 EINVAL:一个或者众个参数无效 ENFILE:已达到体系对掀开文件的局限 ENODEV:指定文件所在的文件体系不声援内存映射 ENOMEM:内存不及,或者进程已超出最大内存映射数目 EPERM:权能不及,操作不批准 ETXTBSY:已写的手段掀开文件,同时指定MAP_DENYWRITE标志 SIGSEGV:试着向只读区写入 SIGBUS:试着访问不属于进程的内存区 参数表明

mmap在移动端代码中的行使

//用于写入文件的缓存Buffer static unsigned char *_buffer = NULL; // mmap缓存文件的大幼 static int mmap_cache_file = 100*1024;  void init() {   //第一步: 按照竖立的缓存位置生成用于映射的文件   makedir_mmapfile(cache_path);   //第二步:掀开缓存文件   int fd = open(cache_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);   //mmap映射的文件的判定   if(fd != -1) {      ......     //第三步:mmap映射文件到buffer内存中     _buffer = (unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);   }   //第四步:关闭文件句柄    close(fd); }  //第五步:操作mmap内存读写 void write(....) {   // 将要写入的数据封装,压缩和加密   data_zlib_compress();    //将mmap的缓存写入到文件中   fwrite(_buffer, sizeof(char), _buffer.length, dest_file);   fflush(dest_file);    // 文件大幼转折等有关操作   update(); } 
日志写入的流程

1.2.3. 移动日志体系架构介绍

客户端日志SDK为开发者挑供日志的打印,主要是将在线上运走期间产生的日志写入文件中,按照开发者的必要捞取指定的日志,为开发者解决线上题目挑供助力。吾们设计了已足基本功能的体系,架构如下图所示:

1.2.4. 客户端日志SDK介绍

日志SDK的架构如图展现,能够分为如下三层,每一层解决了分别的营业场景。

日志SDK在底层行使了流式压缩加密操作,在授与到写入的日志数据,先将数据进走压缩操作,然后再进走加密操作,整个过程中都是流式操作,避免了CPU峰值,缩短对CPU性能义务。在详细的实现中引入了MMAP机制解决了日志丢失题目,行使AES进走日志加密确保日志坦然性。

日志SDK议决服务端下发的策略进走本地日志的动态上报,这边吾们能够议决准时的拉取最新的策略,或者议决push通道更新本地的策略,再或者挑供上报接口,在用户的逆馈中,让用户将日志数据上报上来。现在在下发的策略中吾们进走了大量的自定义,对文件的大幼,缓存时长,日志的写入等级等有关的竖立进走下发操作,实现行使初起化后,筛选过滤,只将吾们必要的日志写入到文件中,为开发者行使。

日志SDK按照策略将指定的日志文件上传到指定的服务器上,这个服务器将对上传的日志进走解压休争码操作,将日志文件还原成原起的输入数据,详细的流程能够参考下面的营业流程。

日志SDK营业流程

日志SDK在的营业流程如下图所示,按照服务端配置的策略,采集指定的日志并进走数据的压缩加密等操作,然后主动将本地日志文件上传到中转服务,将上传效果等有关新闻同步到新闻展现的服务端。

日志SDK性能

上述设计中以及行使中,为了缩短对CPU以及内存的消耗,吾们议决行使mmap技术,将流式压缩加密缓存等操作迁移到native层,那么云云做相对于Java层的日志库吾们对于内存以及CPU的行使率降矮了众少,接下来吾们将行使一个Java层的日志库与行使mmap实现的native库进走对比。

测试条件

性能测试中采用了在联相符台幼米Note3 Android 9体系版本手机,别离测试了已有的Java日志库、现在日志库、美团Logan、腾讯XLog日志库的写入性能。议决写入速度、GC频率、CPU占用率几个维度来衡量日志库的写入性能,测试的效果只限于衡量现在测试环境,并不代外Android平台集体平均水准。

测试数据量:

测试效果 1. 内存的GC测试效果

Java日志库:

native日志库:

从上边的内存性能图片中能够望到,Java日志库在大量写日志的时候回造成屡次的GC,固然native日志库不会展现云云屡次的GC,从图中能够望到Java日志库的GC频率大约是1s/次,native日志库的GC频率大约是7.5s/次。

2. CPU行使率测试效果

Java日志库:

native日志库:

从上边CPU性能图片中能够望到,Java日志库在屡次写入日志的时候CPU的平均行使率大约为13%,native日志库在屡次写入日志的时候CPU的平均行使率大约为5%。

从上述内存以及CPU占用率的对比中,吾们能够望出native日志库相较于Java日志库来说,性能上有了很大的挑示,对于内存的占用较幼,在屡次的I/O操作以及加密压缩操作的情况下cpu的行使率仍保持在较矮值。

日志库性能的对比

上边吾们与Java日志进走了对比,接下来吾们将于其他行使mmap实现的日志库进走下对比:

1.3. 实践案例

在app的线上环境吾们能够遇到各栽题目,吾们期待将展现题目当天的日志获取到用于题目的分析,配相符解决题目。云云的营业场景几乎遮盖了大片面的营业场景,对于自立收银机云云的设备行使场景,运走时期的日志对于题目的排查尤为主要。

数科自立收银设备主要服务于各大超市卖场的自若结账,缓解众条人造收银通道仍无法抵消的收银压力。当展现题目的时候,吾们不能够对行使者进走回访,以是运走时候的日志对于题目排查尤为主要。

在未行使移动日志体系之前,遇到题目后,原由欠缺运营工具,对于题目的排查,必要占用较众的研发资源,在接入移动日志体系后,运营就能够独自处理大片面的题目。云云极大的挑高晓畅决题目的效果,缩短了研发侧参与排查运营题目的时间。

1.4. 写到末了

现在的sdk行使场景是准时拉取服务端的策略,按照下发的最新策略进走日志文件的上报,有必定的时间延后性,后期吾们将盛开主动上报日志的通道以及结相符push推送新闻,挑高日志回捞的及时性以及成功率。

现在的sdk暂时只声援移动端(Android以及iOS),在后续吾们将进走众端声援,将在RN,Flutter,幼程序以及H5等各栽行使场景中联相符行使现在日志库进走日志的采集和存储。



Powered by 黄网站色成年片大免费高清 @2013-2021 RSS地图 HTML地图