????????頻繁的磁盤IO操作可能會給程序或者系統(tǒng)帶來意想不到的問題燥爷。工作中我們可能會碰到在壓縮或者寫大體積文件時(shí),另一個(gè)同學(xué)連接上終端后敲命令會很卡,這種現(xiàn)象非常明顯萎津。但如果程序中頻繁使用磁盤IO葱色,產(chǎn)生的問題就不一定能這么明顯的定位到了递宅。
背景
? ? ? ? 個(gè)人負(fù)責(zé)的一個(gè)組件其中有針對監(jiān)聽指定事件,并在獲取到事件時(shí)進(jìn)行截屏然后回傳服務(wù)端的需求苍狰。由于運(yùn)行環(huán)境特殊的原因恐锣,程序是以system角色跑在windows中,無法直接獲取當(dāng)前用戶的桌面信息舞痰,只能寫一個(gè)截屏程序土榴,并基于CreateProcessAsUser系統(tǒng)接口來調(diào)用,而此接口返回值只有一個(gè)error類型响牛,無法返回其他類型玷禽。
? ? ? ? 之前初始版本實(shí)現(xiàn)時(shí)是在調(diào)截屏程序時(shí)傳遞一個(gè)uuid,截屏程序生成截屏文件呀打,以uuid為文件名直接落盤矢赁,服務(wù)端在獲取接口返回后等待截屏文件落地后讀取截屏內(nèi)容后再發(fā)送出去,由于圖片寫入磁盤需要消耗一定時(shí)間贬丛,服務(wù)端只能等待一段時(shí)間后再判斷截屏文件是否生成撩银。
? ? ? ? 實(shí)際應(yīng)用后經(jīng)測試發(fā)現(xiàn),win2008豺憔、win7上多次觸發(fā)截屏额获,都能獲取完整渲染的圖像文件够庙,而win10中總有一定記錄生成的圖片顯示的不全,經(jīng)過多方排查后一直沒找到確切原因抄邀。
? ? ? ? 在一次優(yōu)化另一個(gè)模塊的磁盤io占用后耘眨,不經(jīng)意間發(fā)現(xiàn),新版本的程序在win10出現(xiàn)截屏不全的幾率已經(jīng)降低到1/15左右境肾,但偶爾還會出現(xiàn)剔难。那么這么一看,原因基本可以確定跟頻繁磁盤IO有關(guān)了(還有一方面因素奥喻,在相同資源配置下偶宫,win2008和win7系統(tǒng)的流暢度比win10要好的多)。截屏?xí)r要落盤环鲤,而獲取截屏數(shù)據(jù)時(shí)又要重新讀取纯趋,在事件產(chǎn)生的頻率高時(shí),因截屏產(chǎn)生的磁盤IO消耗就大了楔绞,極可能會出現(xiàn)圖片未生成完畢就被讀取的情況结闸。
? ? ? ? 那么驗(yàn)證思路就有了,盡量避免磁盤IO酒朵!經(jīng)過重新設(shè)計(jì)桦锄,新的實(shí)現(xiàn)方案是:服務(wù)端單獨(dú)啟動一個(gè)rpc server,用于單獨(dú)接收截屏程序上報(bào)的截屏數(shù)據(jù)請求蔫耽,然后正常下發(fā)截屏的調(diào)用结耀。截屏程序在收到指令后進(jìn)行截屏,截屏數(shù)據(jù)不寫入文件匙铡,而是申請一個(gè)buffer图甜,并直接寫入buffer,然后通過本地rpc調(diào)用服務(wù)端的方法回傳截屏數(shù)據(jù)鳖眼。服務(wù)端在啟動rpc server時(shí)單獨(dú)初始化一個(gè)帶過期的緩存黑毅,并用uuid為鍵存儲接收的截屏數(shù)據(jù)。下發(fā)截屏調(diào)用的模塊在發(fā)出截屏指令后直接去緩存中進(jìn)行查詢钦讳,查詢到后再根據(jù)業(yè)務(wù)邏輯需求發(fā)送出去矿瘦。
? ? ? ? ?新的截屏方案避免的截屏文件寫入磁盤及從磁盤讀取兩步IO操作,經(jīng)多次測試愿卒,win10環(huán)境下截屏渲染不全的現(xiàn)象未再出現(xiàn)缚去。
? ? ? ? 引用一個(gè)很經(jīng)典的對比圖