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