石 毅,陳 愷
(中國(guó)民用航空中南地區(qū)空中交通管理局廣西分局,南寧 530100)
廣西空管分局現(xiàn)階段管理運(yùn)行的本地相關(guān)空管數(shù)據(jù)類型包括監(jiān)視數(shù)據(jù),報(bào)文數(shù)據(jù)等。而監(jiān)視數(shù)據(jù)包括萊斯自動(dòng)化系統(tǒng)綜合航跡、華泰自動(dòng)化系統(tǒng)綜合航跡、雷達(dá)數(shù)據(jù)、ADSB 數(shù)據(jù)等。以萊斯自動(dòng)化系統(tǒng)綜合航跡數(shù)據(jù)的引接應(yīng)用為例,一共包括氣象融合系統(tǒng)、自動(dòng)化主備同步監(jiān)控系統(tǒng)、空中交通流量預(yù)測(cè)系統(tǒng)等七套系統(tǒng)引接該路數(shù)據(jù)。若均直接通過(guò)萊斯自動(dòng)化系統(tǒng)DOP(綜合數(shù)據(jù)輸出)服務(wù)器引接,將極大增加服務(wù)器的工作負(fù)荷。因此,為加強(qiáng)分局本地?cái)?shù)據(jù)管理,規(guī)范數(shù)據(jù)信號(hào)輸出,合理規(guī)劃數(shù)據(jù)信號(hào)資源,并有效監(jiān)控各路本地?cái)?shù)據(jù)鏈路狀態(tài),擬研制空管綜合數(shù)據(jù)交互平臺(tái)。
空管綜合數(shù)據(jù)交互平臺(tái)采用基于Java 語(yǔ)言的C/S 架構(gòu)進(jìn)行系統(tǒng)的構(gòu)建[1],系統(tǒng)主要包含一臺(tái)數(shù)據(jù)處理服務(wù)器及防火墻,其結(jié)構(gòu)如圖1 所示。
圖1 空管綜合數(shù)據(jù)交互平臺(tái)結(jié)構(gòu)框圖
系統(tǒng)主要功能模塊包括數(shù)據(jù)接收處理模塊、數(shù)據(jù)輸出模塊及終端顯示模塊。系統(tǒng)通過(guò)接收處理各路監(jiān)視數(shù)據(jù)、報(bào)文數(shù)據(jù)及其他本地空管數(shù)據(jù),并根據(jù)終端用戶應(yīng)用需求,將相應(yīng)數(shù)據(jù)定制輸出到對(duì)應(yīng)系統(tǒng),實(shí)現(xiàn)數(shù)據(jù)資源的規(guī)劃應(yīng)用。此外,系統(tǒng)提供收發(fā)鏈路的開(kāi)關(guān)操作,斷線告警,延遲監(jiān)測(cè)及歷史數(shù)據(jù)的查詢和調(diào)用輸出等功能。系統(tǒng)的信號(hào)處理流程如圖2所示。
圖2 系統(tǒng)信號(hào)處理流程
數(shù)據(jù)接收處理效率,是衡量數(shù)據(jù)接收處理模塊的重要技術(shù)指標(biāo)之一。由于在輸入鏈路上,各監(jiān)視數(shù)據(jù)、報(bào)文數(shù)據(jù)及其他相關(guān)空管數(shù)據(jù)存在輸入上的流量差異(各數(shù)據(jù)類型流量統(tǒng)計(jì)為:監(jiān)視數(shù)據(jù)>報(bào)文數(shù)據(jù)>其他空管數(shù)據(jù)),以氣象報(bào)文、自動(dòng)化系統(tǒng)報(bào)文數(shù)據(jù)接收為例,氣象報(bào)文數(shù)據(jù)鏈路僅在每個(gè)整點(diǎn)發(fā)送一份報(bào)文數(shù)據(jù),其余均為空閑時(shí)段,而自動(dòng)化系統(tǒng)當(dāng)處于主用狀態(tài)時(shí),系統(tǒng)報(bào)文數(shù)據(jù)鏈路將對(duì)外發(fā)送數(shù)據(jù)。若對(duì)上述鏈路的數(shù)據(jù)接收處理均采用傳統(tǒng)的多線程技術(shù),將占用系統(tǒng)大量進(jìn)程資源,極大增加系統(tǒng)服務(wù)器的工作壓力。因此,提出采用基于Java的NIO技術(shù),該方法將有效提高數(shù)據(jù)接收效率,節(jié)約系統(tǒng)資源。
Java NIO 即同步非阻塞I/O 模型,它包含Channel、Buffer、Selector三大核心組件[2]。Channel 為通道,它表示一個(gè)打開(kāi)的連接,這個(gè)連接可以連接到I/O 設(shè)備或者一個(gè)支持I/O 訪問(wèn)的應(yīng)用程序;Buffer 為緩沖區(qū),在NIO 庫(kù)中,所有數(shù)據(jù)都是通過(guò)緩沖區(qū)進(jìn)行處理;Selector 為選擇器,其提供了選擇已經(jīng)就緒的任務(wù)的能力。在Java NIO中,通過(guò)使用緩沖區(qū)和通道來(lái)進(jìn)行數(shù)據(jù)傳輸。而選擇器將會(huì)不斷地輪詢注冊(cè)在上面的所有通道,如果某個(gè)通道為讀寫等事件做好準(zhǔn)備,那么就處于就緒狀態(tài),即可進(jìn)行后續(xù)的IO操作。這樣,一個(gè)單獨(dú)的線程可以管理多個(gè)通道,從而管理多個(gè)網(wǎng)絡(luò)連接,提高效率。Java NIO連接模型如圖3所示。
圖3 Java NIO連接模型
目前,空管綜合數(shù)據(jù)交互平臺(tái)共引接萊斯自動(dòng)化系統(tǒng)綜合航跡、萊斯自動(dòng)化系統(tǒng)計(jì)劃、S模式雷達(dá)、ADS-B 數(shù)據(jù)、氣象報(bào)文等共九路數(shù)據(jù)源。Java NIO技術(shù)實(shí)現(xiàn)各路數(shù)據(jù)接收處理的主要步驟如下:
(1)根據(jù)低流量數(shù)據(jù)源的數(shù)據(jù)類型,設(shè)置不同類型的緩沖區(qū)。如QNH 數(shù)據(jù)設(shè)置為ByteBuffer類型;
(2)為每個(gè)緩沖區(qū)建立通道,如QNH 數(shù)據(jù)緩沖區(qū)的通道類型為ServerSocketChannel,該通道類型可以監(jiān)聽(tīng)新進(jìn)來(lái)的TCP 連接,對(duì)每一個(gè)新進(jìn)來(lái)的連接都會(huì)創(chuàng)建一個(gè)SocketChannel,通過(guò)TCP 讀寫網(wǎng)絡(luò)中的數(shù)據(jù);
(3)創(chuàng)建選擇器,并向選擇器注冊(cè)通道;
(4)設(shè)置選擇器對(duì)通道的監(jiān)聽(tīng)事件類型,如對(duì)于QNH數(shù)據(jù)緩沖區(qū)的通道監(jiān)聽(tīng)事件類型為SelectionKey.OP_WRITE,即有數(shù)據(jù)寫入緩沖區(qū)時(shí),再讀取緩沖區(qū)寫入通道的數(shù)據(jù);
(5)調(diào)用Buffer clear()方法,清空緩沖區(qū),等待下次數(shù)據(jù)的寫入。
通過(guò)Java NIO 技術(shù),統(tǒng)計(jì)系統(tǒng)滿負(fù)荷情況下,共減少非必要線程開(kāi)支數(shù)量四個(gè),釋放了約500 M 的內(nèi)存資源。數(shù)據(jù)接收處理模塊部分代碼如圖4所示。
圖4 數(shù)據(jù)接收處理模塊部分代碼
空管綜合數(shù)據(jù)交互平臺(tái)提供歷史數(shù)據(jù)查詢及調(diào)用功能。其歷史數(shù)據(jù)儲(chǔ)存主要為監(jiān)視數(shù)據(jù)的存儲(chǔ),儲(chǔ)存方式通過(guò)數(shù)據(jù)文件(.DAT)方式,按天為單位以時(shí)間戳YYYYMMDD 命名進(jìn)行存儲(chǔ),文件存放到服務(wù)器指定目錄下。若各路數(shù)據(jù)源存儲(chǔ)過(guò)程或進(jìn)行歷史數(shù)據(jù)調(diào)用輸出操作時(shí),均采用實(shí)時(shí)文本讀寫的方式,將極大影響數(shù)據(jù)存儲(chǔ)模塊的讀寫速度,增加服務(wù)器的工作壓力。因此,提出一種改進(jìn)型Hash 算法,實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)模塊的數(shù)據(jù)高性能存儲(chǔ)及調(diào)用功能,增強(qiáng)系統(tǒng)可塑性及可靠性。
Hash 定義為基于特定鍵將一個(gè)值轉(zhuǎn)換為另一個(gè)值的過(guò)程,是一種將輸入值轉(zhuǎn)換為通常更短的輸出值的函數(shù),并且被設(shè)計(jì)為對(duì)于每個(gè)輸入值都是唯一的。Hash 函數(shù)的主要優(yōu)點(diǎn)是可以用于在相對(duì)較小的空間中存儲(chǔ)任何大小的數(shù)據(jù),其在計(jì)算機(jī)編程中用于各種目的,例如將數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中或驗(yàn)證數(shù)據(jù)完整性。而選擇對(duì)應(yīng)的Hash 算法主要考慮三點(diǎn):①安全性,算法具有一定加密性;②算法的速度,算法具備高性能處理能力;③輸入的大小,算法可以滿足處理數(shù)據(jù)源的數(shù)據(jù)大小。由于空管綜合數(shù)據(jù)交互平臺(tái)運(yùn)行環(huán)境為內(nèi)網(wǎng)環(huán)境,數(shù)據(jù)存取較為安全,而數(shù)據(jù)處理速度相對(duì)要求較高,且監(jiān)視數(shù)據(jù)源的數(shù)據(jù)流量較大,因此,選擇SHA-256算法。在密碼學(xué)中,SHA 是加密哈希函數(shù),SHA-256是最常用的使用32 位字計(jì)算的哈希函數(shù)。對(duì)于任意長(zhǎng)度的消息,SHA-256 都會(huì)產(chǎn)生一個(gè)256位的哈希值,稱作消息摘要。這個(gè)摘要相當(dāng)于是個(gè)長(zhǎng)度為32 個(gè)字節(jié)的數(shù)組,通常由一個(gè)長(zhǎng)度為64 的十六進(jìn)制字符串來(lái)表示。本質(zhì)上,它是一個(gè)通過(guò)將消息區(qū)塊為密鑰對(duì)中間哈希值進(jìn)行加密的256位加密算法。該算法具備安全、快速的特點(diǎn),并且可以處理大量數(shù)據(jù)。最后,通過(guò)調(diào)用Java HashMap方法實(shí)現(xiàn)Hash[3]。
HashMap 類使用Hash 算法來(lái)存儲(chǔ)和檢索數(shù)據(jù),它存儲(chǔ)表示為鍵值對(duì)的數(shù)據(jù),其中鍵是非空且唯一的。Hash 算法實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)的主要步驟為:①為各路接入監(jiān)視數(shù)據(jù)源創(chuàng)建HashMap,HashMap 以接收時(shí)間戳為鍵值,算法通過(guò)調(diào)用getInstance(“SHA-256”)的靜態(tài)方法進(jìn)行初始化;②當(dāng)監(jiān)視數(shù)據(jù)源有數(shù)據(jù)接收時(shí),為數(shù)據(jù)標(biāo)記當(dāng)前接收時(shí)間戳,并調(diào)用add()方法,存入對(duì)應(yīng)HashMap;③設(shè)置監(jiān)聽(tīng)HashMap 的大小,當(dāng)?shù)竭_(dá)一定值后,調(diào)用ge(tkey)方法,按接收時(shí)間順序查找時(shí)間戳鍵值,獲取其對(duì)應(yīng)的數(shù)據(jù)值;④調(diào)用spli(t)方法,按時(shí)間戳對(duì)數(shù)據(jù)值進(jìn)行拆分,并打印輸出;⑤調(diào)用BufferedWriter()方法,將打印內(nèi)容寫入數(shù)據(jù)文件;⑥調(diào)用remove()方法,刪除HashMap 中已完成查找的時(shí)間戳鍵值及其對(duì)應(yīng)的數(shù)據(jù)數(shù)值。實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)的部分代碼如圖5所示。
圖5 數(shù)據(jù)存儲(chǔ)模塊部分代碼
而當(dāng)執(zhí)行歷史數(shù)據(jù)調(diào)用功能時(shí),實(shí)現(xiàn)該功能的關(guān)鍵步驟為:①調(diào)用Java的Date()方法,設(shè)置數(shù)據(jù)回放的開(kāi)始時(shí)間;②調(diào)用Java 的Timer()方法,設(shè)置數(shù)據(jù)回放的時(shí)間軸為1秒步進(jìn);③調(diào)用Java 的InputStreamReader()和BufferedReader()方法,讀取該回放時(shí)間的數(shù)據(jù)文件中滿足當(dāng)前回放時(shí)刻的數(shù)據(jù)段,并暫存數(shù)據(jù)回放Hashmap;④將Hashmap 內(nèi)容輸出至數(shù)據(jù)輸出模塊,進(jìn)行封裝,并最終發(fā)送至指定地址及端口;⑤調(diào)用Java 的Runnable()方法線程,對(duì)數(shù)據(jù)回放過(guò)程進(jìn)行實(shí)時(shí)監(jiān)聽(tīng),當(dāng)?shù)竭_(dá)回放結(jié)束時(shí)間后,停止數(shù)據(jù)回放。實(shí)現(xiàn)歷史數(shù)據(jù)調(diào)用功能的部分代碼如圖6所示。
圖6 Runnable()方法實(shí)現(xiàn)數(shù)據(jù)回放過(guò)程監(jiān)聽(tīng)
上述步驟中需要調(diào)用到的Java Buffered-Writer()及BufferedReader()方法均帶有緩沖區(qū),可以實(shí)現(xiàn)文本數(shù)據(jù)的多次、高效讀寫。并通過(guò)Hash 算法,數(shù)據(jù)存儲(chǔ)過(guò)程更加安全、快速,從而實(shí)現(xiàn)了數(shù)據(jù)存儲(chǔ)模塊的高效性及可靠性。
以配置數(shù)據(jù)輸出至流量預(yù)測(cè)系統(tǒng)為例,該系統(tǒng)需要通過(guò)UDP 協(xié)議接收自動(dòng)化系統(tǒng)綜合航跡及自動(dòng)化系統(tǒng)報(bào)文數(shù)據(jù)。由于空管綜合數(shù)據(jù)交互平臺(tái)至流量預(yù)測(cè)系統(tǒng)間為單機(jī)通訊,因此采用單播進(jìn)行傳輸通訊。
Java 提供了DatagramSocket 類作為基于UDP協(xié)議的Socket[4],該方法可以實(shí)現(xiàn)UDP 發(fā)送數(shù)據(jù),主要步驟為:①調(diào)用DatagramSocket()方法,創(chuàng)建發(fā)送端Socket 對(duì)象,構(gòu)造數(shù)據(jù)報(bào)套接字并將其綁定到本地主機(jī)上的任何可用端口;②分別創(chuàng)建綜合航跡及報(bào)文數(shù)據(jù)包對(duì)象,該數(shù)據(jù)包寫入待發(fā)送數(shù)據(jù),并調(diào)用DatagramPacke(t)方法,進(jìn)行目的地址及端口號(hào)的數(shù)據(jù)封裝;③調(diào)用Send()方法,通過(guò)udp 的socket 服務(wù)將數(shù)據(jù)包發(fā)送。通過(guò)上述方法,實(shí)現(xiàn)了發(fā)送端的自動(dòng)化系統(tǒng)綜合航跡及報(bào)文數(shù)據(jù)的數(shù)據(jù)封裝和發(fā)送。
線程是進(jìn)程中的實(shí)際運(yùn)作單位,是進(jìn)程的一條流水線,是程序的實(shí)際執(zhí)行者,是最小的執(zhí)行單位。通常在一個(gè)進(jìn)程中可以包含若干個(gè)線程,且一個(gè)進(jìn)程中至少有一個(gè)線程。而進(jìn)程指正在運(yùn)行的程序,是系統(tǒng)進(jìn)行資源分配和調(diào)用的獨(dú)立單位,每一個(gè)進(jìn)程都有它自己的內(nèi)存空間和系統(tǒng)資源。因此,進(jìn)程的創(chuàng)建和銷毀耗費(fèi)大量的系統(tǒng)資源,從而衍生出線程的概念。即允許在一個(gè)進(jìn)程中創(chuàng)建多個(gè)線程,這些線程共享進(jìn)程的資源,并且每個(gè)線程擁有自己獨(dú)立的程序計(jì)數(shù)器、線程局部變量等資源,叫多線程技術(shù)[5]。多線程技術(shù)具有提高進(jìn)程使用率、CPU利用率及數(shù)據(jù)吞吐量等優(yōu)點(diǎn)。
目前,空管綜合數(shù)據(jù)交互平臺(tái)共配置三路數(shù)據(jù),分別輸出至流量預(yù)測(cè)系統(tǒng)、空管復(fù)盤分析系統(tǒng)和QNH 不一致告警系統(tǒng)。Java 內(nèi)置了對(duì)多線程的支持,可以很方便地開(kāi)發(fā)出具備多線程功能,同時(shí)處理多個(gè)任務(wù)的應(yīng)用。多線程技術(shù)實(shí)現(xiàn)數(shù)據(jù)的多路輸出的主要步驟為:①為各路數(shù)據(jù)輸出創(chuàng)建MyThread 類的對(duì)象;②重寫run()方法,即定義該線程輸出數(shù)據(jù)類型及輸出目的地址和端口號(hào);③調(diào)用線程對(duì)象的start()方法啟動(dòng)線程。
由于空管綜合數(shù)據(jù)交互平臺(tái)可對(duì)各路數(shù)據(jù)輸出進(jìn)行開(kāi)關(guān)操作,當(dāng)配置了多條輸出鏈路時(shí),進(jìn)程的創(chuàng)建和銷毀將占用較大資源,影響系統(tǒng)性能。使用Java 的線程池接口,因?yàn)榫€程池具有多重優(yōu)點(diǎn):可減少創(chuàng)建新線程的時(shí)間,提高響應(yīng)速度;重復(fù)利用線程池中線程,不需要每次都創(chuàng)建,降低資源消耗;便于線程管理等。調(diào)用Java newCacheThreadPol(l)方法,創(chuàng)建一個(gè)可緩存的線程池,并提前創(chuàng)建好多個(gè)線程,放入線程池中,使用時(shí)直接獲取,使用完放回池中??梢员苊忸l繁創(chuàng)建銷毀、實(shí)現(xiàn)重復(fù)利用。
上述多線程技術(shù),最終實(shí)現(xiàn)了數(shù)據(jù)輸出模塊的多路輸出,并具有穩(wěn)定性及可靠性。
空管綜合數(shù)據(jù)交互平臺(tái)的人機(jī)界面采用分頁(yè)式界面設(shè)計(jì)[6],總共劃分成數(shù)據(jù)輸入流監(jiān)控、數(shù)據(jù)輸出流監(jiān)控、歷史數(shù)據(jù)查詢(調(diào)用)、日志記錄及配置管理共五大功能頁(yè)。各功能頁(yè)面顯示簡(jiǎn)潔、友好,其中通過(guò)數(shù)據(jù)輸入、輸出流監(jiān)控頁(yè)面可直觀查看到各條鏈路狀態(tài),并可在數(shù)據(jù)輸入、輸出流配置界面對(duì)鏈路進(jìn)行開(kāi)關(guān)或者數(shù)據(jù)源選擇等操作。數(shù)據(jù)輸入流監(jiān)控界面及數(shù)據(jù)輸出流配置界面分別如圖7、圖8所示。
圖7 數(shù)據(jù)輸入流監(jiān)控界面
圖8 數(shù)據(jù)輸出流配置界面
系統(tǒng)的歷史數(shù)據(jù)查詢功能頁(yè)面,可以查詢到各輸入監(jiān)視源的歷史數(shù)據(jù),并可進(jìn)行歷史數(shù)據(jù)導(dǎo)出或調(diào)用輸出操作。而系統(tǒng)的日志記錄功能頁(yè)面可以查詢到歷史告警信息,系統(tǒng)操作日志等內(nèi)容。最后一項(xiàng)管理配置功能頁(yè)面則提供常用告警參數(shù)設(shè)置,歷史數(shù)據(jù)輸出目的地址及端口號(hào)等參數(shù)設(shè)置。
空管綜合數(shù)據(jù)交互平臺(tái)通過(guò)NIO、多線程技術(shù)實(shí)現(xiàn)多路數(shù)據(jù)的輸入及輸出。通過(guò)改進(jìn)型Hash 算法實(shí)現(xiàn)信息的共享性和數(shù)據(jù)封裝性。在系統(tǒng)的實(shí)際應(yīng)用中,技術(shù)維護(hù)人員通過(guò)系統(tǒng)可進(jìn)行本地?cái)?shù)據(jù)的統(tǒng)一管理,數(shù)據(jù)資源的合理規(guī)劃,數(shù)據(jù)應(yīng)用的規(guī)范輸出,提高了技術(shù)維護(hù)部門的工作效率,降低在用系統(tǒng)服務(wù)器的工作壓力。同時(shí),系統(tǒng)采用模塊化設(shè)計(jì),提高了系統(tǒng)的可擴(kuò)展性和可維護(hù)性,為后期本地三級(jí)數(shù)據(jù)中心建設(shè)提供了借鑒經(jīng)驗(yàn);此外,系統(tǒng)還可與分局的自研項(xiàng)目,如:空管復(fù)盤分析系統(tǒng)、雷達(dá)質(zhì)量分析系統(tǒng)進(jìn)行互聯(lián),實(shí)現(xiàn)數(shù)據(jù)回放及數(shù)據(jù)質(zhì)量分析等功能,該系統(tǒng)將在空管單位和地方機(jī)場(chǎng)具有廣泛的應(yīng)用前景。