徐志祥,李春秋,曹冰冰,牛小剛
(大連理工大學(xué) 機(jī)械工程學(xué)院,遼寧 大連 116024)
大型電機(jī)是能源、國(guó)防、采掘等行業(yè)關(guān)鍵裝備的驅(qū)動(dòng)部件,其安全運(yùn)行不僅事關(guān)電機(jī)本身的安全,更關(guān)乎整個(gè)生產(chǎn)鏈的安全。因此,如何提高大型電機(jī)的安全性和可靠性,及時(shí)準(zhǔn)確地發(fā)現(xiàn)電機(jī)故障或診斷出潛在故障,保障關(guān)鍵裝備安全運(yùn)行,一直受到廣泛的關(guān)注和重視。物聯(lián)網(wǎng)和云計(jì)算技術(shù)的出現(xiàn),為大型電機(jī)的在線狀態(tài)監(jiān)測(cè)提供了全新的技術(shù)手段。利用物聯(lián)網(wǎng)技術(shù),通過將電機(jī)的運(yùn)行狀態(tài)數(shù)據(jù)發(fā)送到云服務(wù)器,檢測(cè)人員能夠通過遠(yuǎn)程終端如手機(jī)APP或電腦網(wǎng)頁(yè)查看電機(jī)的運(yùn)行狀態(tài),從而極大地提高電機(jī)狀態(tài)監(jiān)測(cè)的實(shí)時(shí)性,便于相關(guān)人員及時(shí)處置出現(xiàn)的問題,延長(zhǎng)電機(jī)的使用壽命,降低生產(chǎn)鏈風(fēng)險(xiǎn)。
在基于物聯(lián)網(wǎng)的大型電機(jī)遠(yuǎn)程監(jiān)測(cè)系統(tǒng)中,需要采集大量電機(jī)參數(shù)上傳到云端,在云服務(wù)器中對(duì)這些數(shù)據(jù)進(jìn)行存儲(chǔ)、轉(zhuǎn)發(fā)和計(jì)算,給云服務(wù)器系統(tǒng)造成了很大負(fù)擔(dān)。本文針對(duì)這一問題創(chuàng)新性地設(shè)計(jì)了云服務(wù)器上的數(shù)據(jù)庫(kù)通信接口以及數(shù)據(jù)接收和發(fā)送接口。針對(duì)傳統(tǒng)模式中使用Socket連接和HTTP協(xié)議實(shí)現(xiàn)數(shù)據(jù)接收和發(fā)送時(shí)造成的云服務(wù)器系統(tǒng)CPU與內(nèi)存資源浪費(fèi),將數(shù)據(jù)接收與發(fā)送接口的性能進(jìn)行了優(yōu)化,降低了云服務(wù)器系統(tǒng)資源的消耗。
本文使用PyMySQL庫(kù)進(jìn)行與MySQL數(shù)據(jù)庫(kù)通信模塊的編寫。使用Tornado庫(kù)中的TCPServer與協(xié)程方式編寫數(shù)據(jù)接收接口,基于WebSocket協(xié)議使用Tornado庫(kù)中的WebSocketHandler實(shí)現(xiàn)用戶終端的數(shù)據(jù)發(fā)送。相比傳統(tǒng)模式,在相同條件下此舉能夠大幅降低云服務(wù)器的CPU資源消耗和內(nèi)存占用,使物聯(lián)網(wǎng)大型電機(jī)監(jiān)測(cè)系統(tǒng)中云服務(wù)器的性能得到提升[1-3]。
在大型電機(jī)遠(yuǎn)程監(jiān)測(cè)系統(tǒng)中,云服務(wù)器需要接收硬件采集設(shè)備得到的數(shù)據(jù),將其存儲(chǔ)在數(shù)據(jù)庫(kù)中,并在需要時(shí)將數(shù)據(jù)庫(kù)中的指定數(shù)據(jù)發(fā)送到遠(yuǎn)程終端,供檢測(cè)人員查看,其整體功能框架如圖1所示。為實(shí)現(xiàn)以上功能,本文基于Python編程語言,按照模塊化的編程思想,針對(duì)數(shù)據(jù)庫(kù)通信模塊、數(shù)據(jù)接收接口和數(shù)據(jù)發(fā)送接口進(jìn)行設(shè)計(jì),搭建了可用的大型電機(jī)遠(yuǎn)程監(jiān)測(cè)云服務(wù)器[4]。
圖1 云服務(wù)器整體框架
在云服務(wù)器中,無論是電機(jī)監(jiān)測(cè)數(shù)據(jù)的接收還是發(fā)送,都需要與數(shù)據(jù)庫(kù)通信。本文所設(shè)計(jì)的云服務(wù)器使用開源的MySQL數(shù)據(jù)庫(kù),并通過Python的PyMySQL擴(kuò)展庫(kù)實(shí)現(xiàn)數(shù)據(jù)的寫入和讀取[5]。
MySQL是關(guān)系型數(shù)據(jù)庫(kù),數(shù)據(jù)按照“database-tablecolumn”的形式存儲(chǔ)。對(duì)于電機(jī)而言,主要的監(jiān)測(cè)參數(shù)可以分為電氣參數(shù)、環(huán)境參數(shù)和狀態(tài)參數(shù)。為每種參數(shù)分別創(chuàng)建單獨(dú)的表,并統(tǒng)一放在名為“motor”的數(shù)據(jù)庫(kù)中。
每個(gè)表都包含id、create_time和value。id對(duì)應(yīng)每條數(shù)據(jù)的唯一索引;create_time表示數(shù)據(jù)上傳的時(shí)間;value表示數(shù)據(jù)的值。表的結(jié)構(gòu)見表1所列。
表1 數(shù)據(jù)庫(kù)中表的結(jié)構(gòu)
對(duì)數(shù)據(jù)庫(kù)進(jìn)行的操作主要可分為兩類:寫入和讀取。在MySQL中,數(shù)據(jù)的寫入通過“插入(INSERT)”語句實(shí)現(xiàn),讀取通過“查詢(SELECT)”語句實(shí)現(xiàn)。
數(shù)據(jù)庫(kù)讀寫邏輯如圖2所示。當(dāng)接收到硬件采集的數(shù)據(jù)時(shí),首先為每一個(gè)參數(shù)生成對(duì)應(yīng)的數(shù)據(jù)庫(kù)表名,再按照表中的結(jié)構(gòu)將數(shù)據(jù)格式化,然后通過PyMySQL庫(kù)創(chuàng)建與數(shù)據(jù)庫(kù)的連接,借助INSERT語句將數(shù)據(jù)寫入數(shù)據(jù)庫(kù),最后關(guān)閉與數(shù)據(jù)庫(kù)的連接。當(dāng)收到用戶端發(fā)送的請(qǐng)求時(shí),首先從請(qǐng)求中解析出數(shù)據(jù)所在的表,然后創(chuàng)建與數(shù)據(jù)庫(kù)的連接,通過SELECT語句查詢數(shù)據(jù),隨后關(guān)閉與數(shù)據(jù)庫(kù)的連接,最后將讀取的數(shù)據(jù)返回用戶端。
圖2 數(shù)據(jù)庫(kù)讀寫邏輯
數(shù)據(jù)接收接口是和硬件采集端對(duì)接的重要部分,它有2個(gè)任務(wù):接收電機(jī)監(jiān)測(cè)數(shù)據(jù)和將數(shù)據(jù)寫入數(shù)據(jù)庫(kù)。
為了接收硬件采集的數(shù)據(jù),云服務(wù)器需要與硬件端的控制器建立網(wǎng)絡(luò)通信。基于TCP/IP協(xié)議建立Socket連接是一種可靠的方法。但使用普通的Socket連接在面臨大量數(shù)據(jù)傳入的場(chǎng)景時(shí),需要通過多線程來提高并發(fā)能力,線程之間的頻繁調(diào)度將消耗大量系統(tǒng)資源[6-7]。
Python支持“協(xié)程”機(jī)制,與多線程類似,它也支持非阻塞異步并發(fā)操作。協(xié)程的工作方式如圖3所示,當(dāng)一組數(shù)量大的數(shù)據(jù)到來時(shí),由程序?qū)⑵浞殖扇舾蓴?shù)據(jù)片,每個(gè)數(shù)據(jù)片使用一個(gè)協(xié)程處理,所有協(xié)程可以運(yùn)行在同一個(gè)線程中。使用協(xié)程節(jié)省了線程調(diào)度的開銷,因此工作效率高而消耗低。
圖3 協(xié)程的工作方式
Tornado庫(kù)是Python的Web服務(wù)器擴(kuò)展庫(kù),它提供了方便的調(diào)用協(xié)程的方式:通過gen.coroutine裝飾器裝飾包含yield表達(dá)式的異步生成器,此時(shí)handle_stream函數(shù)就是一個(gè)協(xié)程。handle_stream函數(shù)定義在繼承了TCP Server的子類中,通過TCP Server端口可以等待硬件端發(fā)起連接。
數(shù)據(jù)接收接口的關(guān)鍵代碼如下所示:
read_l是上傳數(shù)據(jù)的前4個(gè)字節(jié),包含數(shù)據(jù)長(zhǎng)度信息,也可作為安全驗(yàn)證。根據(jù)數(shù)據(jù)長(zhǎng)度讀取上傳字節(jié)流中的所有數(shù)據(jù),并以字典形式存儲(chǔ)于data_dict中,完成數(shù)據(jù)接收操作。
根據(jù)模塊化編程思想將數(shù)據(jù)庫(kù)的寫入與讀取功能封裝在函數(shù)中,并保存為Python文件,在需要時(shí)可以直接調(diào)用。into_db.insert_data函數(shù)就是封裝好的數(shù)據(jù)庫(kù)寫入函數(shù),將data_dict作為參數(shù)傳入就可以實(shí)現(xiàn)數(shù)據(jù)寫入功能。
為方便測(cè)試人員實(shí)時(shí)查看數(shù)據(jù),需要將數(shù)據(jù)顯示在手機(jī)或個(gè)人電腦上。這就要求云服務(wù)器能夠?qū)?shù)據(jù)發(fā)送至遠(yuǎn)程終端。數(shù)據(jù)發(fā)送接口主要有2個(gè)任務(wù):從數(shù)據(jù)庫(kù)讀取出電機(jī)的數(shù)據(jù)并發(fā)送給指定用戶。
在電腦端,比較常用的數(shù)據(jù)顯示方式是通過瀏覽器獲取Web網(wǎng)頁(yè)。在手機(jī)端,隨著微信的廣泛應(yīng)用,微信小程序是一種便捷、可靠的選擇。Web網(wǎng)頁(yè)和微信小程序都可以使用WebSocket協(xié)議通信。WebSocket是一種建立在TCP上的全雙工長(zhǎng)連接應(yīng)用層協(xié)議,相比傳統(tǒng)的HTTP協(xié)議,建立了一次連接即可保持長(zhǎng)久的雙向傳輸機(jī)制,減少了不必要的請(qǐng)求頭部信息的發(fā)送,所以內(nèi)存占用較小,能夠顯著降低系統(tǒng)負(fù)擔(dān)。
基于WebSocket協(xié)議的數(shù)據(jù)發(fā)送接口同樣通過Tornado庫(kù)實(shí)現(xiàn),關(guān)鍵代碼如下所示:
EchoWebSocket是 一 個(gè) 繼 承 了Tornado中WebsocketHandler類的子類,定義on_message方法,在方法中傳入的參數(shù)message即用戶端發(fā)送的請(qǐng)求數(shù)據(jù),約定包含用戶信息以及所請(qǐng)求的參數(shù)類型。將用戶請(qǐng)求發(fā)送到JSON字符串轉(zhuǎn)換成字典的形式并傳遞給封裝好的MySQL數(shù)據(jù)庫(kù)讀取函數(shù),再將取出的數(shù)據(jù)通過write_message方法以JSON字符串的形式返回給用戶端。在主函數(shù)中將EchoWebSocket類傳給Application方法,再通過IOLoop.current().start()方法監(jiān)聽指定端口,等待用戶發(fā)起請(qǐng)求。
為驗(yàn)證所設(shè)計(jì)云服務(wù)器數(shù)據(jù)接口功能的實(shí)用性,使用阿里云服務(wù)器在CentOS7系統(tǒng)上搭建服務(wù)器系統(tǒng),并與硬件采集端、電腦網(wǎng)頁(yè)端和手機(jī)端聯(lián)合測(cè)試。
圖4所示為Web瀏覽器端對(duì)于電機(jī)前端軸承振動(dòng)圖像的顯示結(jié)果。圖5所示為微信小程序端的顯示界面。
圖4 Web網(wǎng)頁(yè)端數(shù)據(jù)顯示
圖5 微信小程序數(shù)據(jù)顯示
為測(cè)試數(shù)據(jù)接收接口的性能,分別使用傳統(tǒng)的Socket方式和Tornado協(xié)程方式編寫數(shù)據(jù)接收接口,通過20個(gè)測(cè)試用戶端同時(shí)上傳數(shù)據(jù),每個(gè)用戶傳入相同的數(shù)據(jù),對(duì)比2種設(shè)計(jì)模式下操作系統(tǒng)的CPU占用率、內(nèi)存使用率以及數(shù)據(jù)寫入操作完成時(shí)間,在多次測(cè)試后取平均值,得到的數(shù)據(jù)接口性能對(duì)比結(jié)果見表2所列。
表2 兩種數(shù)據(jù)接收接口性能對(duì)比
為測(cè)試數(shù)據(jù)發(fā)送接口的性能,分別基于HTTP協(xié)議和WebSocket協(xié)議編寫數(shù)據(jù)發(fā)送接口,使用20個(gè)測(cè)試用戶端,每個(gè)用戶同時(shí)請(qǐng)求相同數(shù)據(jù),對(duì)比2種設(shè)計(jì)模式下操作系統(tǒng)的CPU占用率、內(nèi)存使用率以及數(shù)據(jù)讀取操作完成時(shí)間,在多次測(cè)試后取平均值,得到的對(duì)比結(jié)果見表3所列。
表3 兩種數(shù)據(jù)發(fā)送接口性能對(duì)比
通過對(duì)比可以看出,在相同條件下,使用Tornado協(xié)程方式與Socket方式相比,內(nèi)存使用率以及完成時(shí)間幾乎相同,但Socket方式下的CPU占用率為37.3%,Tornado協(xié)程方式下的CPU占用率為27.3%,只使用Socket方式的CPU占用率為73.2%。而使用WebSocket協(xié)議與HTTP協(xié)議相比,兩者的CPU占用率與完成時(shí)間幾乎相同,但HTTP方式的內(nèi)存使用率為4.1%,WebSocket方式的內(nèi)存使用率為3.5%,只使用HTTP方式的內(nèi)存使用率為85.4%。所以通過Tornado協(xié)程方式的數(shù)據(jù)接收模塊和基于WebSocket協(xié)議的數(shù)據(jù)發(fā)送模塊能夠大幅提高系統(tǒng)性能。
本文使用Python編程語言設(shè)計(jì)了大型電機(jī)監(jiān)測(cè)系統(tǒng)中云服務(wù)器的數(shù)據(jù)庫(kù)通信接口、數(shù)據(jù)接收接口和數(shù)據(jù)發(fā)送接口。針對(duì)云服務(wù)器處理大量測(cè)量數(shù)據(jù)時(shí)系統(tǒng)負(fù)擔(dān)加劇的問題,將數(shù)據(jù)接收接口和數(shù)據(jù)發(fā)送接口進(jìn)行性能優(yōu)化,降低云服務(wù)器的系統(tǒng)資源消耗。
(1)基于協(xié)程方式,通過Tornado庫(kù)中的TCPServer方法對(duì)數(shù)據(jù)接收模塊的性能進(jìn)行優(yōu)化。相比Socket多線程方法,在相同條件下能夠?qū)PU占用率降低為之前的73.2%。
(2)基于WebSocket協(xié)議,通過Tornado庫(kù)中的WebSocketHandler方法對(duì)數(shù)據(jù)發(fā)送模塊的性能進(jìn)行優(yōu)化,相比基于HTTP協(xié)議的方法,在相同條件下能夠?qū)?nèi)存占用率降低為之前的85.4%。