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