付學(xué)良,李德軍
(南京國電南自電網(wǎng)自動(dòng)化有限公司,南京 210000)
配電網(wǎng)作為輸配電系統(tǒng)的最后一個(gè)環(huán)節(jié),其自動(dòng)化程度與供電可靠性密切相關(guān)。配電自動(dòng)化是改進(jìn)供電質(zhì)量、提高供電可靠性、擴(kuò)大供電能力、實(shí)現(xiàn)配電網(wǎng)高效經(jīng)濟(jì)運(yùn)行的重要手段[1]。與調(diào)度自動(dòng)化系統(tǒng)相比,配電自動(dòng)化系統(tǒng)的數(shù)據(jù)采集存在以下特點(diǎn):(1)配電網(wǎng)數(shù)據(jù)采集量大,采集頻率較低,中型系統(tǒng)采集量已超過20萬點(diǎn);(2)主站與終端設(shè)備直接通信,通信鏈路數(shù)隨監(jiān)控設(shè)備增加而大幅增加;(3)存在基于公網(wǎng)的數(shù)據(jù)采集;(4)系統(tǒng)的典型部署模式是地縣一體。由此可見,配電網(wǎng)大數(shù)據(jù)采集成為配電自動(dòng)化系統(tǒng)的一項(xiàng)關(guān)鍵技術(shù)[2]。Linux下的epoll機(jī)制是處理高并發(fā)(High concurrency)的成功模型,其與Windows下完成端口(IOCP)機(jī)制,都是I/O復(fù)用,都是異步消息事件的通知機(jī)制。將基于epoll機(jī)制的設(shè)計(jì)模型應(yīng)用于大規(guī)模tcp連接,互聯(lián)網(wǎng)方面的成功案例很多,但應(yīng)用于電力自動(dòng)化的少之又少,epoll模型成功用于配電自動(dòng)化采集,對(duì)配電自動(dòng)化的快速發(fā)展,以及后續(xù)的大數(shù)據(jù)分析有積極意義。
目前,Linux下I/O多路復(fù)用機(jī)制主要有3種:select,poll和epoll。 I/O多路復(fù)用就是通過一種機(jī)制,可以監(jiān)視多個(gè)描述符,一旦某個(gè)描述符就緒(一般是讀就緒或者寫就緒),能夠通知程序進(jìn)行相應(yīng)的讀寫操作。但select,poll,epoll本質(zhì)上都是同步I/O,因?yàn)樗鼈兌夹枰谧x寫事件就緒后自己負(fù)責(zé)讀寫,也就是說這個(gè)讀寫過程是阻塞的,而異步I/O則無需自己負(fù)責(zé)讀寫,異步I/O會(huì)負(fù)責(zé)把數(shù)據(jù)從內(nèi)核拷貝到用戶空間[3]。表1簡要列出了三者的區(qū)別。
epoll是Linux內(nèi)核為處理大批量文件描述符而做了改進(jìn)的poll,是Linux下多路復(fù)用I/O接口select/poll的增強(qiáng)版本,它能顯著提高程序在大量并發(fā)連接中只有少量活躍情況下系統(tǒng)中央處理器(CPU)的利用率。另一點(diǎn)原因是,獲取事件時(shí)它無須遍歷整個(gè)被偵聽的描述符集,只要遍歷那些被內(nèi)核I/O事件異步喚醒而加入Ready隊(duì)列的描述符集合就行了。epoll除了提供select/poll那種I/O事件的水平觸發(fā)(Level triggered)外,還提供了邊緣觸發(fā)(Edge triggered),這就使得用戶空間程序有可能緩存I/O狀態(tài),減少epoll_wait/epoll_pwait的調(diào)用,提高應(yīng)用程序效率[4]。
與傳統(tǒng)電力信息采集服務(wù)器模型不同,大規(guī)模配電終端采集面臨連接終端數(shù)量多、信息量大、通信鏈路不穩(wěn)定的問題,同時(shí)還必須保證數(shù)據(jù)響應(yīng)的快速性和可靠性[5]?;谝陨咸匦?,本文提出了一種基于epoll機(jī)制,采用多線程同步技術(shù)、超時(shí)異常處理技術(shù)的海量通信連接處理模型。采用epoll機(jī)制解決了海量配電終端網(wǎng)絡(luò)通信以及效率和可靠性問題;超時(shí)異常處理技術(shù)解決了作為客戶端連接時(shí),epoll模型的穩(wěn)定性問題;多線程同步中的互斥鎖技術(shù)很好地解決了數(shù)據(jù)處理過程中的效率和穩(wěn)定性問題[6]。
表1 select,poll與epoll區(qū)別[3]
海量配電終端信息處理模型由網(wǎng)絡(luò)通信層、數(shù)據(jù)處理層和消息隊(duì)列3部分組成。網(wǎng)絡(luò)通信層為主線程,專門負(fù)責(zé)epoll的維護(hù)、配電終端數(shù)據(jù)接收,推送數(shù)據(jù)到消息隊(duì)列。數(shù)據(jù)處理層主要負(fù)責(zé)處理消息隊(duì)列的數(shù)據(jù),此部分由多個(gè)線程共同處理,每個(gè)線程定期掃描對(duì)應(yīng)的消息隊(duì)列,有數(shù)據(jù)時(shí)進(jìn)行處理,相當(dāng)于數(shù)據(jù)的消費(fèi)過程。消息隊(duì)列與數(shù)據(jù)線程一一對(duì)應(yīng),每個(gè)數(shù)據(jù)線程只處理自己對(duì)應(yīng)消息隊(duì)列的數(shù)據(jù)。此模型將網(wǎng)絡(luò)信息獲取和信息處理分離,用共享數(shù)據(jù)隊(duì)列作為二者的交換介質(zhì),用互斥鎖來控制二者的訪問權(quán)限,保證了數(shù)據(jù)接受的完整性和時(shí)效性。海量配電終端信息處理模型如圖1所示。
圖1 海量配電終端信息處理模型
一般情況下,創(chuàng)建1個(gè)線程是不能提高程序執(zhí)行效率的,所以要?jiǎng)?chuàng)建多個(gè)線程。但是,多個(gè)線程同時(shí)運(yùn)行時(shí)可能調(diào)用線程函數(shù),在多個(gè)線程同時(shí)對(duì)同一個(gè)內(nèi)存地址進(jìn)行寫入,由于CPU時(shí)間調(diào)度上的問題,寫入數(shù)據(jù)會(huì)被多次覆蓋,導(dǎo)致后續(xù)數(shù)據(jù)讀取異常,甚至程序的異常中斷退出。
基于上述問題,多線程對(duì)同一資源訪問時(shí),采用線程同步機(jī)制中的互斥鎖技術(shù)來控制處理數(shù)據(jù)的寫入。主線程接收到配電終端發(fā)送的實(shí)時(shí)數(shù)據(jù),相當(dāng)于生產(chǎn)者,信息處理線程負(fù)責(zé)處理數(shù)據(jù),相當(dāng)于消費(fèi)者。對(duì)于每個(gè)緩沖隊(duì)列定義一個(gè)互斥鎖,當(dāng)網(wǎng)絡(luò)通信線程收到終端發(fā)送的1條數(shù)據(jù)時(shí),申請(qǐng)對(duì)其中某一個(gè)隊(duì)列加鎖,然后將數(shù)據(jù)加入到此隊(duì)列中,之后解鎖。當(dāng)對(duì)應(yīng)處理線程開始工作后,申請(qǐng)對(duì)此隊(duì)列加鎖,發(fā)現(xiàn)隊(duì)列中存在數(shù)據(jù),對(duì)此數(shù)據(jù)記性處理,之后解鎖。多個(gè)線程以此類推。
傳統(tǒng)epoll模型大多針對(duì)服務(wù)器端,而配電終端采集不僅僅要考慮服務(wù)器模式,還要考慮批量客戶端模式。例如,北京電力科學(xué)研究院歷年針對(duì)配電主站國網(wǎng)的測試中,數(shù)據(jù)采集規(guī)約采用IEC60870-5-104《配電自動(dòng)化系統(tǒng)應(yīng)用DL/T 634.5104—2009實(shí)施細(xì)則》,此規(guī)約需要配電主站采集側(cè)作為客戶端,原有的epoll服務(wù)器端模式無法滿足要求。本文在原有服務(wù)器模式基礎(chǔ)上,設(shè)計(jì)了客戶端模型,實(shí)現(xiàn)了服務(wù)端和客戶端并存的信息采集模型。
此模型在不影響服務(wù)端工作的基礎(chǔ)上,創(chuàng)建打開線程來定期連接海量配電終端,根據(jù)epoll產(chǎn)生的回調(diào)事件來判斷與終端連接是否成功。但在不同的操作系統(tǒng)中,由于協(xié)議棧機(jī)制問題,并不是每個(gè)定期連接都會(huì)產(chǎn)生回調(diào)事件,在此引入超時(shí)異常處理機(jī)制,將超時(shí)還未產(chǎn)生回調(diào)的連接終端加入到超時(shí)隊(duì)列中,作為epoll的異常處理fd,將其從epoll文件描述符集合中刪除,從而保證了epoll文件描述符集合的正確性和穩(wěn)定性。
在ubuntu12.04服務(wù)器上,本文提出了海量配電終端信息處理模型的實(shí)現(xiàn)方法,編寫了一個(gè)海量配電終端信息采集和處理的服務(wù)軟件。本服務(wù)軟件直接調(diào)用Linux底層內(nèi)核函數(shù)實(shí)現(xiàn)epoll機(jī)制,利用互斥鎖實(shí)現(xiàn)線程同步,運(yùn)行超時(shí)處理機(jī)制實(shí)現(xiàn)epoll穩(wěn)定連接。服務(wù)端/客戶端軟件的基本流程如下。
(1)初始化,包括讀取數(shù)據(jù)庫中配置好的海量終端參數(shù),創(chuàng)建互斥鎖,創(chuàng)建處理線程。
(2)創(chuàng)建監(jiān)聽服務(wù)。
(3)創(chuàng)建epoll,初始化epoll,將本地監(jiān)聽的socket加入到epoll文件描述符集合中。
(4)創(chuàng)建打開線程,定期連接配電終端(服務(wù)端)。
(5)開始定期調(diào)用epoll_wait(),獲取文件描述符事件數(shù),并對(duì)所有事件逐個(gè)處理。事件主要分為接收配電終端連接事件、連接到配電終端事件、讀寫事件及錯(cuò)誤事件,其中,可讀事件負(fù)責(zé)進(jìn)行數(shù)據(jù)接收處理。
(6)數(shù)據(jù)的處理線程在啟動(dòng)后以輪詢的方式從緩沖隊(duì)列獲取數(shù)據(jù),并進(jìn)行相應(yīng)處理。
(7)打開線程連接某個(gè)配電終端超時(shí)時(shí),作為異常的epoll文件描述符處理,即從文件描述符集合中刪除,并關(guān)閉對(duì)應(yīng)socket,基本流程如圖2所示。
圖2 epoll機(jī)制C/S模型流程圖
目前,陜西寶雞采用的配電主站采集系統(tǒng)中,前置采集模塊模型采集的是本文提出的epoll模型,采集服務(wù)器配置為Ubuntu 12.4,64G內(nèi)存,CPU20核?,F(xiàn)場已接入故障指示器、饋線終端設(shè)備(DTU)、配變終端設(shè)備(FTU)等配電終端達(dá)到2 000個(gè),CPU占用率在5%左右,接入數(shù)據(jù)穩(wěn)定、準(zhǔn)確,并且時(shí)效性高。
本文研究了Linux epoll機(jī)制,并基于此機(jī)制研究了海量配電終端的信息采集模型,運(yùn)用epoll經(jīng)典服務(wù)模型,結(jié)合多線程同步技術(shù)和超時(shí)異常處理技術(shù),解決了配電信息大容量采集的一個(gè)核心問題,既滿足了作為服務(wù)端信息采集的高容量性,又滿足了作為大批量客戶端訪問配電終端穩(wěn)定性,保證了配電信息采集的安全性和時(shí)效性。本文采集模型已應(yīng)用于陜西寶雞配電網(wǎng)系統(tǒng),證明了此模型的有效性和穩(wěn)定性。