OPENSTF 平臺(tái)網(wǎng)絡(luò)流量?jī)?yōu)化方案詳解

背景

openstf是一款優(yōu)秀的手機(jī)集群管理平臺(tái),功能強(qiáng)大、性能優(yōu)秀、擴(kuò)展性很高,可以大幅度提高手機(jī)的使用效率,使用nodejs和angularjs開發(fā),遵循apache licene2.0開源協(xié)議,用戶可以對(duì)源碼進(jìn)行修改發(fā)布。(源碼地址:https://github.com/openstf)

使用openstf平臺(tái)可以方便的對(duì)手機(jī)進(jìn)行遠(yuǎn)程管理、調(diào)試、遠(yuǎn)程手機(jī)桌面監(jiān)控等操作,但是這一切都建立在平臺(tái)的網(wǎng)絡(luò)帶寬環(huán)境非常好的情況下,stf對(duì)網(wǎng)絡(luò)帶寬環(huán)境要求非常高。為什么存在這種情況,看下圖:

在本地搭建一臺(tái)stf平臺(tái)服務(wù)器,用戶從另一臺(tái)PC訪問stf平臺(tái)對(duì)手機(jī)進(jìn)行管理。stf 服務(wù)器端通過流量監(jiān)控軟件發(fā)現(xiàn)單個(gè)訪問的上行流量達(dá)到3.22MB/s,最高可以到達(dá)5MB/s以上。實(shí)際上的帶寬占用達(dá)到5*8=40Mbps,通常情況下平臺(tái)上不可能只有一個(gè)用戶,按照10個(gè)用戶同時(shí)使用stf服務(wù)的情況下帶寬要求達(dá)到400Mbps(stf服務(wù)的帶寬和普通web服務(wù)不一樣,stf服務(wù)的帶寬是持續(xù)占用的,后續(xù)說明)。對(duì)于局域網(wǎng)用戶來說這個(gè)帶寬要求勉強(qiáng)達(dá)到,但是對(duì)于把stf服務(wù)發(fā)布到公網(wǎng)提供給外部用戶使用這種情況帶寬成本就太高了,現(xiàn)在電信機(jī)房的20M上行帶寬成本為每年10萬左右。在局域網(wǎng)中同時(shí)支撐20個(gè)以上的用戶同時(shí)訪問時(shí)局域網(wǎng)帶寬要求也非常高,不可能為了搭建一個(gè)服務(wù)改造局域網(wǎng)。為了兼顧用戶體驗(yàn)和帶寬成本只能從優(yōu)化stf的數(shù)據(jù)傳輸量上找方法了。

問題分析

已經(jīng)知道 stf服務(wù)對(duì)帶寬占用很高,現(xiàn)在需要找到為什么會(huì)占用如此高的帶寬,在分析帶寬的時(shí)候肯定要用到抓包工具。使用chrome自帶的devtool工具對(duì)stf服務(wù)進(jìn)行抓包,發(fā)現(xiàn)stf 的web端會(huì)不停的從瀏覽器緩存中讀取圖片格式的文件。

對(duì)這些圖片格式的文件分析后發(fā)現(xiàn)這些圖片就是被管理的手機(jī)的屏幕截圖


再查看抓包結(jié)果發(fā)現(xiàn)有個(gè)websocket的長(zhǎng)連接一直在從后端推送二進(jìn)制文件文件到web端,初步推斷剛才圖片格式文件就是這個(gè)websocket連接推送到前端的,前端收到二進(jìn)制數(shù)據(jù)后轉(zhuǎn)換成圖片格式文件,再把圖片展示到web界面上。


為了證明以上推斷,關(guān)閉手機(jī)端的屏幕,這時(shí)候發(fā)現(xiàn)websocket 完全停止傳輸數(shù)據(jù)了,監(jiān)控流量發(fā)現(xiàn)流量基本上為0KB/s。


現(xiàn)在可以斷定就是這個(gè)websocket服務(wù)為了把手機(jī)端的屏幕截圖實(shí)時(shí)傳輸給web端從而占用了大量的網(wǎng)絡(luò)帶寬。這也說明了為什么在stf平臺(tái)操作手機(jī)時(shí)網(wǎng)絡(luò)帶寬是持續(xù)占用而不是像普通web服務(wù)那樣有請(qǐng)求才占用帶寬。

?????? 要減少websocket 的流量需要從源頭優(yōu)化,減少所傳輸文件的數(shù)據(jù)量,這里是一方面需要減小原始手機(jī)屏幕截圖的文件大小,另一方面減少文件傳輸?shù)膫€(gè)數(shù)。如何減少文件大小,有兩個(gè)思路:降低圖片質(zhì)量或者降低圖片分辨率。如何減少文件個(gè)數(shù):這里只能降低圖片傳輸?shù)膸瑪?shù)。解決思路已經(jīng)確定了,接下來就要分析代碼、分析數(shù)據(jù)流從而優(yōu)化代碼流程達(dá)到效果。

工作原理

前面分析到web端的手機(jī)屏幕同步來自于對(duì)手機(jī)屏幕端的同步截圖,那么stf截圖并發(fā)送給web端就可能存在三種方案:

1.? ? 手機(jī)端截圖后傳給stf服務(wù)端,stf服務(wù)端再傳給stf web端

2.? ? stf平臺(tái)直接截圖后傳給stf web端

3.? ? 手機(jī)端截圖后直接傳給stf web端

通過抓包發(fā)現(xiàn)與stf web端通訊的websoket的服務(wù)地址是 stf服務(wù)器的而不是手機(jī)的,同時(shí)考慮到手機(jī)直接傳數(shù)據(jù)給stf web端對(duì)手機(jī)網(wǎng)絡(luò)環(huán)境的限制(手機(jī)和stf 用戶需要在同一網(wǎng)絡(luò)這會(huì)嚴(yán)重限制平臺(tái)使用環(huán)境)的要求,這就排除了第三種可能性。接下來就是查資料讀代碼了,通過官網(wǎng)資料得知,stf使用了minicap這個(gè)截圖工具。minicap?是一款開源的anroid截屏工具,minicap使用c++開發(fā)工作在android ndk層,通過實(shí)時(shí)抓取手機(jī)的顯示緩存的數(shù)據(jù)生成二進(jìn)制的圖片文件信息,因此截圖效率極高(android手機(jī)屏幕刷新頻率有多快minicap截圖頻率就有多快),這保證了stf在同步android手機(jī)的屏幕時(shí)高質(zhì)量、高幀數(shù),同時(shí)也導(dǎo)致了很高的帶寬占用。這樣就確定了stf同步手機(jī)屏幕用的是方案一。

針對(duì)方案1的優(yōu)化方案有兩種:

A.? ? ? 修改minicap源碼,在android端生成圖片數(shù)據(jù)時(shí)就降低圖片的大小

B.? ? ? 在minicap把截圖傳給stf服務(wù)端后,在stf服務(wù)端降低圖片大小后再傳給web端

在對(duì)minicap的源碼進(jìn)行研究后就放棄了方案A,minicap源碼工程大,邏輯太復(fù)雜,同時(shí)修改后還要考慮到不同手機(jī)的兼容性問題,總之就是工作量大、太復(fù)雜。相對(duì)的方案B可行性就高很多,只需對(duì)stf服務(wù)端代碼進(jìn)行修改而不用考慮各種手機(jī)的兼容性,而且stf服務(wù)端使用的nodejs腳本開發(fā)難度小很多。

確定了在stf服務(wù)端對(duì)圖片大小進(jìn)行降低后再傳給web端這種方式接下來需要找到stf端接收minicap數(shù)據(jù)的邏輯了。在對(duì)stf工作流程和代碼進(jìn)行研究后,在plugins/streen/stream.j下找到了stf接收minicap數(shù)據(jù)的邏輯。

具體邏輯如下:


在手機(jī)連接到stf平臺(tái)后,stf?會(huì)加載stream.js,stream.js會(huì)建立一個(gè)websocket的服務(wù)(這個(gè)服務(wù)是提供給web端的),在建立websocket服務(wù)的時(shí)候會(huì)啟動(dòng)一個(gè)websocket的監(jiān)聽者,同時(shí)啟動(dòng)一個(gè)minicap的實(shí)例,stf web端連接websocket服務(wù)后會(huì)啟動(dòng)一個(gè)websocket會(huì)話,websocket監(jiān)聽者監(jiān)聽到有屏幕同步信息時(shí)就會(huì)給minicap的實(shí)例發(fā)消息,minicap接收消息后開始截屏,在minicap實(shí)例截屏后直接通過websocket會(huì)話發(fā)送給你stf web端,這樣stf web端就可以獲取到手機(jī)的截圖了。工作流程圖如下:


?????? 由上面的流程圖可以看出FrameProducer類是對(duì)minicap的原始數(shù)據(jù)進(jìn)行處理的,stream.js上有這段代碼


通過查閱官方代碼發(fā)現(xiàn)這里的-Q參數(shù)可以調(diào)整minicap抓取的圖片質(zhì)量


再看下這個(gè)- Q參數(shù)的默認(rèn)值,在stream.js 的啟動(dòng)函數(shù)找到了,如果沒有人為設(shè)置這里的默認(rèn)值是80,也就是說原始圖片質(zhì)量的80%

.option('screen-jpeg-quality', {

describe: 'The JPG quality touse for the screen.'

, type: 'number'

, default: process.env.SCREEN_JPEG_QUALITY || 80

})

在使用stf管理手機(jī)的時(shí)候我們主要是操作手機(jī),對(duì)手機(jī)的顯示效果并不關(guān)注,因此完全可以把顯示質(zhì)量降低到可用范圍從而減少流量,直接把圖片質(zhì)量降低到50%

通過實(shí)際使用發(fā)現(xiàn)stf web 端50%的顯示質(zhì)量完全可以接受,參考下對(duì)比圖:左邊圖片質(zhì)量為80%,右邊圖片質(zhì)量為50%

再看下這時(shí)候的實(shí)際網(wǎng)絡(luò)帶寬占用對(duì)比:左邊圖片質(zhì)量為80%,右邊圖片質(zhì)量為50%

流量從3.22MB/s降低到了692KB/s,效果很明顯了,但是692KB/s相對(duì)來說還是不夠理想。如果再降低圖片質(zhì)量就不太合適,只能通過降低圖片數(shù)量來繼續(xù)降低總的流量了。繼續(xù)研究stream.js 最終找到了減少傳輸幀數(shù)的方法:在websocket的ws會(huì)話發(fā)送圖片二進(jìn)制數(shù)據(jù)到web端時(shí)丟棄1/3的數(shù)據(jù),修改方式如下

降低幀數(shù)前后的對(duì)比效果

降低幀數(shù)后的前后流量對(duì)比

通過降低幀數(shù)數(shù)據(jù)流量從692KB/s降低到了468KB/s,實(shí)際使用中降低幀數(shù)后的體驗(yàn)并沒有相差很遠(yuǎn),因?yàn)楣ぷ髟赑C 端的瀏覽器上17幀的刷新屏幕也是夠流暢了。

總結(jié)

下圖是整個(gè)優(yōu)化過程中帶寬占用的變化:未優(yōu)化、只優(yōu)化圖片質(zhì)量、優(yōu)化圖片質(zhì)量和幀數(shù)

?????? 帶寬占用最終降低了10倍左右,整個(gè)優(yōu)化過程中代碼修改很少,修改的地方也非常簡(jiǎn)單。但是如果不對(duì)整個(gè)stf工具的前后端流程和代碼進(jìn)行研究,不了解底層相關(guān)的工作原理還是很難下手的。通過對(duì)前端的抓包后端的數(shù)據(jù)流分析,最終在修改了很少源碼情況下起到了立竿見影的效果,節(jié)省了10倍的帶寬。

展望

從3MB/s到400KB/s的帶寬占用這個(gè)效果是挺明顯的,但是實(shí)際上400KB/s的帶寬占用還是不夠優(yōu)秀。上面的優(yōu)化方案已經(jīng)把stf平臺(tái)前端顯示質(zhì)量和刷新頻率降低到了剛好可用的狀態(tài),現(xiàn)在如果還要繼續(xù)降低帶寬占用肯定不能繼續(xù)用這種方法了,有沒有其他方案?在繼續(xù)研究流量?jī)?yōu)化方案時(shí),數(shù)據(jù)流媒體方案展示出來。能否做到在保證用戶體驗(yàn)的情況下把3.2MB/s的帶寬占用降低30倍達(dá)到100KB/s左右?答案是肯定的。下一篇文章“基于流媒體技術(shù)的stf平臺(tái)流量?jī)?yōu)化方案”。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容