徐志祥,李春秋,曹冰冰,牛小剛
(大連理工大學 機械工程學院,遼寧 大連 116024)
大型電機是能源、國防、采掘等行業關鍵裝備的驅動部件,其安全運行不僅事關電機本身的安全,更關乎整個生產鏈的安全。因此,如何提高大型電機的安全性和可靠性,及時準確地發現電機故障或診斷出潛在故障,保障關鍵裝備安全運行,一直受到廣泛的關注和重視。物聯網和云計算技術的出現,為大型電機的在線狀態監測提供了全新的技術手段。利用物聯網技術,通過將電機的運行狀態數據發送到云服務器,檢測人員能夠通過遠程終端如手機APP或電腦網頁查看電機的運行狀態,從而極大地提高電機狀態監測的實時性,便于相關人員及時處置出現的問題,延長電機的使用壽命,降低生產鏈風險。
在基于物聯網的大型電機遠程監測系統中,需要采集大量電機參數上傳到云端,在云服務器中對這些數據進行存儲、轉發和計算,給云服務器系統造成了很大負擔。本文針對這一問題創新性地設計了云服務器上的數據庫通信接口以及數據接收和發送接口。針對傳統模式中使用Socket連接和HTTP協議實現數據接收和發送時造成的云服務器系統CPU與內存資源浪費,將數據接收與發送接口的性能進行了優化,降低了云服務器系統資源的消耗。
本文使用PyMySQL庫進行與MySQL數據庫通信模塊的編寫。使用Tornado庫中的TCPServer與協程方式編寫數據接收接口,基于WebSocket協議使用Tornado庫中的WebSocketHandler實現用戶終端的數據發送。相比傳統模式,在相同條件下此舉能夠大幅降低云服務器的CPU資源消耗和內存占用,使物聯網大型電機監測系統中云服務器的性能得到提升[1-3]。
在大型電機遠程監測系統中,云服務器需要接收硬件采集設備得到的數據,將其存儲在數據庫中,并在需要時將數據庫中的指定數據發送到遠程終端,供檢測人員查看,其整體功能框架如圖1所示。為實現以上功能,本文基于Python編程語言,按照模塊化的編程思想,針對數據庫通信模塊、數據接收接口和數據發送接口進行設計,搭建了可用的大型電機遠程監測云服務器[4]。

圖1 云服務器整體框架
在云服務器中,無論是電機監測數據的接收還是發送,都需要與數據庫通信。本文所設計的云服務器使用開源的MySQL數據庫,并通過Python的PyMySQL擴展庫實現數據的寫入和讀取[5]。
MySQL是關系型數據庫,數據按照“database-tablecolumn”的形式存儲。對于電機而言,主要的監測參數可以分為電氣參數、環境參數和狀態參數。為每種參數分別創建單獨的表,并統一放在名為“motor”的數據庫中。
每個表都包含id、create_time和value。id對應每條數據的唯一索引;create_time表示數據上傳的時間;value表示數據的值。表的結構見表1所列。

表1 數據庫中表的結構
對數據庫進行的操作主要可分為兩類:寫入和讀取。在MySQL中,數據的寫入通過“插入(INSERT)”語句實現,讀取通過“查詢(SELECT)”語句實現。
數據庫讀寫邏輯如圖2所示。當接收到硬件采集的數據時,首先為每一個參數生成對應的數據庫表名,再按照表中的結構將數據格式化,然后通過PyMySQL庫創建與數據庫的連接,借助INSERT語句將數據寫入數據庫,最后關閉與數據庫的連接。當收到用戶端發送的請求時,首先從請求中解析出數據所在的表,然后創建與數據庫的連接,通過SELECT語句查詢數據,隨后關閉與數據庫的連接,最后將讀取的數據返回用戶端。

圖2 數據庫讀寫邏輯
數據接收接口是和硬件采集端對接的重要部分,它有2個任務:接收電機監測數據和將數據寫入數據庫。
為了接收硬件采集的數據,云服務器需要與硬件端的控制器建立網絡通信?;赥CP/IP協議建立Socket連接是一種可靠的方法。但使用普通的Socket連接在面臨大量數據傳入的場景時,需要通過多線程來提高并發能力,線程之間的頻繁調度將消耗大量系統資源[6-7]。
Python支持“協程”機制,與多線程類似,它也支持非阻塞異步并發操作。協程的工作方式如圖3所示,當一組數量大的數據到來時,由程序將其分成若干數據片,每個數據片使用一個協程處理,所有協程可以運行在同一個線程中。使用協程節省了線程調度的開銷,因此工作效率高而消耗低。

圖3 協程的工作方式
Tornado庫是Python的Web服務器擴展庫,它提供了方便的調用協程的方式:通過gen.coroutine裝飾器裝飾包含yield表達式的異步生成器,此時handle_stream函數就是一個協程。handle_stream函數定義在繼承了TCP Server的子類中,通過TCP Server端口可以等待硬件端發起連接。
數據接收接口的關鍵代碼如下所示:

read_l是上傳數據的前4個字節,包含數據長度信息,也可作為安全驗證。根據數據長度讀取上傳字節流中的所有數據,并以字典形式存儲于data_dict中,完成數據接收操作。
根據模塊化編程思想將數據庫的寫入與讀取功能封裝在函數中,并保存為Python文件,在需要時可以直接調用。into_db.insert_data函數就是封裝好的數據庫寫入函數,將data_dict作為參數傳入就可以實現數據寫入功能。
為方便測試人員實時查看數據,需要將數據顯示在手機或個人電腦上。這就要求云服務器能夠將數據發送至遠程終端。數據發送接口主要有2個任務:從數據庫讀取出電機的數據并發送給指定用戶。
在電腦端,比較常用的數據顯示方式是通過瀏覽器獲取Web網頁。在手機端,隨著微信的廣泛應用,微信小程序是一種便捷、可靠的選擇。Web網頁和微信小程序都可以使用WebSocket協議通信。WebSocket是一種建立在TCP上的全雙工長連接應用層協議,相比傳統的HTTP協議,建立了一次連接即可保持長久的雙向傳輸機制,減少了不必要的請求頭部信息的發送,所以內存占用較小,能夠顯著降低系統負擔。
基于WebSocket協議的數據發送接口同樣通過Tornado庫實現,關鍵代碼如下所示:

EchoWebSocket是 一 個 繼 承 了Tornado中WebsocketHandler類的子類,定義on_message方法,在方法中傳入的參數message即用戶端發送的請求數據,約定包含用戶信息以及所請求的參數類型。將用戶請求發送到JSON字符串轉換成字典的形式并傳遞給封裝好的MySQL數據庫讀取函數,再將取出的數據通過write_message方法以JSON字符串的形式返回給用戶端。在主函數中將EchoWebSocket類傳給Application方法,再通過IOLoop.current().start()方法監聽指定端口,等待用戶發起請求。
為驗證所設計云服務器數據接口功能的實用性,使用阿里云服務器在CentOS7系統上搭建服務器系統,并與硬件采集端、電腦網頁端和手機端聯合測試。
圖4所示為Web瀏覽器端對于電機前端軸承振動圖像的顯示結果。圖5所示為微信小程序端的顯示界面。

圖4 Web網頁端數據顯示

圖5 微信小程序數據顯示
為測試數據接收接口的性能,分別使用傳統的Socket方式和Tornado協程方式編寫數據接收接口,通過20個測試用戶端同時上傳數據,每個用戶傳入相同的數據,對比2種設計模式下操作系統的CPU占用率、內存使用率以及數據寫入操作完成時間,在多次測試后取平均值,得到的數據接口性能對比結果見表2所列。

表2 兩種數據接收接口性能對比
為測試數據發送接口的性能,分別基于HTTP協議和WebSocket協議編寫數據發送接口,使用20個測試用戶端,每個用戶同時請求相同數據,對比2種設計模式下操作系統的CPU占用率、內存使用率以及數據讀取操作完成時間,在多次測試后取平均值,得到的對比結果見表3所列。

表3 兩種數據發送接口性能對比
通過對比可以看出,在相同條件下,使用Tornado協程方式與Socket方式相比,內存使用率以及完成時間幾乎相同,但Socket方式下的CPU占用率為37.3%,Tornado協程方式下的CPU占用率為27.3%,只使用Socket方式的CPU占用率為73.2%。而使用WebSocket協議與HTTP協議相比,兩者的CPU占用率與完成時間幾乎相同,但HTTP方式的內存使用率為4.1%,WebSocket方式的內存使用率為3.5%,只使用HTTP方式的內存使用率為85.4%。所以通過Tornado協程方式的數據接收模塊和基于WebSocket協議的數據發送模塊能夠大幅提高系統性能。
本文使用Python編程語言設計了大型電機監測系統中云服務器的數據庫通信接口、數據接收接口和數據發送接口。針對云服務器處理大量測量數據時系統負擔加劇的問題,將數據接收接口和數據發送接口進行性能優化,降低云服務器的系統資源消耗。
(1)基于協程方式,通過Tornado庫中的TCPServer方法對數據接收模塊的性能進行優化。相比Socket多線程方法,在相同條件下能夠將CPU占用率降低為之前的73.2%。
(2)基于WebSocket協議,通過Tornado庫中的WebSocketHandler方法對數據發送模塊的性能進行優化,相比基于HTTP協議的方法,在相同條件下能夠將內存占用率降低為之前的85.4%。