成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

京東零售云mPaaS移動端日志回?fù)铺剿鲗?shí)踐

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

1.1. 引言

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

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

1.2. 設(shè)計(jì)方案

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

1.2.1. 什么是mmap?

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

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

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

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

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

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

1.2.2. mmap的使用

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

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

mmap函數(shù)

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

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

  1. EACCES:訪問出錯
  2. EAGAIN:文件已被鎖定,或者太多的內(nèi)存已被鎖定
  3. EBADF:fd不是有效的文件描述詞
  4. EINVAL:一個或者多個參數(shù)無效
  5. ENFILE:已達(dá)到系統(tǒng)對打開文件的限制
  6. ENODEV:指定文件所在的文件系統(tǒng)不支持內(nèi)存映射
  7. ENOMEM:內(nèi)存不足,或者進(jìn)程已超出最大內(nèi)存映射數(shù)量
  8. EPERM:權(quán)能不足,操作不允許
  9. ETXTBSY:已寫的方式打開文件,同時(shí)指定MAP_DENYWRITE標(biāo)志
  10. SIGSEGV:試著向只讀區(qū)寫入
  11. SIGBUS:試著訪問不屬于進(jìn)程的內(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ā)者提供日志的打印,主要是將在線上運(yùn)行期間產(chǎn)生的日志寫入文件中,根據(jù)開發(fā)者的需要撈取指定的日志,為開發(fā)者解決線上問題提供助力。我們設(shè)計(jì)了滿足基本功能的系統(tǒng),架構(gòu)如下圖所示:

1.2.4. 客戶端日志SDK介紹

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

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

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

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

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

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

日志SDK性能

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

測試條件

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

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

測試結(jié)果

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

Java日志庫:

native日志庫:

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

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

Java日志庫:

native日志庫:

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

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

日志庫性能的對比

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

 

1.3. 實(shí)踐案例

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

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

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

1.4. 寫到最后

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

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

責(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)實(shí)踐

2024-07-11 08:09:21

2018-01-22 10:33:01

云計(jì)算 新零售

2023-01-30 15:22:31

2016-10-19 18:31:13

云存儲

2023-05-11 08:00:30

2018-03-20 09:56:50

新零售

2017-09-30 10:00:41

2021-09-08 18:12:57

京東零售云

2018-06-06 17:39:03

2024-05-31 09:00:07

2017-10-30 17:18:15

阿里云
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 一区二区在线免费观看 | 日韩国产一区二区三区 | 美女三区| 久久久久九九九女人毛片 | 91精品国产91久久久久久丝袜 | a级片在线 | 97国产一区二区精品久久呦 | 亚洲精品久久久9婷婷中文字幕 | 精品日韩一区二区三区av动图 | 欧美一区2区三区4区公司 | 日韩欧美精品一区 | av在线影院 | 日韩亚洲一区二区 | 狠狠综合网 | 精品国产一区二区三区久久久四川 | 影音先锋中文在线 | 超碰欧美 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 亚洲小视频在线播放 | 男人久久天堂 | 国产精品伦理一区 | www.国产| 三级黄色片在线观看 | 精品中文字幕一区二区三区 | 亚洲日本中文 | 中文字幕av网 | 欧美日韩免费一区二区三区 | 国产精品久久久久久久久久妇女 | 久久久涩 | 99精品视频一区二区三区 | 免费国产黄网站在线观看视频 | 精品一区二区三区91 | 羞羞视频在线网站观看 | 午夜在线 | 国产三级日本三级 | 久久一级免费视频 | 久久久久成人精品亚洲国产 | 日韩欧美中文字幕在线观看 | 欧美极品一区二区 | 国产成人综合一区二区三区 | 欧美乱大交xxxxx另类电影 |