鄧桂星,張 銳,李世春,劉耀宗,王 瑜
(中國鐵路蘭州局集團(tuán)有限公司 信息技術(shù)所,蘭州 730000)
車流徑路是當(dāng)前我國鐵路優(yōu)化運輸組織、合理分配運力資源、提升路網(wǎng)整體通過能力的重要技術(shù)手段,為鐵路貨運編組計劃制定、運到時限考核、車流推算、違規(guī)車流判定、計費徑路調(diào)整等業(yè)務(wù)提供必要的數(shù)據(jù)支持。先前開發(fā)的“可視化鐵路網(wǎng)貨流、車流公共信息平臺”[1]解決了全路車流徑路判定的問題,廣泛應(yīng)用于貨運、運輸[2]、調(diào)度和統(tǒng)計等業(yè)務(wù)信息系統(tǒng)[3]。但這些應(yīng)用采用本地計算模式,依賴于最新下載的車流徑路數(shù)據(jù),若未及時更新徑路數(shù)據(jù),會造成計算結(jié)果與運輸實際情況的差異,不利于運輸組織和經(jīng)營考核。
為解決上述問題,在64 bit Linux 操作系統(tǒng)上,利用 Eclipse 開發(fā)工具和I/O 編程模型EPOLL,開發(fā)全路車流徑路服務(wù),實現(xiàn)全路車流徑路數(shù)據(jù)的集中計算與分布應(yīng)用。
WebLogic 與Tomcat 服務(wù)均基于Java 語言,而先前開發(fā)的車流徑路算法程序基于C++語言,跨語言代碼調(diào)用需借助JNA,會顯著降低系統(tǒng)運行效率。且傳統(tǒng)網(wǎng)絡(luò)通訊SELECT 編程模型已不能滿足目前訪問車流徑路數(shù)據(jù)的大量客戶端連接和高速數(shù)據(jù)傳輸需求。EPOLL 編程模型是Linux 內(nèi)核為處理大批量文件描述符而改進(jìn)的POLL,是Linux 操作系統(tǒng)上多路復(fù)用I/O 接口-SELECT/POLL 的增強版本,在大量并發(fā)連接中只有部分連接活躍的情況下,可顯著提高系統(tǒng)CPU 利用率[4]。經(jīng)過與Windows 操作系統(tǒng)上的SELECT 編程模型和IOCP 編程模型的實驗對比,發(fā)現(xiàn)在Linux 操作系統(tǒng)上采用EPOLL 編程模型開發(fā)應(yīng)用服務(wù),代碼維護(hù)簡潔、并發(fā)處理能力強、讀寫效率高,能夠滿足訪問車流徑路數(shù)據(jù)的大量客戶端連接及高速數(shù)據(jù)傳輸?shù)男枨蟆?/p>
EPOLL 編程模型與SELECT/POLL 類似,均是基于TCP/IP 網(wǎng)絡(luò)傳輸協(xié)議的套接字編程模型,但EPOLL 模型可承載更多并發(fā)客戶端連接,采用內(nèi)存映射等技術(shù),且系統(tǒng)調(diào)用時只處理活躍連接,執(zhí)行效率更高[4],其工作流程如圖1 所示。
圖1 EPOLL 編程模型的工作流程
(1)INT EPOLL_CREATE(INT SIZE),用于生成一個EPOLL 專用的文件描述符,即申請一段內(nèi)存空間來存放被關(guān)注的套接字上發(fā)生的事件;參數(shù)SIZE 是系統(tǒng)連接的最大客戶端數(shù)量,可被省略(此時取系統(tǒng)最大值)[5]。
(2)INT EPOLL_CTL(···,STRUCT EPOLL_EVENT *EV),用于控制被關(guān)注的文件描述符上發(fā)生的事件:注冊、修改、刪除;參數(shù)EV 用于通知操作系統(tǒng)需要監(jiān)聽何種事件。
(3)INT EPOLL_WAIT(···, STRUCT EPOLL_EVENT *EVENTS,···),用于獲取有觸發(fā)事件的文件描述符;函數(shù)調(diào)用過程中使用內(nèi)存映射(MMAP)技術(shù),免去復(fù)制文件描述符的開銷[4]。
水平觸發(fā)方式(LT,Level Triggered):操作系統(tǒng)會通知文件描述符是否就緒;若已就緒,程序可讀寫就緒的套接字;若程序未做任何操作,操作系統(tǒng)會繼續(xù)發(fā)出通知;水平觸發(fā)方式編程出錯的可能性小,但處理速度慢[5]。
邊沿觸發(fā)方式(ET,Edge Triggered):是一種高速工作方式,只支持非阻塞,比水平觸發(fā)效率高;當(dāng)一個事件發(fā)生時,可調(diào)用EPOLL_WAIT 獲取該事件,若系統(tǒng)尚未處理完該事件對應(yīng)的套接字緩沖區(qū),而這個套接字中沒有新的事件發(fā)生時,不能再通過EPOLL_WAIT 調(diào)用獲得該事件[5]。
水平觸發(fā)方式下,開發(fā)EPOLL 服務(wù)簡單且不易出錯;邊沿觸發(fā)方式下,程序運算速度快,但代碼略微復(fù)雜。
車流徑路服務(wù)的開發(fā)采用邊沿觸發(fā)方式。
基于EPOLL 編程模型的車流徑路服務(wù)的開發(fā)包括車流徑路系統(tǒng)[6]的移植與EPOLL 服務(wù)的設(shè)計與實現(xiàn)。
先前開發(fā)的車流徑路系統(tǒng)是在Win32 操作系統(tǒng)上采用標(biāo)準(zhǔn)C++語言開發(fā)的。而車流徑路系統(tǒng)的移植利用Linux 版Eclipse 作為開發(fā)工具[7],需解決從32 bit 操作系統(tǒng)移植到64 bit 操作系統(tǒng)的相關(guān)問題。在32 bit 操作系統(tǒng)上,long 和pointer 變量的長度為4 byte[8],在64 bit 操作系統(tǒng)上則為8 byte,移植后會造成內(nèi)存空間大小的變化以及讀取二進(jìn)制文件錯位等問題。為此,采用宏定義統(tǒng)一變量長度,編譯生成.SO 文件(動態(tài)鏈接庫),供EPOLL 模型調(diào)用。
64 bit 操作系統(tǒng)的尋址能力更強,可顯著提高運行效率。經(jīng)實驗對比發(fā)現(xiàn),在Win32 操作系統(tǒng)的單進(jìn)程模式下,每秒鐘能計算7萬條車流徑路數(shù)據(jù),Linux64 操作系統(tǒng)下則可達(dá)10萬條左右。
基于EPOLL 模型的服務(wù)采用多線程技術(shù)來提高訪問效率;主線程負(fù)責(zé)收集已經(jīng)發(fā)生的客戶端事件、徑路計算和數(shù)據(jù)傳輸,監(jiān)聽線程負(fù)責(zé)處理新的客戶端連接。
如圖2 所示,車流徑路服務(wù)的建立過程如下:
圖2 車流徑路服務(wù)的建立過程
(1)調(diào)用EPOLL_CREATE()生成一個EPOLL 專用的文件描述符,并啟動車流徑路系統(tǒng);
(2)在主線程中調(diào)用EPOLL_WAIT()收集已經(jīng)發(fā)生的客戶端事件,并進(jìn)行車流徑路計算和數(shù)據(jù)傳輸;
(3)啟動監(jiān)聽線程,專門處理新的客戶端連接,管理客戶端隊列;
(4)卸載車流徑路數(shù)據(jù),清空客戶端隊列,關(guān)閉EPOLL 專用文件描述符,退出服務(wù)。
在實驗環(huán)境下,采取多線程技術(shù)[9]模擬客戶端的并發(fā)訪問,進(jìn)行壓力測試。在創(chuàng)建10000個并發(fā)線程時,基于EPOLL 編程模型的車流徑路服務(wù)的連接、運算和傳輸都較為穩(wěn)定,CPU 利用率和內(nèi)存占用率均在正常范圍內(nèi)。與Tomcat 服務(wù)、SELECT 和IOCP 編程模型相比,基于EPOLL 編程模型的車流徑路服務(wù)在編程復(fù)雜度、傳輸效率和穩(wěn)定性方面均有明顯優(yōu)勢。目前,該服務(wù)已為全路車流徑路的實時查詢、貨物運到時限預(yù)警、承運清算以及鐵路局的其它特色應(yīng)用提供支持,每日計算量在10萬次以上,高峰訪問并發(fā)量約1000個用戶。經(jīng)過一年的運行監(jiān)測,該服務(wù)運行穩(wěn)定,未發(fā)現(xiàn)異常狀況。
Linux 操作系統(tǒng)及EPOLL 編程模型具有高并發(fā)、高效率和高穩(wěn)定性,滿足國產(chǎn)化應(yīng)用的開發(fā)需求,使應(yīng)用系統(tǒng)開發(fā)擺脫了對商業(yè)中間件的依賴。利用Linux 操作系統(tǒng)內(nèi)核的高并發(fā)處理機(jī)制,較好地解決了車流徑路共享難題,實現(xiàn)全路車流徑路數(shù)據(jù)的集中運算和分布應(yīng)用。
今后,還將采用二進(jìn)制流方式進(jìn)行數(shù)據(jù)傳輸,以提高數(shù)據(jù)的安全性和傳輸效率。