自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

京東零售云mPaaS移動端日志回撈探索實踐

云計算 PaaS
移動操作系統(tǒng)為開發(fā)者提供了功能豐富的日志組件,比如說Android Studio 中的Logcat窗口會顯示系統(tǒng)消息,例如在進行垃圾回收時顯示的消息,以及使用Log類添加到應(yīng)用的消息, 能夠輔助開發(fā)者進行高效的開發(fā)工作。

1.1. 引言

移動操作系統(tǒng)為開發(fā)者提供了功能豐富的日志組件,比如說Android Studio 中的Logcat窗口會顯示系統(tǒng)消息,例如在進行垃圾回收時顯示的消息,以及使用Log類添加到應(yīng)用的消息, 能夠輔助開發(fā)者進行高效的開發(fā)工作。然而在生產(chǎn)環(huán)境中,當用戶(或者老板)反饋一些問題,又比較冷僻難以復(fù)現(xiàn)的時候(不是Crash),常常就會陷入一籌莫展的境地。此時,借助線上異常數(shù)據(jù)實時上報,我們只能是祈禱用戶網(wǎng)絡(luò)環(huán)境通暢,能夠及時把異常數(shù)據(jù)第一時間上報上來,然而這種做法并不能保證我們永遠那么幸運。

于是,我們需要研制一款性能較高的移動日志系統(tǒng)來解決我們當下的難題,該系統(tǒng)能具備日志信息完整、性能損耗低、輕量級(體積)、精確回撈的特點。 接下來介紹一下移動日志系統(tǒng)的研發(fā)歷程。

1.2. 設(shè)計方案

移動日志系統(tǒng)使用了Linux系統(tǒng)中提供的mmap作為日志文件的載體,目前業(yè)內(nèi)流行的XLOG日志組件、MMKV、美團Logan均采用了此方案,其最大的優(yōu)勢就是高效I/O、低損耗、跨進程 等優(yōu)勢,接下來引入下mmap的基本介紹。

1.2.1. 什么是mmap?

操作系統(tǒng)分為內(nèi)核態(tài)和用戶態(tài)兩種運行模式:

  • 內(nèi)核態(tài)(Kernel MODE)能夠運行操作系統(tǒng)程序 用戶態(tài)(User MODE)能夠運行用戶程序
  • 用戶態(tài)(即應(yīng)用程序)是不能直接對物理設(shè)備進行操作的(Ps:對物理設(shè)備進行操作,即對設(shè)備的物理地址寫數(shù)據(jù))。如果想讀取硬盤上的某一段數(shù)據(jù)通常都需要經(jīng)過 硬盤->內(nèi)核->用戶,即數(shù)據(jù)需要經(jīng)歷兩次拷貝,效率十分低下。 為了解決這樣的問題,內(nèi)存映射的概念出現(xiàn)了:內(nèi)核映射即mmap,mmap將設(shè)備的物理地址映射到進程的虛擬地址,則用戶操作虛擬內(nèi)存時就相當于對物理設(shè)備進行操作了,減少了內(nèi)核到用戶的一次數(shù)據(jù)拷貝,從而提高數(shù)據(jù)的吞吐率。

在Linux中可以使用mmap用來在進程虛擬內(nèi)存地址空間中分配地址空間,創(chuàng)建和物理內(nèi)存的映射關(guān)系 :

當使用mmap映射文件到進程后,就可以直接操作這段虛擬地址進行文件的讀寫等操作,不必再調(diào)用read,write等系統(tǒng)調(diào)用。但需注意,直接對該段內(nèi)存寫時不會寫入超過當前文件大小的內(nèi)容。

總之,mmap區(qū)別于以往的文件讀寫,具備以下幾個優(yōu)點:

  • 減少了數(shù)據(jù)的拷貝次數(shù),用內(nèi)存讀寫取代I/O讀寫,提高了文件讀取效率
  • 實現(xiàn)了用戶空間和內(nèi)核空間的高效交互方式。兩空間的各自修改操作可以直接反映在映射的區(qū)域內(nèi),從而被對方空間及時捕捉
  • 提供進程間共享內(nèi)存及相互通信的方式。不管是父子進程還是無親緣關(guān)系的進程,都可以將自身用戶空間映射到同一個文件或匿名映射到同一片區(qū)域。從而通過各自對映射區(qū)域的改動,達到進程間通信和進程間共享的目的
  • 同時,如果進程A和進程B都映射了區(qū)域C,當A第一次讀取C時通過缺頁從磁盤復(fù)制文件頁到內(nèi)存中;但當B再讀C的相同頁面時,雖然也會產(chǎn)生缺頁異常,但是不再需要從磁盤中復(fù)制文件過來,而可直接使用已經(jīng)保存在內(nèi)存中的文件數(shù)據(jù)
  • 可用于實現(xiàn)高效的大規(guī)模數(shù)據(jù)傳輸。內(nèi)存空間不足,是制約大數(shù)據(jù)操作的一個方面,解決方案往往是借助硬盤空間協(xié)助操作,補充內(nèi)存的不足。但是進一步會造成大量的文件I/O操作,極大影響效率。這個問題可以通過mmap映射很好的解決。換句話說,但凡是需要用磁盤空間代替內(nèi)存的時候,mmap都可以發(fā)揮其功效

1.2.2. mmap的使用

對于移動端日志采集SDK來說,主要進行的工作就是將用戶寫入的數(shù)據(jù)保存到文件中,在這個過程中涉及到在native層調(diào)用mmap函數(shù)實現(xiàn)在進程虛擬內(nèi)存地址空間中分配地址空間,創(chuàng)建和物理內(nèi)存的映射關(guān)系。

接下來介紹一下Linux系統(tǒng)中mmap機制的使用流程:

mmap函數(shù)

  • 函數(shù)聲明
  1. void* mmap(void* __addr, size_t __size, int __prot, int __flags, int __fd, off_t __offset); 
  • 返回值說明

成功執(zhí)行時,mmap()返回被映射區(qū)的指針。失敗時,mmap()返回MAP_FAILED[其值為(void *)-1],error被設(shè)為以下的某個值:

  1. EACCES:訪問出錯
  2. EAGAIN:文件已被鎖定,或者太多的內(nèi)存已被鎖定
  3. EBADF:fd不是有效的文件描述詞
  4. EINVAL:一個或者多個參數(shù)無效
  5. ENFILE:已達到系統(tǒng)對打開文件的限制
  6. ENODEV:指定文件所在的文件系統(tǒng)不支持內(nèi)存映射
  7. ENOMEM:內(nèi)存不足,或者進程已超出最大內(nèi)存映射數(shù)量
  8. EPERM:權(quán)能不足,操作不允許
  9. ETXTBSY:已寫的方式打開文件,同時指定MAP_DENYWRITE標志
  10. SIGSEGV:試著向只讀區(qū)寫入
  11. SIGBUS:試著訪問不屬于進程的內(nèi)存區(qū)
  • 參數(shù)說明

 

mmap在移動端代碼中的使用

 

  1. //用于寫入文件的緩存Buffer 
  2. static unsigned char *_buffer = NULL
  3. // mmap緩存文件的大小 
  4. static int mmap_cache_file = 100*1024; 
  5.  
  6. void init() { 
  7.   //第一步: 根據(jù)設(shè)置的緩存位置生成用于映射的文件 
  8.   makedir_mmapfile(cache_path); 
  9.   //第二步:打開緩存文件 
  10.   int fd = open(cache_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); 
  11.   //mmap映射的文件的判斷 
  12.   if(fd != -1) { 
  13.      ...... 
  14.     //第三步:mmap映射文件到buffer內(nèi)存中 
  15.     _buffer = (unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
  16.   } 
  17.   //第四步:關(guān)閉文件句柄 
  18.    close(fd); 
  19.  
  20. //第五步:操作mmap內(nèi)存讀寫 
  21. void write(....) { 
  22.   // 將要寫入的數(shù)據(jù)封裝,壓縮和加密 
  23.   data_zlib_compress(); 
  24.  
  25.   //將mmap的緩存寫入到文件中 
  26.   fwrite(_buffer, sizeof(char), _buffer.length, dest_file); 
  27.   fflush(dest_file); 
  28.  
  29.   // 文件大小變化等相關(guān)操作 
  30.   update(); 

日志寫入的流程

1.2.3. 移動日志系統(tǒng)架構(gòu)介紹

客戶端日志SDK為開發(fā)者提供日志的打印,主要是將在線上運行期間產(chǎn)生的日志寫入文件中,根據(jù)開發(fā)者的需要撈取指定的日志,為開發(fā)者解決線上問題提供助力。我們設(shè)計了滿足基本功能的系統(tǒng),架構(gòu)如下圖所示:

1.2.4. 客戶端日志SDK介紹

日志SDK的架構(gòu)如圖展示,可以分為如下三層,每一層解決了不同的業(yè)務(wù)場景。

日志SDK在底層使用了流式壓縮加密操作,在接收到寫入的日志數(shù)據(jù),先將數(shù)據(jù)進行壓縮操作,然后再進行加密操作,整個過程中都是流式操作,避免了CPU峰值,減少對CPU性能負擔(dān)。在具體的實現(xiàn)中引入了MMAP機制解決了日志丟失問題,使用AES進行日志加密確保日志安全性。

日志SDK通過服務(wù)端下發(fā)的策略進行本地日志的動態(tài)上報,這里我們可以通過定時的拉取最新的策略,或者通過push通道更新本地的策略,再或者提供上報接口,在用戶的反饋中,讓用戶將日志數(shù)據(jù)上報上來。當前在下發(fā)的策略中我們進行了大量的自定義,對文件的大小,緩存時長,日志的寫入等級等相關(guān)的設(shè)置進行下發(fā)操作,實現(xiàn)應(yīng)用初始化后,篩選過濾,只將我們需要的日志寫入到文件中,為開發(fā)者使用。

日志SDK根據(jù)策略將指定的日志文件上傳到指定的服務(wù)器上,這個服務(wù)器將對上傳的日志進行解壓和解碼操作,將日志文件還原成原始的輸入數(shù)據(jù),具體的流程可以參考下面的業(yè)務(wù)流程。

日志SDK業(yè)務(wù)流程

日志SDK在的業(yè)務(wù)流程如下圖所示,根據(jù)服務(wù)端配置的策略,采集指定的日志并進行數(shù)據(jù)的壓縮加密等操作,然后主動將本地日志文件上傳到中轉(zhuǎn)服務(wù),將上傳結(jié)果等相關(guān)信息同步到信息展示的服務(wù)端。

日志SDK性能

上述設(shè)計中以及使用中,為了減少對CPU以及內(nèi)存的消耗,我們通過使用mmap技術(shù),將流式壓縮加密緩存等操作轉(zhuǎn)移到native層,那么這樣做相對于Java層的日志庫我們對于內(nèi)存以及CPU的使用率降低了多少,接下來我們將使用一個Java層的日志庫與使用mmap實現(xiàn)的native庫進行對比。

測試條件

性能測試中采用了在同一臺小米Note3 Android 9系統(tǒng)版本手機,分別測試了已有的Java日志庫、當前日志庫、美團Logan、騰訊XLog日志庫的寫入性能。通過寫入速度、GC頻率、CPU占用率幾個維度來衡量日志庫的寫入性能,測試的結(jié)果只限于衡量當前測試環(huán)境,并不代表Android平臺整體平均水準。

測試數(shù)據(jù)量:

測試結(jié)果

1. 內(nèi)存的GC測試結(jié)果

Java日志庫:

native日志庫:

從上邊的內(nèi)存性能圖片中可以看到,Java日志庫在大量寫日志的時候回造成頻繁的GC,雖然native日志庫不會出現(xiàn)這樣頻繁的GC,從圖中可以看到Java日志庫的GC頻率大約是1s/次,native日志庫的GC頻率大約是7.5s/次。

2. CPU使用率測試結(jié)果

Java日志庫:

native日志庫:

從上邊CPU性能圖片中可以看到,Java日志庫在頻繁寫入日志的時候CPU的平均使用率大約為13%,native日志庫在頻繁寫入日志的時候CPU的平均使用率大約為5%。

從上述內(nèi)存以及CPU占用率的對比中,我們可以看出native日志庫相較于Java日志庫來說,性能上有了很大的提示,對于內(nèi)存的占用較小,在頻繁的I/O操作以及加密壓縮操作的情況下cpu的使用率仍保持在較低值。

日志庫性能的對比

上邊我們與Java日志進行了對比,接下來我們將于其他使用mmap實現(xiàn)的日志庫進行下對比:

 

1.3. 實踐案例

在app的線上環(huán)境我們可能遇到各種問題,我們希望將出現(xiàn)問題當天的日志獲取到用于問題的分析,協(xié)助解決問題。這樣的業(yè)務(wù)場景幾乎覆蓋了大部分的業(yè)務(wù)場景,對于自助收銀機這樣的設(shè)備使用場景,運行時期的日志對于問題的排查尤為重要。

數(shù)科自助收銀設(shè)備主要服務(wù)于各大超市賣場的自如結(jié)賬,緩解多條人工收銀通道仍無法抵消的收銀壓力。當出現(xiàn)問題的時候,我們不可能對使用者進行回訪,所以運行時候的日志對于問題排查尤為重要。

在未使用移動日志系統(tǒng)之前,遇到問題后,由于缺少運營工具,對于問題的排查,需要占用較多的研發(fā)資源,在接入移動日志系統(tǒng)后,運營就可以獨自處理大部分的問題。這樣極大的提高了解決問題的效率,減少了研發(fā)側(cè)參與排查運營問題的時間。

1.4. 寫到最后

當前的sdk使用場景是定時拉取服務(wù)端的策略,根據(jù)下發(fā)的最新策略進行日志文件的上報,有一定的時間延后性,后期我們將開放主動上報日志的通道以及結(jié)合push推送消息,提高日志回撈的及時性以及成功率。

當前的sdk暫時只支持移動端(Android以及iOS),在后續(xù)我們將進行多端支持,將在RN,F(xiàn)lutter,小程序以及H5等各種應(yīng)用場景中統(tǒng)一使用當前日志庫進行日志的采集和存儲。

責(zé)任編輯:未麗燕 來源: 京東零售云
相關(guān)推薦

2021-09-15 16:41:20

京東零售云Flutter熱重載

2021-09-16 18:44:05

京東云PaaS平臺Android

2022-06-28 13:41:43

京東數(shù)據(jù)處理

2019-03-21 19:19:35

新零售阿里云零售云

2022-05-18 13:24:47

京東調(diào)優(yōu)實踐

2024-07-11 08:09:21

2018-01-22 10:33:01

云計算 新零售

2023-01-30 15:22:31

2021-09-08 18:12:57

京東零售云

2016-10-19 18:31:13

云存儲

2018-06-06 17:39:03

2023-05-11 08:00:30

2018-03-20 09:56:50

新零售

2017-09-30 10:00:41

2019-07-17 05:33:33

零售物聯(lián)網(wǎng)IOT

2024-05-31 09:00:07

2021-08-13 11:38:51

京東零售云智能出行
點贊
收藏

51CTO技術(shù)棧公眾號