溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

APP是如何高效保存日志

發(fā)布時(shí)間:2021-12-22 15:15:28 來源:億速云 閱讀:374 作者:柒染 欄目:互聯(lián)網(wǎng)科技

今天就跟大家聊聊有關(guān)APP是如何高效保存日志,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

有過嵌入式開發(fā)經(jīng)驗(yàn)的都知道日志的存儲(chǔ)是個(gè)比較麻煩的問題。之前ARM開源了一款項(xiàng)目:cmbacktrace,github地址就不貼了,可以將crash時(shí)的堆棧信息進(jìn)行保存。但是對于手機(jī)app來說,光保存程序崩潰時(shí)的日志信息時(shí)遠(yuǎn)遠(yuǎn)不夠的,根本無法定位到具體原因。在講解淘系使用的日志系統(tǒng)之前,先看一下最通用的日志系統(tǒng)。

通用方案一

主流的日志模塊比如logback,是屬于實(shí)時(shí)日志記錄系統(tǒng),也就是每產(chǎn)生一句日志就進(jìn)行加密存入磁盤文件。這樣有個(gè)缺點(diǎn)就是I/O過于密集占用大量CPU資源,影響程序性能,極易卡頓。一般使用與app開發(fā)調(diào)試階段,正式發(fā)版肯定要把log功能關(guān)閉,等用戶產(chǎn)生程序崩潰等反應(yīng)問題時(shí),才重新打一個(gè)調(diào)試包進(jìn)行復(fù)現(xiàn)。但是很多時(shí)候場景不完全相同,很難復(fù)現(xiàn)問題。

前文有講過cache數(shù)據(jù)與磁盤數(shù)據(jù)之間的關(guān)系:進(jìn)程是如何使用內(nèi)存的?

APP是如何高效保存日志

程序?qū)懳募僮鞯臅r(shí)候,并不是直接操作磁盤里的文件,而是先把數(shù)據(jù)寫入系統(tǒng)緩存,也就是臟頁中,然后操作系統(tǒng)的守護(hù)進(jìn)程update進(jìn)程會(huì)定時(shí)(一般為30s)將臟頁更新到磁盤里。數(shù)據(jù)寫入磁盤存在兩次拷貝:從用戶空間內(nèi)存拷貝到內(nèi)核空間內(nèi)存,然后從內(nèi)核空間flush寫入到磁盤。加上具體寫入磁盤的操作無法由程序控制,因此這里會(huì)造成CPU峰值過高導(dǎo)致性能降低。

通用方案二

直接使用Android的logsdk當(dāng)然方便,但是會(huì)造成性能問題,那么我們可以先將日志保存到內(nèi)存緩存,達(dá)到一定大小后再加密寫入文件。同時(shí)為了減少數(shù)據(jù)流,先對數(shù)據(jù)進(jìn)行壓縮再寫入(借鑒HTTP網(wǎng)絡(luò)傳輸?shù)淖龇ǎ?。整體方案如下圖:

APP是如何高效保存日志

這種方案不需要實(shí)時(shí)保存日志,不會(huì)產(chǎn)生CPU峰值。但是丟日志的問題仍然沒解決。比如程序crash異常退出時(shí),很多場景并不會(huì)有系統(tǒng)事件通知,也就無法保存crash時(shí)的堆棧。鵝廠的嵌入式操作系統(tǒng)Tencenttiny OS宣稱在stm32系列單板上解決了這個(gè)問題,但是使用起來仍然差強(qiáng)人意。更為重要的是,Android系統(tǒng)比嵌入式系統(tǒng)復(fù)雜的多,很多方案無法直接套用。

手淘優(yōu)化方案

手淘app主要從兩個(gè)方面來提高日志使用效率。

mmap

通過調(diào)用mmap存儲(chǔ)映射I/O,具體方案就是將磁盤文件映射到用戶空間緩沖區(qū)上,對內(nèi)存緩沖區(qū)執(zhí)行數(shù)據(jù)操作時(shí),相當(dāng)于操作磁盤中的文件。這樣的好處就是不需要使用read和write。映射方案如下圖所示。

APP是如何高效保存日志

使用mmap的好處是免去一次實(shí)時(shí)數(shù)據(jù)拷貝,同時(shí)可以通過調(diào)用msync、munmap將數(shù)據(jù)臟頁寫回磁盤文件,對于應(yīng)用層可控(起一個(gè)后臺(tái)線程異步執(zhí)行就行)。優(yōu)化后具體效果可以參看APUE圖14-28。

這里要注意,intmadvise(caddr_t addr, size_t len, int advice);這個(gè)接口在Unix說明是可以通過使用madv_willneed參數(shù)來預(yù)加載磁盤文件到內(nèi)存,但是在mac上實(shí)驗(yàn)并沒什么效果,因此妥善的方案是對每個(gè)頁執(zhí)行讀取一個(gè)字節(jié)的操作,這樣保證文件加載到內(nèi)存中。

數(shù)據(jù)壓縮

數(shù)據(jù)是先加密還是先壓縮?標(biāo)準(zhǔn)做法是先壓縮再加密。明文一般都有冗余度,壓縮之后內(nèi)容會(huì)變少。相反如果先加密,會(huì)破壞文件的冗余度。通用的壓縮方法主要有g(shù)zip、huffman等,手淘借鑒HTTP2的hpack頭部壓縮,在facebook開源的zstd壓縮算法基礎(chǔ)上進(jìn)行了網(wǎng)絡(luò)傳輸?shù)膬?yōu)化。因?yàn)槿罩局型ǔ?huì)有大量相同特性的短語,因此會(huì)在服務(wù)端常駐一個(gè)字典,并且適時(shí)更新由客戶端拉取,通過字典壓縮提升壓縮率。同時(shí)為了防止數(shù)據(jù)損壞影響整個(gè)壓縮包無法解壓,采用流式壓縮(即日志達(dá)到32k時(shí)進(jìn)行壓縮)。分塊壓縮雖然總體效率略低,但是因?yàn)椴粫?huì)在短時(shí)間內(nèi)幾種打包壓縮,不會(huì)造成CPU峰值。

實(shí)際使用過程中還對外置SD卡進(jìn)行了適配,當(dāng)SD卡被刪除時(shí)會(huì)將日志存入臨時(shí)緩存,每次進(jìn)程被殺掉時(shí)清理緩存,防止長時(shí)間占用用戶空間造成輿情。

看完上述內(nèi)容,你們對APP是如何高效保存日志有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

app
AI