攜程酒店統(tǒng)一云手機平臺探索與實踐
作者簡介
酒店無線效能研發(fā)組,負(fù)責(zé)酒店無線團隊基礎(chǔ)能力平臺的研發(fā),比如Cloud Touch平臺(云端手機),內(nèi)容運營平臺,自動化測試流程等,通過對日常規(guī)律性事務(wù)的抽象總結(jié)提供解決方案,提高平臺所承載業(yè)務(wù)的整體效能。
一、背景
攜程內(nèi)部會有大量的部門或團隊需要在App新版本、新站點完成研發(fā)階段所有功能測試后,在上架前(Post Release)階段,再進行無拘束的從客人視角驗收的訴求(比如競品對比、Localization體驗等)。對于已經(jīng)上架的版本,我們的客服人員在客人協(xié)助、新員工培訓(xùn)等場合,也有著使用生產(chǎn)資源來獲得與客人同一視角的環(huán)境訴求,這對我們研發(fā)流程中已經(jīng)存在的測試環(huán)境的適用性提出了巨大的挑戰(zhàn),無論從操作體驗、還是資源對齊等多方面,測試環(huán)境都難以滿足訴求。
- 例如為滿足Trip.com的新站點上線前的海外駐地驗收訴求,需支持新站點的新功能提前向定向人群釋放的能力。
- 例如為滿足客服在對客協(xié)助時,能充分理解客人的進線問題,需支持員工和客人的視角保持一致的App操作平臺。
二、全場景建設(shè)
我們綜合評估了相似訴求以及平臺能力可能的輻射面后,下圖呈現(xiàn)了我們對系統(tǒng)(下文統(tǒng)一命名Cloud Touch)的適用人群的預(yù)期:
以駐地驗收場景為例:基于Cloud Touch平臺,可統(tǒng)一收口驗收人員的設(shè)備管理,通過云平臺提供統(tǒng)一的遠(yuǎn)程操作入口。這樣不論我們的員工在世界任何駐地,都可以方便的使用中心化維護的設(shè)備,同時新站點的RC包將在Cloud Touch上提前上架,完成待驗收版本的部署。
以客服協(xié)助場景為例:基于客服工作臺給員工提供統(tǒng)一的進入Cloud Touch的入口,可供員工在與客人的對話中了解客人的對應(yīng)App版本,能快捷的在設(shè)備池中選擇相關(guān)預(yù)置好的實機進行場景鑒定工作。
(以上示意圖)
三、基于Cloud Touch的技術(shù)解決方案
3.1 核心平臺設(shè)計
基于以上分析,平臺需要解決的是覆蓋不同應(yīng)用場景的設(shè)備資源的分配管理問題,實現(xiàn)不同地域請求的中心化分發(fā)問題,提供本地設(shè)備的遠(yuǎn)程操控以及畫面的實時同步問題,以達(dá)到類似于遠(yuǎn)程桌面的交互體驗。并且可基于平臺化的收口能力為不同業(yè)務(wù)場景提供統(tǒng)一的預(yù)置參數(shù)和環(huán)境的配置,使各項工作的標(biāo)準(zhǔn)化能進一步得到提升。
3.2 設(shè)備分池設(shè)計
我們有大量的客服員工座席,同時也有研發(fā)線的測試驗收人員,設(shè)備池的足夠大是硬件條件,但是如何有效的利用這些設(shè)備,協(xié)調(diào)好不同應(yīng)用場景的人和設(shè)備的關(guān)系,這還需要一套滿足核心場景的分配策略設(shè)計,主要的核心流程如下:
3.3 遠(yuǎn)程設(shè)備操控設(shè)計與實現(xiàn)
實現(xiàn)了平臺化和設(shè)備的統(tǒng)一分發(fā)工作后,那么技術(shù)的核心在于如何選型并實現(xiàn)一套端到端的遠(yuǎn)程控制方案。
因為不同系統(tǒng)的對接技術(shù)不同,此處我們以iOS的實現(xiàn)為例,WebDriverAgent是Facebook 在17年的 SeleniumConf 大會上推出的一款新的iOS移動測試框架(WDA),WebDriverAgent 在 iOS 端實現(xiàn)了一個 WebDriver Server 能夠?qū)崿F(xiàn)與瀏覽器進行交互,它的實現(xiàn)使用了經(jīng)典的Server-Client架構(gòu)(C/S),客戶端發(fā)送一個Requset,服務(wù)器端返回一個Response,借助這個 Server 我們可以遠(yuǎn)程控制 iOS 設(shè)備。
WDAClient:基于WebDriverAgent實現(xiàn)的WDA的客戶端。facebook-wda 就是 WDA 的 Python 客戶端庫,通過直接構(gòu)造HTTP請求直接跟WebDriverAgent通信。
WDAServer:運行WDA App的機器,實現(xiàn)了WebDriver的通訊協(xié)議。
Session:服務(wù)器端需要維護客戶端的Session,客戶端首次發(fā)送請求的字符串是'/session/sessionId/url′。服務(wù)器端根據(jù)url打開對應(yīng)的url地址,同時將sessionId解析成真實的值,然后返回給客戶端。以后客戶端再向瀏覽器發(fā)送請求時,會攜帶session值一起發(fā)送。
WebElement:WebDriverAPI中的對象,代表頁面上的一個DOM元素。
JsonWireProtocol:是通過使用webdriver與remote server進行通信的 web service 協(xié)議 。通過http請求,完成和remote server的交互。
Mobile JSON Wire Protocol Specification:移動端自動化協(xié)議。
(此處引用了WDA官方的部分基礎(chǔ)技術(shù)說明,如您感興趣可以再進一步參考github上的facebook archive項目)
3.3.1 指令集適配
Client端可以接收多種不同類型的指令以完成不同的動作,主要包括以下幾種:
(1)基本指令通信格式(iOS/Android格式公用,處理略有不同,以下用iOS舉例):
{
"serial":"00008030-000D48A40291802E", // IOS設(shè)備udid
"type":"M_TOUCH", // 命令類型枚舉值
"message":{
"action":0, // 鼠標(biāo)或鍵盤 0按下 1松開
"keycodeType":"ascii", // 代表鍵盤事件輸入的是ascii碼
"keyCode":60, // 鍵盤按下了哪個鍵 非ascii時響應(yīng)對應(yīng)系統(tǒng)鍵
"position":{
"x":687, // 鼠標(biāo)點擊事件x像素坐標(biāo)
"y":1116, // 鼠標(biāo)點擊事件y像素坐標(biāo)
}
}
}
(2)基本指令:鼠標(biāo)事件(點擊/滑動操作)
- 前端頁面根據(jù)設(shè)備上報的分辨率和用戶在畫面上操作的位置,計算鼠標(biāo)的像素位置x,y并組裝鼠標(biāo)事件命令
- Client收到actinotallow=0命令時(即按下鼠標(biāo)時),記錄鼠標(biāo)按下的坐標(biāo)和命令的時間
- Client收到actinotallow=1命令時(即松開鼠標(biāo)時),記錄鼠標(biāo)松開的坐標(biāo)和命令的時間。
- Client根據(jù)設(shè)備的scale(IOS設(shè)備像素和uiKit的縮放比)將命令下發(fā)的像素坐標(biāo)轉(zhuǎn)換為ui操作坐標(biāo),獲得命令的起點和終點。將按下和松手的時間差值作為命令的執(zhí)行時間,組裝WDA命令。
- 請求WDA的url為:/wda/swipe,根據(jù)起點、終點、命令執(zhí)行時間、命令觸發(fā)頻率的不同可產(chǎn)生點擊、長按、雙擊、滑動的效果
(3)基本指令:按鍵事件
- 前端記錄用戶按下的按鍵并轉(zhuǎn)換為ascii碼,組裝鍵盤輸入事件,長時間按壓會連續(xù)產(chǎn)生的命令;用戶在頁面上點擊的系統(tǒng)按鍵(電源、主頁、菜單鍵)也會被轉(zhuǎn)換為鍵盤輸入事件
- Client收到actinotallow=0時,若收到ascii碼的字符,則觸發(fā)字符輸入事件;若收到系統(tǒng)按鍵,則組裝對應(yīng)的命令完成操作
- 字符輸入事件: /wda/keys接口默認(rèn)有同步快照機制,會消耗大量時間確保輸入按照順序進行,平均響應(yīng)時間1字符/秒。云手機對時效的要求更高,所以將WDA快照機制刪除,并在Client中使用隊列,將短時間內(nèi)的多個字符合并成1個字符串,調(diào)用1次/wda/keys即可完成多個字符的輸入,做到輸入實時響應(yīng)
- 電源鍵:請求/wda/locked獲取當(dāng)前鎖屏狀態(tài)后,調(diào)用/wda/lock或者/wda/unlock進行鎖屏與解鎖
- 主頁鍵:請求/wda/home回到主頁
- 菜單鍵(APP選擇頁):WDA未提供對應(yīng)接口,通過組裝上劃命令請求/wda/dragfromtoforduration,模擬上劃進入菜單頁。注:這里不能使用/wda/swipe,沒有效果
- Client收到actinotallow=1時,代表用戶已經(jīng)松手,不做響應(yīng)
(4)復(fù)雜腳本指令
- 在上方提到的基本的操作之外,Client還可以接受更多命令入?yún)⒉⒅С謫酒餟I自動化腳本,自動化腳本將會完成更加復(fù)雜的指令,從而實現(xiàn)智能化控制與使用
- 接收啟動app類型、用戶賬號密碼,頁面deeplink等,喚起app完成用戶登錄后直接跳轉(zhuǎn)進入對應(yīng)頁面
- 接收app下載地址、版本號等,實現(xiàn)app的卸載與安裝并處理彈窗等信息
3.4 遠(yuǎn)程畫面同步的設(shè)計與實現(xiàn)
關(guān)于畫面的同步,先拋一下大家熟知的ffmpeg,這是一個開源的跨平臺音視頻處理工具,它可以用于錄制、轉(zhuǎn)換和流媒體處理等多種音視頻操作。我們通過抓幀操作,數(shù)據(jù)通過ffmpeg進行處理后依次進行h.264轉(zhuǎn)碼,并將編碼信息推給到web端直播服務(wù),當(dāng)前30s的視頻約 30M,h.264轉(zhuǎn)碼后只有 3MB,畫面流目前設(shè)置為1秒20幀。
3.4.1 畫面抓取
iOS設(shè)備畫面抓取流程:
(1)WDA mjpegServer
WDA自帶mjpegServer,mjpegServer會不斷地調(diào)用截屏API,并將截屏數(shù)據(jù)壓縮后組裝成mjpeg的數(shù)據(jù)流格式發(fā)送到畫面流的端口。
(2)截屏速度/壓縮質(zhì)量參數(shù)
WDA mjpegServer可以通過參數(shù)對截圖的速度,截圖后的壓縮質(zhì)量進行設(shè)置。根據(jù)服務(wù)器性能和使用場景對FBMjpegServerScreenshotQuality和FBMjpegServerFramerate進行調(diào)整以得到最好效果。
人眼對幀數(shù)的感知在24幀左右,所以我們將FBMjpegServerFramerate設(shè)置為24,用戶在使用時就不會感受到卡頓(幀率的選擇在3.4.2第四小節(jié)講述)
static NSUInteger FBMjpegScalingFactor = 100; // 截圖縮放比,默認(rèn)100,一般不做修改
static NSUInteger FBMjpegServerScreenshotQuality = 25; // 截圖壓縮質(zhì)量,范圍1-100,默認(rèn)25。值越大圖片質(zhì)量越好。
static NSUInteger FBMjpegServerFramerate = 24; // 截圖輸出速度,即幀率,默認(rèn)10
(3)Client畫面獲取
用戶開始使用時,會產(chǎn)生畫面初始化命令發(fā)送給Client。
Client通過GET請求畫面流的端口,便可以得到連續(xù)的mjpeg畫面流。
得到的畫面流數(shù)據(jù)格式是以--BoundaryString分隔開的一張張mjpeg圖片,每一張圖片都可以單獨作為jpeg圖片保存下來。
3.4.2 流媒體處理
iOS畫面流轉(zhuǎn)視頻流流程:
上文提到的Client端可以通過GET請求畫面流端口得到一張張的jpeg圖片,mjpeg是幀內(nèi)編碼,數(shù)據(jù)非常大。如果直接將該畫面流數(shù)據(jù)推送給服務(wù)器,對使用方的帶寬要求會非常高,所以要轉(zhuǎn)成h.264的幀間編碼方式。
(1)Client請求畫面流端口并逐幀抓取圖片
通過ffmpeg請求畫面流端口,通過解碼器抓取每一張jpeg圖片。
(2)h.264編碼
將抓取到的每一張jpeg圖片都交給ffmpeg的編碼器,設(shè)置參數(shù)并進行h.264編碼并輸出到標(biāo)準(zhǔn)輸出。
補充:解碼器和編碼器的幀率設(shè)置需要略大于WDA設(shè)置的截屏速度,這樣才能保證畫面的響應(yīng)一直是實時的。
(3)推流至流服務(wù)器
我們使用了平臺研發(fā)中心框架架構(gòu)研發(fā)部多媒體組提供的流服務(wù)器。通過引入框架團隊提供的JAR包,便可方便將數(shù)據(jù)推流至服務(wù)器上。
ffmpeg編碼器標(biāo)準(zhǔn)輸出的每一幀,都會用設(shè)備在平臺上的主鍵作為唯一標(biāo)識標(biāo)記發(fā)送給流服務(wù)器。
公司的流服務(wù)器在接收到數(shù)據(jù)后,會根據(jù)唯一標(biāo)識生成類似于直播間的播放地址。前端訪問該地址便可以看到手機的畫面。
(4)推流碼率
我們需要選取合適的幀率和碼率,以達(dá)到視頻流暢度和清晰度上的平衡:
以碼率上限設(shè)定為4.5mbps為例,用戶端所需要的網(wǎng)絡(luò)速度峰值550KB/s左右。
所需帶寬(KB/s) ≈ 推流碼率最大值(bps)/8/1024。
因為實際上用戶的操作速度,并不會非???,對于帶寬的占用會更少,一般操作引起的畫面變動所需帶寬在150-200KB/s左右,而靜止?fàn)顟B(tài)下所需帶寬僅在5-40KB/s
綜合各個方面,我們是以WDA截屏速度為24的基礎(chǔ)上適當(dāng)加入了關(guān)鍵幀,將Client推流幀率定在30幀/s,碼率上限設(shè)定為4.5mbps,實測占用帶寬350KB/s左右,畫面顯示流暢、清晰、無花屏。
而我們使用的WIFI下載速度最高值在7.5MB/s左右,因此推流碼率和帶寬不是瓶頸。瓶頸主要在于ffmpeg將圖片流轉(zhuǎn)換為視頻流的效率。通過計算,Client端java單線程ffmpeg的轉(zhuǎn)碼效率在每秒40幀左右,這可以通過技術(shù)優(yōu)化得到提高。
四、數(shù)據(jù)采集
作為一套相關(guān)工種的員工將賴以推進日常工作的基礎(chǔ)平臺來講,其穩(wěn)定性必須是全維度可檢測的,不僅需要支持對系統(tǒng)日常運行的健康進行監(jiān)控,同時也要支持采集足夠的運行數(shù)據(jù),提供給平臺研發(fā)人員分析并推進后續(xù)的迭代工作。
平臺穩(wěn)定性:通過各種監(jiān)測維度數(shù)據(jù)及日志,提升用戶感知穩(wěn)定性;
使用檢測量:用于評估用戶依賴平臺工作的量,后期平臺迭代對用戶影響度;
五、實踐總結(jié)
在面向自動化測試領(lǐng)域,包括攜程在內(nèi),其實有很多的UI自動化測試方案所采用的技術(shù)與此相似,甚至使用的技術(shù)底座都是相同的,比如WDA框架就是Facebook 推出的一項新的iOS移動測試框架。
無獨有偶,我們團隊在最初實現(xiàn)一些技術(shù)功能后,也是首先重點推廣于測試場景。但是攜程的業(yè)務(wù)面非常寬廣,我們不僅有開發(fā)測試場景,還有內(nèi)容核驗場景,尤其是我們的國際化走在前列,有大量的海外員工也要一起參與到非常多的驗收環(huán)節(jié)。
那么像應(yīng)用版本,參數(shù)配置,環(huán)境初始化,資源準(zhǔn)備這些環(huán)節(jié)在不同國別的同事間同步或培訓(xùn),是相當(dāng)耗費人力和成本的,且效果并不佳。基于我們對技術(shù)和平臺的深度分析和演進后才發(fā)現(xiàn),其實技術(shù)的應(yīng)用空間很廣,使一項基礎(chǔ)的技術(shù)平臺化起來后,很容易將場景、人員、設(shè)備、配置都統(tǒng)合在一起,很多交流成本可以直接降低,驗收設(shè)備的不充分利用問題也得到很好的解決,尤其是共性問題的發(fā)現(xiàn)和解決變得高效。
在我們后續(xù)的工作中,還將基于當(dāng)前的一些體驗進行以下幾個方面的持續(xù)優(yōu)化:
- 模擬器場景支持并發(fā)安裝包
- 單設(shè)備的多場景復(fù)用
最終使平臺的體驗完全可替代實機操作,讓我們的潛在用戶切身感受到上平臺比自己在手機上做各項工作更加便利與高效。