劉暾東 黃祚 孫洪飛
(廈門大學自動化系,福建廈門 361005)
目前,全國很多城市的路燈監控系統受到區域限制,仍停留在小規模的監控模式上,使得各地區的監控標準不統一,管理混亂,同時也占用了大量的人力和物力資源。因此,將各區域的路燈監控系統進行統一的管理,形成一個大規模的統一的監控體系,已成為將來路燈監控發展的趨勢。傳統的SOCKET通信模型有著客戶端數量的限制,當實際的客戶端超過限制,將會出現數據阻塞和丟失,甚至是服務器軟件崩潰的情況,而引入了完成端口技術的通信模型沒有客戶端數量的限制,并且擁有著高效的數據處理能力,能夠在大規模路燈監控系統內發揮優勢,保障了數據傳輸的高效性和可靠性。在Visual C++2008編程環境下,通過完成端口技術的應用,將原有的基于C/S模式的路燈監控系統軟件進行優化,使得整套系統可以應用于大數量客戶端的場合,并且仍能保持通信系統較高的穩定性。
路燈監控系統分為遠程終端設備和監控軟件兩個部分。遠程終端設備安裝在路燈控制現場,是實現監控功能的主要硬件設備。遠程終端通過GPRS無線通信網絡與服務器相連[2],根據用戶的設置參數,實現定時開關燈,采集數據和事故報警等功能。根據不同地區的情況,其數量可能非常的龐大,傳輸到服務器的數據量也會非常龐大。監控軟件是一套在 Visual C++2008開發平臺下,基于Client/Server模式的網絡通信軟件[3],由服務端軟件和客戶端軟件兩個部分組成,后臺數據庫選用MS SQL Server 2005。監控系統結構圖如圖1所示。
監控軟件的服務端安裝并工作于服務器上,負責接收監控終端設備傳輸而來的數據,對數據進行分析,并存入數據庫;同時與軟件的客戶端進行通信,并且將軟件客戶端的指令數據,轉發到相應的監控終端設備,對被監控對象的進行管理與控制。監控軟件的客戶端工作在用戶電腦上,通過網絡與服務端和數據庫相連,為少數特定的路燈監控管理員提供服務。客戶端為這些管理員用戶提供了一個功能齊全的圖形界面。用戶可以通過客戶端查詢數據,發送控制指令,也可以通過客戶端的電子地圖功能和柜體監控動畫實時的了解各個遠程終端的工作狀態。
圖1 系統結構圖
3.1.1 完成端口簡介
網絡通信模塊是整個系統最核心的部分,由于要負責大規模的數據傳輸與處理,因此對軟件的性能的高效性提出了挑戰,而完成端口通信技術的應用解決了這一難題。
完成端口 (I/OCompletionPort)是一個Windows NT執行子系統的核心對象。通過將完成端口與任意I/O句柄 (文件或Socket等)關聯,使得用戶可以通過完成端口,異步的獲取并處理 I/O的結果。
完成端口是由系統直接提供并行優化支持的,在完成端口上建立幾個并行的服務線程,一般數量為CPU數,它們為到達完成端口的服務請求提供服務。當有服務請求到達時,如果有可用的服務線程,則激活該線程,如果沒有可用服務線程,則將服務請求加入請求隊列,該隊列采用先進先出 (FIFO)的策略,來保證這些請求得到公平的服務。服務線程的建立和請求隊列的FIFO策略,減少了CPU在不同線程間切換的次數,降低線程上下文切換所造成的開銷。
3.1.2 重疊I/O
完成端口的設計原理是讓應用程序使用重疊的數據結構,一次投遞一個或多個I/O請求,當這些請求完成后,應用程序可以為他們提供服務。這就要求我們在使用完成端口時必須要使用重疊I/O。重疊I/O,即當I/O功能調用時,不論I/O是否完成,函數馬上返回,由操作系統底層處理I/O的實際工作,而應用程序 (進程)可以繼續做其他事情。因而,完成端口是處理完成重疊I/O的一種高效的機制[5]。
3.1.3 工作線程
除了工作在完成端口上的服務線程外,在關聯套接字之前,還必須創建一個或多個工作線程,以便在I/O請求投遞給完成端口對象后,為完成端口提供服務。工作線程的個數取決于應用程序的總體設計情況。創建的工作線程由完成端口管理。當有I/O完成通知到來,則由完成端口喚醒一個工作線程接收I/O完成通知,并對其進行處理。完成端口自動對工作線程進行調度,喚醒哪個工作線程則由完成端口決定。若無I/O完成通知,則所有的工作線程都在等待。根據經驗,工作線程的數量一般為CPU數量的兩倍再加上2。
網絡通信模塊通過 CreateIoCompletionPort函數創建完成端口對象,并將接收到的SOCKET對象與完成端口關聯,啟動一定數量的工作線程,通過GetQueuedCompletionStatus函數獲取完成端口上SOCKET的當前狀態,并將收到的數據從緩存出取出。完成端口的主要工作流程圖如圖2所示。
主線程:
1)程序啟動的時候,初始化網絡并且創建完成端口句柄:
CompletionPort=CreateIoCompletionPort(INVA-LID_HANDLE_VALUE,NULL,0,0);
2)啟動2*N+2個工作線程,N為CPU數量:
圖2 完成端口模塊流程圖
3)進入一個監聽循環,開始監聽客戶端連接請求;
4)將接收到的客戶端SOCKET與完成端口對象綁定;
5)發出一個異步的WSARecv或是WSASend操作,實際的接收和發送數據操作會由操作系統完成。
6)重復以上3)到5)的操作。
工作線程:
1)進入循環,通過GetQueuedCompletionStatus函數,從完成端口上取得 WSASend/WSARecv的操作結果;
2)根據完成端口上I/O狀態,進行數據的處理;
3)提交一個新的WSASend/WSARecv操作請求;
4)重復以上1)到4)的操作。
整個監控系統采用TCP(Transmission Control Protocol,傳輸控制協議)進行數據傳輸,在此基礎上設計了一套監控系統規約,來完成服務端與遠程終端,服務端與客戶端的通信。根據路燈監控的實際需求,數據報文包括以下幾種形式。
1)遠程終端主動向軟件服務端發送的連接認證數據報文,如表1所示。
表1 連接認證數據報文格式
2)遠程終端定時向軟件服務端發送的現場數據報文,主要包括路燈監控現場采集到的電流,電壓,溫度,開關狀態,報警信息等數據信息,如表2所示。
3)軟件客戶端發送給服務端,并由服務端轉發到相應遠程終端的參數設置報文,根據不同的功能號,報文發送不同的參數信息,包括開關燈時間,報警閥值,數據采集周期等如表3所示。
表2 現場數據報文
表3 參數設置報文
3.4.1 內存池的設計
完成端口模型采用異步通信模式,每次調用WSASend和WSARecv函數都需要在內存創建一個結構體空間,函數調用完畢后,再銷毀這個結構體空間。頻繁的創建和銷毀內存空間占用了大量的系統資源,因此,在設計完成端口程序時,根據需求創建一定數量的結構體空間,并將其放入一個統一的空閑隊列,當調用WSASend和WSARecv函數時,從隊列中取用一個結構體空間,使用完畢,再將其放回隊列。
3.4.2 連接池的設計
當用傳統的 accept函數接收客戶端時,accept函數會創建一個socket作為返回值,分配給客戶端。客戶端斷開連接時,創建的socket會被銷毀。創建和銷毀socket的過程會占用大量的系統資源,因此在接收客戶端時,采用 acceptEx函數代替 accept,該函數可以把一個事先創建好的socket對象,分配給接收到的客戶端。首先,創建好一定數量的socket對象,形成一個連接池,當接收到客戶端的連接請求時,從連接池中取出空閑socket對象,分配給該客戶端,斷開連接時,再將socket放回連接池隊列。連接池的設計減少了客戶端SOCKET的不斷創建與銷毀,節省了大量的系統資源。
3.4.3 線程池的設計
完成端口本身就應用了線程池技術,線程池中的線程不僅包括了工作者線程,還包括了工作上完成端口上的服務線程。有效的對這些線程進行管理,能夠減少CPU在不同線程間的頻繁切換,降低了切換線程上下文所耗費的時間。
3.4.4 數據池的設計
完成端口模塊接收到的數據,要根據通信規約進行處理與分析,并將數據存儲到相應的數據庫中。由于完成端口網絡通信的數據傳輸總是不平穩的,常常會出現短時間內接收到大量數據,而另一段時間內只接收到少量數據要的情況。為了防止服務器在短時間內超負荷工作,造成的數據意外丟失或是程序崩潰的情況,在進行數據處理時,預先建立了數據存儲隊列,形成一個數據池,將未處理的數據加入隊列,并采用FIFO的策略來分配CPU時間,這就使得CPU資源得到充分的利用,提高了數據處理的安全性和可靠性。
客戶端軟件通過一般的SOCKET通信方式與服務器相連,主要是功能是為用戶提供一個簡潔,便利的用戶功能界面。地圖顯示模塊通過對GIS電子地圖的繪制,將城市地圖及路燈系統的分布圖直觀的顯示給用戶,使得用戶能夠大體的了解到整個路燈系統的運行狀態。動畫顯示模塊通過FLASH編程技術,將單個遠程終端所控制的配電柜示意圖展示給用戶,用戶可以了解到現場的實時數據并對具體的監控點進行設置,開關燈等操作。數據顯示模塊與數據庫相連,用戶可以查詢到各個監控點的歷史數據以及當前的設置參數,了解路燈系統的具體工作狀態。軟件客戶端主界面如圖3所示。
完成端口通信模型與傳統通信模型相比,擁有更大的數據吞吐量和客戶端數目,并且通過線程池、連接池、內存池的設計和應用,節省了系統資源,提高了服務器軟件的數據處理效率。在對傳統通信模型和完成端口通信模型的性能測試和比較中,選取饑餓的客戶端和每秒線程上下文切換次數兩個重要指標為測試對象。饑餓的客戶端定義為同一時間向服務器申請連接并發送數據的客戶端中,未被服務器影響的客戶端數。
選用兩臺 Intel Core2 1.9GHz雙核 CPU,2G內存臺式機,一臺用作服務器電腦,一臺用作客戶端電腦。服務器電腦上分別安裝傳統通信模型的舊版路燈監控軟件和完成端口模型的新版路燈監控軟件,并且在軟件程序中加入測試代碼,用來計算饑餓客戶端數目和線程上下文的切換次數;客戶端電腦上用測試軟件來模擬一定數量的終端設備的客戶端,并向服務器同時進行連接和發送數據的操作。
圖3 客戶端軟件主界面
不斷的改變模擬客戶端的數量,對兩種通信模型進行測試,分別記錄下兩種模型在不同數量的客戶端下,饑餓客戶端數量和線程上下文切換的次數,重復多次測試,取得多組數據,取其平均值。
如表4所示,當模擬客戶端數目逐漸增加時,傳統通信模型的饑餓客戶端數量也不斷增加,這就使得大量的客戶端無法得到服務器響應,大量客戶端的數據無法傳輸,導致數據的阻塞和丟失。而完成端口通信模型采取了一系列的優化策略,并不存在客戶端無法得到服務的情況。
表4 饑餓客戶端測試
如表5所示,在模擬客戶端數量較少時,兩種通信模型的線程上下文切換次數相當;當模擬客戶端數量增加時,傳統通信模型的切換次數劇增,而每次的切換都會導致系統資源的額外開銷,這就使的傳統通信模型的數據處理效率十分低下。使用完成端口通信模型時,線程上下文切換次數并未隨著模擬客戶端的增加而產生更大的變化,因此完成端口模型更適合于大量客戶端的應用場合,并且仍可保持的數據通信的可靠性和高效性。
表5 每秒線程上下文切換次數
完成端口技術的引入,充分發揮了服務器多CPU的優勢,使得整個監控系統的數據通信性能得到了極大的優化了。經過壓力測試,當監控終端設備數量達5000時,系統仍然能夠保持高效、穩定的運行。目前該系統應用于廈門路橋公司,龍巖長汀等地的路燈控制,取得了良好的效果。
[1]趙炯,徐博銘,宋蘊璞.火災報警系統集成監控和管理軟件設計 [J].計算機工程,2008,34(16):259~261
[2]王成福,唐曉強.基于GPRS的路燈監控系統的設計與實現 [J].電力系統通信,2008,29(190):18~21
[3]閆謙時,陳雷.一種基于網絡的監控軟件設計與實現[J].計算機與數字工程,2009,37(2):183~185
[4]基于IOCP機制的網絡游戲服務器通信層的實現 [J].計算機工程與應用,2009,47(7):75~81
[5]Gyu-baek Kim,An Effective Processing Server for Various Database Operations of Large-scale On-line Games[C],IASTED International Conference on Information and Knowledge Sharing,Arizona,U.S.A,November 2003,Vol.1,pp.188~192
[6]陳和平,王早,李曉卉.基于單個 I/O完成端口的HTTP代理方法研究 [J].計算機工程與設計,2005,26(11):2995~2997
[7]唐海娜,李俊.網絡性能監測技術綜述 [J].計算機應用研究,2004,21(8):10~13