高齊琦,江 婷,田世隆,林嘉琦
(中電海康集團(tuán)有限公司,杭州 312000)
隨著大數(shù)據(jù)時(shí)代的到來,存儲(chǔ)行業(yè)也面臨著新的機(jī)遇和挑戰(zhàn).高效、真實(shí)且實(shí)時(shí)的存儲(chǔ)設(shè)備可視化,不僅有利于此類設(shè)備的設(shè)計(jì),也能為后續(xù)的運(yùn)營(yíng)和維護(hù)提供幫助.傳統(tǒng)磁盤陣列 (Redundant Array of Independent Disk; RAID) 的可視化設(shè)計(jì),只是通過表格羅列信息或是前視圖、后視圖的方式來實(shí)現(xiàn),無法在空間位置上展示盤陣的細(xì)節(jié),操作難以上手,且管理界面單調(diào)、互動(dòng)性差,影響信息傳遞和操作效率,降低決策和響應(yīng)速度.
WebGL (Web Graphical Library) 的誕生使得瀏覽器不需要任何插件即可呈現(xiàn)豐富的3D圖形,并且提供更友好的交互功能[1],例如實(shí)時(shí)動(dòng)畫播放[2]、機(jī)房可視化[3]等工作.然而,在磁盤陣列的3D可視化問題上,目前國(guó)內(nèi)極少涉及.
針對(duì)以上問題,本文提出基于WebGL第三方庫(kù)three.js 3D磁盤陣列可視化的設(shè)計(jì)和實(shí)現(xiàn)框架,同時(shí)針對(duì)three.js API對(duì)復(fù)雜形態(tài)可視化的不足,還提出了預(yù)繪制模型,并以O(shè)BJ形式導(dǎo)入的策略.最后,在可視化3D磁盤基礎(chǔ)上,增加了豐富且實(shí)用的交互功能,為磁盤陣列可視化表達(dá)提供了一種新的方法和途徑.
本文按如下內(nèi)容展開,在第2節(jié)將簡(jiǎn)要介紹WebGL與three.js庫(kù); 第3節(jié)介紹系統(tǒng)框架和頁面的主要功能; 在第4節(jié)提出基于three.js的3D磁盤陣列可視化設(shè)計(jì),討論簡(jiǎn)單和復(fù)雜組件的模型建立和導(dǎo)入方法; 在第5節(jié)介紹客戶端的交互功能; 最后進(jìn)行總結(jié)并對(duì)后續(xù)工作做出展望.
WebGL是一種跨平臺(tái)、免費(fèi)的3D繪圖協(xié)議,是HTML5規(guī)范的組成之一,通過HTML5 Canvas元素對(duì)外暴露DOM (Document Object Model) 編程接口[2].基于OpenGL ES 2.0標(biāo)準(zhǔn),WebGL通過增加對(duì)OpenGL ES 2.0的JavaScript綁定,為HTML5 Canvas提供基于硬件的3D加速渲染,使得瀏覽器無需第三方插件,就可以借助系統(tǒng)顯卡在瀏覽器里呈現(xiàn)高性能3D圖形.
雖然WebGL API (Application Programming Interface)的出現(xiàn)使得前端開發(fā)者可以直接在頁面中繪制3D圖形,但是WebGL提供的是低級(jí)別的、光柵化的API,直接編程會(huì)面臨復(fù)雜且易出錯(cuò)的問題.為了構(gòu)建一個(gè)高等級(jí)的、對(duì)前端開發(fā)者更加友好的WebGL開發(fā)環(huán)境,許多開源JavaScript庫(kù)被創(chuàng)造出來,其中three.js的應(yīng)用最廣泛,它不僅提供了簡(jiǎn)單易懂的JavaScript API,并且集輕量級(jí)、開源免費(fèi)等優(yōu)秀品質(zhì)于一身[4,5].因此,本文選用three.js作為基本的開發(fā)工具庫(kù).
前端頁面基于Vue.js構(gòu)建MVVM (Model-View-ViewModel) 模式的漸進(jìn)式框架,如圖1所示,即采用自底向上增量開發(fā)設(shè)計(jì),核心庫(kù)只關(guān)注圖層,拓展了HTML功能[6].
本文實(shí)驗(yàn)系統(tǒng)使用restful架構(gòu),這是一種針對(duì)網(wǎng)絡(luò)應(yīng)用開發(fā)的架構(gòu),具有簡(jiǎn)潔靈活高效的優(yōu)點(diǎn).應(yīng)用此架構(gòu),前端頁面不再需要數(shù)據(jù)表去保存資源,所有的資源均通過restful API從服務(wù)器端獲取,保證前后端分離,系統(tǒng)結(jié)構(gòu)簡(jiǎn)潔高效.
圖1 Vue.js MVVM架構(gòu)
本文實(shí)驗(yàn)系統(tǒng)采用SQLite數(shù)據(jù)庫(kù),這是一種輕型數(shù)據(jù)庫(kù),易于被集成到系統(tǒng)中,且具有簡(jiǎn)潔、開源等優(yōu)秀性能.SQLite數(shù)據(jù)庫(kù)在系統(tǒng)中用于組織、存儲(chǔ)和管理數(shù)據(jù),從而保證數(shù)據(jù)的可靠性.
從硬件層直接獲取不同類型子組件的信息在數(shù)據(jù)結(jié)構(gòu)上難以保持一致,本文實(shí)驗(yàn)系統(tǒng)在實(shí)際盤陣硬件形態(tài)之上封裝了設(shè)備管理層,用于實(shí)際盤陣硬件形態(tài)數(shù)據(jù)的統(tǒng)一管理,包括設(shè)置參數(shù)和獲取信息等功能.
本文研究的3D磁盤陣列可視化,以單獨(dú)頁面的形式集成在系統(tǒng)的客戶端中,通過客戶端與服務(wù)端進(jìn)行通信,為用戶提供豐富的交互功能.
本文提出的3D磁盤陣列可視化系統(tǒng)的框架如圖2所示,系統(tǒng)采用B/S結(jié)構(gòu)設(shè)計(jì),分為服務(wù)端和客戶端兩大部分,服務(wù)器端負(fù)責(zé)數(shù)據(jù)的收集、保存和傳輸; 客戶端則呈現(xiàn)實(shí)時(shí)的3D磁盤陣列并實(shí)現(xiàn)信息展示和交互功能.
在服務(wù)端,采用Restful API+數(shù)據(jù)庫(kù)+設(shè)備管理層的分層架構(gòu)設(shè)計(jì),層次明確,易于理解.分層的架構(gòu)使得開發(fā)語言多樣化,便于多人協(xié)同開發(fā).
在客戶端,整個(gè)頁面采用Vue.js框架,其構(gòu)建的MVVM模式使模型與視圖的雙向改變變得簡(jiǎn)單易行.其中視圖部分,利用three.js的API對(duì)磁盤陣列進(jìn)行3D仿真建模,并添加豐富交互功能,呈現(xiàn)在瀏覽器頁面.客戶端與服務(wù)端又采用標(biāo)準(zhǔn)的HTTP協(xié)議進(jìn)行數(shù)據(jù)的傳輸,數(shù)據(jù)以JSON的格式進(jìn)行發(fā)送和接收.
本文實(shí)驗(yàn)基于3.1所述系統(tǒng)實(shí)現(xiàn),重點(diǎn)討論客戶端部分,3D磁盤陣列的可視化設(shè)計(jì)及實(shí)現(xiàn),即圖2中上虛線框中的內(nèi)容.主要功能包括如下兩點(diǎn).
圖2 系統(tǒng)總體框架
1) 對(duì)磁盤陣列進(jìn)行3D仿真建模,并根據(jù)實(shí)際盤陣硬件形態(tài)進(jìn)行資源映射.在本文實(shí)驗(yàn)系統(tǒng)設(shè)計(jì)中,將實(shí)際盤陣分解為若干子組件,如機(jī)箱外殼、磁盤、網(wǎng)口、電源、主板和風(fēng)扇等.對(duì)于規(guī)則子組件,根據(jù)實(shí)際盤陣的尺寸比例,使用three.js提供的API進(jìn)行繪制;對(duì)于復(fù)雜子組件,通過建模軟件創(chuàng)建OBJ模型,然后使用 three.js提供的API導(dǎo)入.判斷實(shí)際盤陣硬件形態(tài),加載對(duì)應(yīng)子組件模型,并按照對(duì)應(yīng)位置拼接到一起,實(shí)現(xiàn)3D仿真建模.
2) 在3D磁盤陣列頁面集成豐富的交互功能,包括3D場(chǎng)景漫游、子組件選中高亮、單擊獲取子組件信息、改變實(shí)際盤陣硬件形態(tài)等交互功能.
針對(duì)3D磁盤陣列的繪制,首先將其分解成多個(gè)子組件,并抽象為具有規(guī)則形態(tài)的幾何體,例如機(jī)箱外殼、磁盤、網(wǎng)口、電源和主板外形都可用立方體近似.通過測(cè)量實(shí)際盤陣的尺寸和位置參數(shù),采用JSON格式記錄所有的尺寸和位置參數(shù),便于繪制規(guī)范和后期維護(hù).記錄的數(shù)據(jù)形式如圖3所示,其中sizeX、sizeY和sizeZ分別對(duì)應(yīng)組件的長(zhǎng)、寬和高; posX、posY和posZ對(duì)應(yīng)組件的位置.
圖3 磁盤數(shù)據(jù)示例
除了子組件的尺寸和位置參數(shù),還需要記錄其外觀和光源反應(yīng)等信息,以獲取該組件的材質(zhì)屬性.本文采用的方法是拍攝實(shí)際盤陣圖片,對(duì)圖片進(jìn)行處理壓縮,形成JPG格式貼圖.
在計(jì)算機(jī)3D可視化中,物體形狀通常由三角形面組成,通常把多個(gè)三角形面形成的網(wǎng)格模型叫做Mesh模型[3,5].根據(jù)three.js的API接口設(shè)計(jì),所有繪制的子組件也以Mesh形式存在于頁面場(chǎng)景中,通過THREE.Mesh(geometry,material)來創(chuàng)建,其中需要的添加的參數(shù)geometry為Mesh對(duì)象的幾何結(jié)構(gòu),material為Mesh對(duì)象的材質(zhì).
Three.js提供多種創(chuàng)建幾何結(jié)構(gòu)的API,可繪制平面、球體、立方體等等,本文實(shí)驗(yàn)繪制的規(guī)則子組件都可抽象為立方體,API接口為THREE.BoxGeometry(sizeX,sizeY,sizeZ); three.js也提供多種創(chuàng)造材質(zhì)的API,本文實(shí)驗(yàn)中使用THREE.MeshPhongMaterial({map: new THREE.TextureLoader().load(url)})增加圖片材質(zhì),其中THREE.MeshPhongMaterial網(wǎng)格Phong式材料,這種材質(zhì)會(huì)考慮光照的影響,THREE.TextureLoader().load(url)函數(shù)從指定位置加載圖片文件,圖片格式可以為PNG、GIF或JPG.
圖4給出了單個(gè)硬盤子組件的Mesh樣例,其余子組件根據(jù)相同的方法繪制.
圖4 繪制單個(gè)磁盤
在3D磁盤陣列的繪制過程中,存在一些形態(tài)復(fù)雜,無法用基本幾何體表現(xiàn)的子組件,例如風(fēng)扇等.本文實(shí)驗(yàn)使用建模軟件創(chuàng)建OBJ模型如圖5所示.
圖5 風(fēng)扇OBJ模型示例
Three.js可以讀取多種三維文件格式,如JSON、OBJ和STL等,對(duì)應(yīng)的格式都要引入一個(gè)額外的JavaScript文件.如本文實(shí)驗(yàn)中使用的OBJ格式模型,需先在頁面中引入OBJLoader.js,然后通過THREE.OBJLoader().load(url,function)函數(shù)完成模型導(dǎo)入.該函數(shù)接收兩個(gè)參數(shù),其一是模型路徑url,另一個(gè)為導(dǎo)入完成后的回調(diào)函數(shù),在回調(diào)函數(shù)中可以設(shè)置模型的位置以及大小.
本節(jié)描述系統(tǒng)根據(jù)實(shí)際盤陣硬件形態(tài),繪制3D磁盤陣列的過程,即資源映射的過程.
首先由客戶端下發(fā)請(qǐng)求獲取實(shí)際盤陣硬件形態(tài)的命令,命令下發(fā)過程如圖2自上而下箭頭所示流程,調(diào)用Restful API后,在數(shù)據(jù)庫(kù)中找到對(duì)應(yīng)的表,然后下發(fā)到設(shè)備管理層獲取實(shí)際盤陣硬件形態(tài)信息; 將獲取的信息返回客戶端的過程如圖2自下而上箭頭所示流程.
在客戶端獲取到實(shí)際盤陣硬件形態(tài)信息后,根據(jù)所述信息,加載對(duì)應(yīng)子組件,并根據(jù)圖3中的posX、posY和posZ參數(shù)設(shè)定位置,將各部分子組件拼接到一起,如圖6所示,實(shí)現(xiàn)資源映射全過程.
由于磁盤數(shù)量較多,開啟定位燈能幫助用戶快速定位磁盤.在3D磁盤陣列中點(diǎn)擊選中一塊磁盤,點(diǎn)擊開啟磁盤燈按鈕,命令下發(fā)過程如圖2自上而下箭頭所示流程,調(diào)用Restful API后,下發(fā)至設(shè)備管理層改變實(shí)際盤陣硬件形態(tài),即點(diǎn)亮磁盤燈.磁盤燈被點(diǎn)亮后,向客戶端返回成功信息,過程如圖2自下而上箭頭所示流程.
圖6 3D磁盤陣列三視圖
為了給用戶提供良好的交互體驗(yàn),在提出的3D磁盤陣列可視化頁面添加交互功能,分別為3D場(chǎng)景漫游、子組件選中、單擊獲取子組件信息以及改變實(shí)際盤陣硬件形態(tài).
當(dāng)3D 磁盤陣列按照硬件形態(tài)被繪制完成后,為了全方位多角度的展示模型,添加3D場(chǎng)景漫游功能,此功能允許用戶在場(chǎng)景內(nèi)自由移動(dòng)視角.
本文實(shí)驗(yàn)使用three.js提供的OrbitControl.js(軌道控件),首先在頁面中引入OrbitControl.js,然后使用THREE.OrbitControls(camera)創(chuàng)建控件,并將它綁定到相機(jī)上,通過orbitcontrols.rotateSpeed、orbitcontrols.zoomSpeed等屬性可分別改變鼠標(biāo)控制相機(jī)的旋轉(zhuǎn)、縮放速度.
通過使用3D場(chǎng)景漫游技術(shù),可全方位多角度的觀察3D 磁盤陣列,如圖7(a)為主板子組件的俯視視圖,通過鼠標(biāo)滾輪滾動(dòng)即可實(shí)現(xiàn)放大縮小,如圖7(b)為主板放大細(xì)節(jié).
本節(jié)將介紹在頁面中選中單個(gè)子組件的交互設(shè)計(jì)中,如何解決不能進(jìn)行DOM操作和如何在同時(shí)擁有Mesh和OBJ的同一頁面進(jìn)行選擇的兩個(gè)技術(shù)難點(diǎn).
由于三維場(chǎng)景中不能進(jìn)行DOM操作,無法直接通過對(duì)每個(gè)子組件添加事件監(jiān)聽來實(shí)現(xiàn)交互操作,three.js中提出了一種射線發(fā)射的方式來判斷子組件是否被選中的方法[7].通過THREE.Raycaster.intersectObjects(obj-ects)方法,從屏幕上的點(diǎn)擊位置向場(chǎng)景中發(fā)射一條射線,在所有objects中第一個(gè)與射線相交的對(duì)象為被選中的子組件.
圖7 漫游功能示例
使用上述方法判斷選中子組件,只能檢測(cè)到Mesh格式對(duì)象,即4.1節(jié)所述的規(guī)則組件,而OBJ模型是多個(gè)Mesh形成的Group形式,無法被檢測(cè).為了實(shí)現(xiàn)OBJ模型的點(diǎn)選功能,將OBJ模型Children (Mesh格式)存入數(shù)組.遍歷其數(shù)組,如果OBJ模型任意Children被選中,則判斷該OBJ模型被選中.
在3D磁盤陣列中添加鼠標(biāo)移入子組件高亮的交互功能,無論是調(diào)用Three.js的API繪制的子組件電源,如圖8(a)所示,還是導(dǎo)入的OBJ模型風(fēng)扇,如圖8(b)所示,都可以在鼠標(biāo)移動(dòng)的過程中被選中.
在5.2的基礎(chǔ)上,將鼠標(biāo)移入移出的交互方式改為左鍵單擊,被單擊的子組件使用淺藍(lán)色遮罩區(qū)分移入選中,如圖9所示.鼠標(biāo)單擊動(dòng)作綁定獲取該子組件詳細(xì)信息事件,命令下發(fā)過程如圖2自上而下箭頭所示流程,調(diào)用Restful API后,下發(fā)至設(shè)備管理層獲取被點(diǎn)擊組件詳細(xì)信息,以JSON形式傳給客戶端.客戶端頁面使用Vue.js框架,將子組件與表單綁定,數(shù)據(jù)成功返回即頁面顯示其詳細(xì)信息,如圖10所示.
圖8 子組建選中示例
圖9 控制器B被選中
圖10 控制器B的詳細(xì)信息
客戶端接收到返回成功信息,通過THREE.Mesh BasicMaterial({color:0xff0000})創(chuàng)建紅色材質(zhì),改變3D模型中對(duì)應(yīng)磁盤定位燈的顏色,如圖11所示.
圖11 磁盤定位燈示例
本文針對(duì)于傳統(tǒng)磁盤陣列可視化的缺陷,對(duì)其進(jìn)行升級(jí),提出了基于Three.js的3D磁盤陣列可視化框架設(shè)計(jì)和實(shí)現(xiàn).針對(duì)簡(jiǎn)單和復(fù)雜形態(tài)的子組件,分別采用簡(jiǎn)單幾何體和OBJ模型的形式進(jìn)行建模,并根據(jù)實(shí)際盤陣的形態(tài)進(jìn)行資源映射.在圖形界面提供了3D場(chǎng)景漫游、子組件選擇、單擊獲取子組件信息和改變實(shí)際盤陣硬件形態(tài)等功能,為用戶提供良好的交互體驗(yàn).二者被有機(jī)結(jié)合并集成到系統(tǒng)軟件中,提升了系統(tǒng)的易用性.因此該研究是有理論意義且具有應(yīng)用價(jià)值的.