陳虹宇,胡 術(shù),董志強,李科磊,殷 源
(1.四川大學(xué)計算機學(xué)院,四川 成都 610064;2.四川大學(xué)國家空管自動化系統(tǒng)技術(shù)重點實驗室, 四川 成都 610045;3.空軍裝備研究院雷達與電子對抗所, 北京 100039)
我國成都、西安區(qū)域管制中心引進了西班牙英德拉(Indra)系統(tǒng),該系統(tǒng)配有模擬仿真訓(xùn)練系統(tǒng),使用與真實系統(tǒng)一樣的設(shè)備與人機界面來訓(xùn)練管制人員。Indra系統(tǒng)是目前中國引進的最先進的航管系統(tǒng)?;诒疚奶岢龅姆椒ㄗ灾餮邪l(fā)的系統(tǒng)與Indra配備的模擬仿真訓(xùn)練系統(tǒng)類似,提供了對航空管制員的訓(xùn)練功能。其運行控制需求復(fù)雜,不僅要求提供對多個組別的模擬飛行員席位和模擬管制員的組隊訓(xùn)練,還要求提供對提供服務(wù)的模擬服務(wù)程序均衡地分配計算資源的能力。針對航管仿真訓(xùn)練系統(tǒng)的相關(guān)訓(xùn)練特點,本文設(shè)計并完成了基于航管仿真訓(xùn)練系統(tǒng)的運行控制系統(tǒng)。
航管仿真訓(xùn)練系統(tǒng)是用于培養(yǎng)和提高空中交通區(qū)域及進近雷達管制人員管制技能的主要手段和標(biāo)準(zhǔn)設(shè)備,能夠逼真地模擬包括設(shè)備、用戶界面等所有與訓(xùn)練相關(guān)的對象。通過實時模擬不同空中交通狀態(tài),以提供一個接近真實的工作環(huán)境來訓(xùn)練管制員,并且提供必要的手段完成這一模擬訓(xùn)練過程的準(zhǔn)備、運行、記錄、回放以及評估等。當(dāng)代大型航管仿真訓(xùn)練系統(tǒng)可以同時進行多個組別、不同訓(xùn)練內(nèi)容、科目的訓(xùn)練,其基本組成如圖1所示。該系統(tǒng)均由UNIX操作系統(tǒng)主機構(gòu)成,仿真軟件采用跨平臺設(shè)計,可以運行在Solaris、Linux等主流操作系統(tǒng)上。
Figure 1 ATC simulation training system圖1 航管仿真訓(xùn)練系統(tǒng)組成圖
進行航管模擬訓(xùn)練的基本過程如下:在進行仿真訓(xùn)練時,教員席位準(zhǔn)備訓(xùn)練數(shù)據(jù),將訓(xùn)練數(shù)據(jù)分發(fā)給參訓(xùn)主機后,開啟訓(xùn)練過程,主要完成對參訓(xùn)的模擬機長席位和模擬雷達管制席位的角色指定,完成一個模擬機長席位和一個或多個模擬雷達管制席位的組隊,在模擬訓(xùn)練服務(wù)器中啟動相應(yīng)組別的多個模擬服務(wù)進程。圖1中,模擬機長P1和模擬雷達管制席位R1和R2組成第一組,通過和模擬訓(xùn)練服務(wù)器交互完成第一組模擬訓(xùn)練任務(wù)。模擬訓(xùn)練服務(wù)器集群中部署相同的進程,可以同時運行一組或多組訓(xùn)練服務(wù)程序,為各組模擬機長和模擬雷達管制席位的運行提供支撐。教員席位通過啟動訓(xùn)練服務(wù)進程、模擬機長和模擬管制員席位完成訓(xùn)練組的開啟,在訓(xùn)練完成后退出相應(yīng)的訓(xùn)練組進程。
為了簡化系統(tǒng)的部署,系統(tǒng)設(shè)計時各訓(xùn)練組的主機(含模擬訓(xùn)練服務(wù)器、模擬機長和模擬管制員席位)均部署一樣的進程,只在運行前由教員席位先進行訓(xùn)練數(shù)據(jù)準(zhǔn)備,然后將不同訓(xùn)練組的訓(xùn)練數(shù)據(jù)按組分發(fā)到參訓(xùn)主機的train_num(即訓(xùn)練組號)目錄下,然后用命令行參數(shù)-Tnum(num為訓(xùn)練組號)啟動訓(xùn)練的各進程,進程通過讀取相應(yīng)的訓(xùn)練數(shù)據(jù)目錄運行不同訓(xùn)練組。
從以上需求來看,大型航管仿真訓(xùn)練系統(tǒng)對運行控制提出了較高的要求,需合理地調(diào)度模擬訓(xùn)練服務(wù)器的計算資源,靈活地組合訓(xùn)練組教員和模擬雷達主機,安全地啟動和退出訓(xùn)練組。
運行控制最基本的要求是對組成訓(xùn)練組的各進程的啟動、停止進行準(zhǔn)確的控制,并且監(jiān)控其運行狀態(tài)。為此,設(shè)計在系統(tǒng)每個主機上部署Agent代理進程,通過教員席位負責(zé)運行調(diào)度的調(diào)度模塊Scheduler對不同主機Agent發(fā)出相應(yīng)的啟動、關(guān)閉命令,完成訓(xùn)練組的運行控制。
為了(1)在模擬訓(xùn)練服務(wù)器中均衡運行不同訓(xùn)練組進程;(2)在不同席位中按模擬飛行員、模擬管制員的不同角色啟動進程,航管模擬訓(xùn)練系統(tǒng)中進程以組作為調(diào)度的最小粒度。圖2為三組訓(xùn)練服務(wù)進程通過三臺模擬訓(xùn)練服務(wù)器為五個訓(xùn)練組提供服務(wù)的實例圖。不同進程組的運行情況,用二元組〈進程組編號/訓(xùn)練組編號〉對應(yīng)一個實際運行的進程組,被稱為訓(xùn)練進程組。
Figure 2 Distribution of process group and training group in services clusters圖2 服務(wù)集群中進程組與訓(xùn)練組的分布
進程組運行控制的基礎(chǔ)是通過Agent實現(xiàn)對組內(nèi)進程進行啟動和退出的操作。通過一個進程對其他進程進行啟動有多種方式,系統(tǒng)實驗了三種啟動方式:
(1)以fork+子進程中exec方式將進程作為Agent的子進程啟動[1],啟動后立即獲得被啟動進程的pid,后續(xù)可使用kill(pid,0)方式檢查進程是否在運行。該方式的缺點是:①子進程將繼承父進程Agent的諸多運行環(huán)境,如打開的文件描述符、控制終端、信息輸出終端等,使父、子進程的輸出將打印在同一個終端,因而無法分辨;②可能導(dǎo)致出現(xiàn)僵死進程,耗費系統(tǒng)資源。
(2)改進上述方法采用兩次fork,可避免僵死進程的出現(xiàn)[2]。但是,該方法:①具有方法(1)中描述的①同樣的缺點;②對使用shell腳本啟動而在退出時使用實際運行pid進行管理的進程(如Java進程),該方法不能處理;③對啟動后立即異常退出的進程,雖然在啟動時就獲取了pid,但由于該進程沒有穩(wěn)定運行,可能會對Agent的狀態(tài)判斷產(chǎn)生短暫的負面影響。
(3)使用 system()啟動。system()函數(shù)執(zhí)行了三步操作:①system()通過調(diào)用fork()由當(dāng)前終端窗口的shell產(chǎn)生子進程;②子進程則調(diào)用execl()來啟動一個全新的程序;③在父進程中調(diào)用waitpid()等待子進程結(jié)束。在調(diào)用system()期間SIGCHLD 信號會被暫時擱置,SIGINT和SIGQUIT 信號則會被忽略[3]。system()方式的另一個好處是可以衍生執(zhí)行多種啟動方式,如在某個終端中執(zhí)行進程(如Linux環(huán)境下的終端仿真程序Gnome Terminal)等。這種方式的缺點是不能立即獲得被啟動進程的pid,需要使用進程定位技術(shù)獲得pid。
目前主要基于第三種方式,為了更好地適應(yīng)進程組運行控制的多樣化需求,也提供了其他幾種方式。
在使用system()啟動時,既可以將子進程的控制臺輸出與父進程的控制臺輸出在一起,也可以啟動一個終端窗口,將子進程的輸出輸出到該窗口;但是,該方法在啟動時無法立即獲取被啟動進程的pid。本系統(tǒng)采用的策略是,在system()啟動后的適應(yīng)性時間(一般是該進程完成必要的初始化并開始穩(wěn)定運行)后,使用與操作系統(tǒng)平臺相關(guān)的進程定位方法獲取進程pid[4]。如在Linux系統(tǒng)下,訪問/proc的虛擬文件系統(tǒng),/proc下以數(shù)字命名的子目錄是進程目錄,通過進程pid來訪問該子目錄,查看子目錄中名為cmdline的文件,可以獲得相關(guān)進程的啟動時間、用戶時間、系統(tǒng)時間等。
在指定訓(xùn)練組關(guān)閉時,各主機需要安全退出該訓(xùn)練組的相關(guān)進程,傳統(tǒng)的做法是由Agent調(diào)用kill()函數(shù)對進程發(fā)出SIGKILL(值為9)信號。但是,在模擬訓(xùn)練服務(wù)器中,如模擬仿真核心需要在退出時將訓(xùn)練過程中生成的評估信息等存入數(shù)據(jù)庫,如果強行退出將導(dǎo)致數(shù)據(jù)丟失。本系統(tǒng)可對進程的退出方式進行配置,對于需要保存數(shù)據(jù)的進程,先發(fā)出SIGTERM(值為15)信號等待適應(yīng)性時間后,如該進程仍未退出,才最后對其發(fā)出SIGKILL信號[2]強制退出。
除了訓(xùn)練組相關(guān)的應(yīng)用進程外,模擬訓(xùn)練系統(tǒng)中有一些進程需要長時間運行,直到系統(tǒng)完全關(guān)機。這類進程包括:基于NTP協(xié)議的對時進程、打印服務(wù)進程、消息中間件、集群管理進程、訓(xùn)練日志進程、系統(tǒng)監(jiān)控進程等。這些進程可以放在Agent啟動前運行,完成主機對時、初始化打印隊列等系統(tǒng)的環(huán)境準(zhǔn)備工作。如Agent在啟動后發(fā)現(xiàn)這些進程沒有啟動,將首先啟動這些進程。本系統(tǒng)將這些進程按主機分成不同的服務(wù)進程組,并由Agent確保其連續(xù)運行,當(dāng)這些進程發(fā)生異常退出時,將自動重啟該進程,以保證服務(wù)提供的持續(xù)性。
Agent進程通過網(wǎng)絡(luò)接收教員席Scheduler模塊發(fā)出的基本運行控制命令,這些命令包括:關(guān)閉全系統(tǒng)主機、停止全系統(tǒng)運行、啟動本機指定進程組、退出本機指定進程組、對運行時異常退出的進程執(zhí)行重啟操作、按默認方式啟動進程組以及關(guān)閉指定進程等?;谶M程的運行控制要求,Agent應(yīng)具有按照命令啟動、退出、管理一臺主機上一個或多個訓(xùn)練進程組的功能。Agent采用了劃分命令隊列、啟動隊列、重啟隊列和退出隊列的管理方式實現(xiàn)了復(fù)雜的運行控制。每個隊列設(shè)置一個定時器驅(qū)動,每秒鐘輪詢隊列一次,執(zhí)行控制命令。
命令隊列接收教員席Scheduler模塊傳入的控制報文并解析命令。解析命令后,根據(jù)其類型,最終將其加入啟動隊列、重啟隊列,或是退出隊列中執(zhí)行。由于命令的執(zhí)行要耗費一定的時間,驅(qū)動器每次只從隊首取出一條命令,待這條命令執(zhí)行完畢后將其從隊列中刪除。
5.1.1 優(yōu)先級劃分
命令隊列區(qū)分了各種命令的優(yōu)先順序,為每個命令定義了不同的優(yōu)先級及不同的處理函數(shù)。命令優(yōu)先級PRI_MODE如下所示,其中優(yōu)先級越高,數(shù)值越低。
enum PRI_MODE
EM_SHUTDOWN= 1,∥關(guān)機命令
EM_CLOSE_ALL_PROC= 2,∥關(guān)閉所有進程
EM_CLOSE_SVR_PROC= 3,/*關(guān)閉所有服務(wù)進程 */
EM_CLOSE_APP_PROC= 4,/*關(guān)閉所有應(yīng)用進程*/
EM_START_DEFAULT_PROC= 5,/*啟動默認進程*/
EM_CLOSE_PROC= 6,∥關(guān)閉某應(yīng)用進程
EM_START_PROC= 7,∥開啟某應(yīng)用進程
升壓調(diào)節(jié)器采用的是SP6641B,它具有很高的電池轉(zhuǎn)換效率能夠滿足多個設(shè)備的電力供應(yīng),而且還具有極低的靜態(tài)電流。
};
Figure 3 Flow chart of process management 圖3 進程管理流程圖
引入優(yōu)先級主要是為了避免如下情況的發(fā)生:教員席位可以不斷發(fā)出各種運行操作命令,這些命令的執(zhí)行和完成都需花費一定時間,在這個時間里如果教員席位不斷惡意地發(fā)出命令,則系統(tǒng)有可能會不斷關(guān)閉和啟動,影響系統(tǒng)穩(wěn)定性。所以,Agent收到命令后, 應(yīng)先根據(jù)命令報文的類型及當(dāng)前隊列中命令,判斷是將新命令加入命令隊列,還是忽略這個命令。對PRI_MODE中的前四種命令,處理規(guī)則為:(1)當(dāng)前沒有要執(zhí)行的命令,直接將新命令加入到命令隊列;(2)當(dāng)這些命令加入時,刪除所有低優(yōu)先級命令;(3)當(dāng)這些命令加入時如果有更高優(yōu)先級命令存在,則放棄加入。這樣能讓教員在系統(tǒng)完全退出、就緒的狀態(tài)下進行下一個系統(tǒng)級操作。而后三種命令的判斷規(guī)則為:(1)當(dāng)前沒有要執(zhí)行的命令,直接將新命令加入到命令隊列;(2)當(dāng)前有正在執(zhí)行的命令,新命令的類型是啟動默認進程,若新命令的優(yōu)先級最高,則新命令加入隊列中,但不刪除隊列之前的命令;(3)當(dāng)前有正在執(zhí)行的命令,新命令的類型是關(guān)閉某應(yīng)用進程,若新命令的優(yōu)先級最高,則新命令加入隊列中,并且刪除當(dāng)前命令隊列中對同一組進程的啟動命令,但不刪除隊列之前的其他命令;(4)當(dāng)前有正在執(zhí)行的命令,新命令的類型是啟動某應(yīng)用進程,若命令隊列中存在關(guān)機命令、關(guān)閉所有進程的命令,則忽略新命令,否則,將其加入隊列。
5.1.2 進程信息管理
由于命令隊列在執(zhí)行命令時,將命令中涉及到的進程交付給了其他三個隊列,故其本身并不知道進程的執(zhí)行結(jié)果,因此把進程劃分為九種狀態(tài)。各隊列根據(jù)進程的執(zhí)行情況,調(diào)整進程的狀態(tài)。例如,進程暫時不能被加入到啟動隊列中(一種情況是,需等到退出隊列中的進程全部退出后,進程才能加入啟動隊列),這時進程被設(shè)置為PS_TOSTART狀態(tài);在進程成功加入啟動隊列后,進程被設(shè)置為PS_INSTART狀態(tài);啟動隊列中的進程成功啟動后,又被設(shè)置為PS_RUNNING狀態(tài)。圖3簡要描述了進程在啟動列表、重啟列表及退出列表中的轉(zhuǎn)換過程。
進程狀態(tài)PROC_STATE如下所示:
enum PROC_STATE
{
PS_NONE= 1,∥初始化狀態(tài)
PS_INSTART= 2,∥在啟動隊列中
PS_TOSTART= 3,∥要加入到啟動隊列
PS_STARTING= 4,∥正在啟動
PS_RUNNING= 5,∥運行中
PS_TOEXIT= 6,∥要加入到退出隊列
PS_STOPPED= 7,∥已經(jīng)停止
PS_INEXIT= 8,∥在退出隊列中
PS_TERMING= 9∥正在停止
};
除了進程狀態(tài)的設(shè)置外,系統(tǒng)還設(shè)計了專門的進程管理器。進程管理器存儲了Agent系統(tǒng)中所有服務(wù)進程和應(yīng)用進程的最新信息,包括進程狀態(tài)信息。因此每次進程狀態(tài)發(fā)生變化時,都要及時修改進程管理器中相關(guān)信息。通過定時器驅(qū)動定時檢查所有應(yīng)用進程的狀態(tài),對已經(jīng)退出的進程,將其從進程管理器中刪除;對等待啟動和等待關(guān)閉進程,將其加入到啟動或退出隊列中。由于運行中的進程可能會發(fā)生異常終止的情況,進程管理器將正常退出的進程標(biāo)記為KILLED(數(shù)值1),異常退出的進程的標(biāo)記為UNKILLED(數(shù)值0)。通過查看進程退出標(biāo)記的值及檢測進程是否還在運行中,來判斷進程有無異常終止。對異常終止的進程,進程管理器將其加入到重啟列表中重新啟動。
啟動隊列接收命令隊列和進程管理器的進程啟動請求,將待啟動進程加入到隊列中。與命令隊列不同,啟動隊列一次處理完所有到來的請求,而不是逐一處理。啟動和重啟隊列中的進程狀態(tài)只能是INSTART和TOSTART兩者之一,啟動成功的進程狀態(tài)修改為PS_RUNNING,并從該隊列中移除。進程執(zhí)行啟動動作后,若超過了60秒仍未啟動成功,則將進程加入到重啟隊列中等待下一次啟動,同時從啟動隊列中刪除。啟動隊列和重啟隊列中的進程要求無重復(fù);同時,啟動進程之前需判斷進程的存活狀態(tài),使用kill(pid,0)得到進程是否已經(jīng)在運行,確保不會再次啟動已經(jīng)在運行的進程。
由于Agent支持在一臺主機上進行不同訓(xùn)練組的切換功能,如席位主機從模擬飛行員切換為模擬雷達管制席位,這樣在啟動新進程組時,若本機上前一組進程仍然在運行,需要進行進程組的切換。進程組的切換要求先將前一個訓(xùn)練組的進程加入退出隊列并殺死,再將待啟動的新訓(xùn)練組進程加入啟動隊列進行啟動。因此,在命令隊列將待啟動進程加入啟動隊列之前,需保證退出隊列的穩(wěn)定態(tài)(即待退出的進程已經(jīng)全部殺死)。如果退出隊列是非穩(wěn)定態(tài),則通過定時器驅(qū)動不斷檢測其狀態(tài),直到達到穩(wěn)定態(tài),才能將待啟動進程加入啟動隊列中。
命令隊列處理退出進程組、退出進程、全系統(tǒng)關(guān)閉、訓(xùn)練組切換等命令時,需要殺死一個或多個進程,所有待殺死的進程被放入到退出隊列中。Agent提供了兩種殺死進程的方式:一種基于SIGKILL信號,一種基于SIGTERM信號。由于SIGTERM信號不能立即殺死進程[2],故設(shè)置超時時間用于判斷SIGTERM是否超時。超時后,使用SIGKILL信號立即殺死進程。在對進程發(fā)出SIGTERM信號后,該進程繼續(xù)保留在退出隊列中,同時記錄下SIGTERM信號的發(fā)出時間,進程狀態(tài)也由PS_INEXIT變?yōu)镻S_TERMING。退出隊列的定時器輪詢隊列時,若檢查到狀態(tài)為PS_TERMING的進程在超時時間之內(nèi)死亡,則將其從退出隊列中移除;若檢查到該進程已經(jīng)超時卻仍然存活,則對該進程發(fā)出SIGKILL信號,強制殺死進程并將該進程移出退出列表。與啟動隊列類似,對退出隊列中進程發(fā)出殺死信號之前,也要判斷其存活狀態(tài),避免對已死亡進程的不必要操作。
當(dāng)采用進程定位方式管理進程時,如果對操作系統(tǒng)中所有的進程進行定時的輪詢,會導(dǎo)致Agent的CPU占用率增高。為了減少Agent的CPU占用率,可以采用將驅(qū)動器運行時間間隔加長的方法,但這樣會降低進程檢測的靈敏度。經(jīng)過優(yōu)化的Agent設(shè)計為:在上述四個隊列均為空時(這是實際系統(tǒng)運行時大部分時間的狀態(tài)),將這種狀態(tài)定義為系統(tǒng)穩(wěn)定態(tài),只對被進程管理器管理的進程用kill(pid, 0)進行存活的判斷,該方法有效降低了CPU占用率。
系統(tǒng)中各主機的Agent定時向Scheduler模塊發(fā)送訓(xùn)練組的信息和狀態(tài),每秒鐘更新一次。更新的信息包括:發(fā)送主機、是否處于穩(wěn)定態(tài)、當(dāng)前CPU使用率、當(dāng)前主機運行了的分組數(shù)目、當(dāng)前本機上運行的分組分別是哪些等。這個報文只在Agent處于穩(wěn)定狀態(tài)的時候進行發(fā)送,如果主機目前狀態(tài)不穩(wěn)定,則會選擇發(fā)送上一次穩(wěn)定態(tài)的信息;同時,指示當(dāng)前的主機狀態(tài)為不穩(wěn)定,以便Scheduler暫時不使用這些信息進行進程組的啟動。Scheduler在啟動后和運行中如果發(fā)現(xiàn)某個訓(xùn)練組發(fā)生組缺失導(dǎo)致該訓(xùn)練組不能正常運行,將選擇在某個訓(xùn)練服務(wù)器上重啟該缺失的訓(xùn)練進程組。圖4是對Agent與Scheduler關(guān)系的簡單描述。
Figure 4 Flow chart of scheduler processing 圖4 Scheduler處理流程圖
對于運行于模擬仿真服務(wù)器上的各進程組,Scheduler在:(1)存在進程異常退出;(2)某臺服務(wù)器CPU占用率高于閾值;(3)訓(xùn)練組啟動后需要對當(dāng)前的服務(wù)器運行的訓(xùn)練服務(wù)進程組在多個服務(wù)器間進行調(diào)度,盡可能保持各航管模擬訓(xùn)練服務(wù)器的CPU負載均衡。Scheduler在負載均衡算法運算后根據(jù)結(jié)果執(zhí)行調(diào)度動作,目前執(zhí)行調(diào)度切換的時間為3秒,可以滿足系統(tǒng)的需要。
Scheduler采用如下方法進行調(diào)度[5~8]:
(1)接收Agent報告的各訓(xùn)練服務(wù)器中各進程的CPU占用率,并得到以進程組為單位的CPU占用率,本系統(tǒng)中使用的占用率為小數(shù)點以后兩位。
(2)檢查各服務(wù)器CPU占用率是否存在較大的差值,如果存在則進行負載均衡動作即進入第三步。
(3)定義一個系統(tǒng)中不可能出現(xiàn)的單機最大負載值MAX_LOAD,當(dāng)系統(tǒng)滿足了進行負載均衡切換的條件后,首先在集群系統(tǒng)中查找當(dāng)前負載小于參數(shù)所指定負載(MAX_LOAD)的服務(wù)器中的最高負載的服務(wù)器,由它們組成一個“最高負載服務(wù)器鏈表”,然后依次遍歷鏈表的每個服務(wù)器上的進程組。假設(shè)某最高負載服務(wù)器上運行的第T個訓(xùn)練組的第N號進程組,于是在當(dāng)前運行的服務(wù)器組中查找具有最低負載的服務(wù)器。如果找到則計算兩臺服務(wù)器切換前后的負載差值,如果切換后的差值小于切換前的則說明切換后負載更趨向均衡,那么將該進程放入進行切換的隊列中,依此類推,直至遍歷完該主機上的所有進程組為止。如果在該主機的遍歷過程中發(fā)生了進程組的變化,那么則跳出對“最高負載服務(wù)器鏈表”的循環(huán),因為由于發(fā)生了切換,所以此時在最高負載服務(wù)器鏈表中的服務(wù)器負載總和可能已經(jīng)不再是系統(tǒng)中的最高負載了,因此重新進行處理,進入下一次遞歸,此時傳遞的參數(shù)仍然是MAX_LOAD,直至遍歷完所有最高負載主機上的進程組。如果遍歷完成而沒有發(fā)生切換,那么就將此時系統(tǒng)中的最高負載總值作為參數(shù)傳遞到下一次遞歸運算中。遞歸的終點是:在服務(wù)器組中再也找不到具有比傳入?yún)?shù)更小的負載總值的服務(wù)器了。此刻訓(xùn)練服務(wù)器組中各主機的負載達到了最大程度的平衡。圖5作為算法流程圖詳細描述了這一步的算法流程與步驟。
在推選出各服務(wù)器要進行切換的服務(wù)器進程組以后,Scheduler會通知這些進程組完成進程運行狀態(tài)檢查點的保存,并使用調(diào)用各服務(wù)器Agent完成檢查點信息到目標(biāo)服務(wù)器的傳輸,在狀態(tài)完成傳遞以后,統(tǒng)一發(fā)起進程組在目標(biāo)機的啟動工作。在進程組跨主機遷移的過程中,Scheduler對外部對集群的控制命令不予處理,對于Agent心跳報文也只記錄收到的時間,這樣做的目的是為了避免切換過程中引起新的調(diào)度。
Figure 5 Flow chart of training server load balancing algorithm圖5 訓(xùn)練服務(wù)器負載均衡算法流程圖
如4.1節(jié)的方法一所述,以fork+子進程中exec方式將進程作為Agent的子進程啟動的方式可能導(dǎo)致出現(xiàn)僵死進程。當(dāng)子進程終止時,它釋放資源,并且發(fā)送SIGCHLD信號通知父進程。父進程接收SIGCHLD信號,返回子進程的狀態(tài),并且釋放系統(tǒng)進程表資源。如果子進程先于父進程終止,而父進程fork()之前既沒有按照SIGCHLD信號調(diào)用處理函數(shù)waitpid()等待子進程結(jié)束,又沒有顯式忽略該信號,則子進程成為僵死進程,無法正常結(jié)束。此時即使是以超級用戶身份調(diào)用kill-9命令也不能殺死僵死進程。直到其父進程結(jié)束,子線程成為孤兒進程,由守護進程init領(lǐng)養(yǎng)孤兒進程,當(dāng)孤兒進程結(jié)束時init為其釋放進程表資源。
實現(xiàn)系統(tǒng)時發(fā)現(xiàn),即使處理了SIGCHILD信號,調(diào)用waitpid()等待子進程結(jié)束,當(dāng)被關(guān)閉進程組的進程過多時,如達到幾十個,由于UNIX系統(tǒng)對同一信號沒有排隊機制,總有幾個子進程無法正常關(guān)閉,出現(xiàn)僵死進程。不僅耗費系統(tǒng)資源,也可能因為僵死進程沒有釋放系統(tǒng)資源,如網(wǎng)絡(luò)通訊的文件描述符綁定的網(wǎng)絡(luò)端口,導(dǎo)致同一進程無法再次啟動,給系統(tǒng)的進程管理帶來很大麻煩。經(jīng)過多次嘗試新方法,最終4.1節(jié)的方法三良好地適應(yīng)了系統(tǒng)進程組控制管理的需求。
以上介紹了基于代理的航管仿真訓(xùn)練系統(tǒng)運行控制的設(shè)計與實現(xiàn),通過對命令隊列、啟動隊列、重啟隊列和退出隊列的設(shè)計,通過對收到的命令按優(yōu)先級進行處理,配合負載均衡算法,有效處理了航管訓(xùn)練系統(tǒng)中運行控制的問題,也實現(xiàn)了對進程運行狀態(tài)信息的監(jiān)控。
在航管仿真訓(xùn)練系統(tǒng)的后續(xù)研發(fā)中,隨著訓(xùn)練功能的日益豐富,對基于代理的運行控制提出了更多的要求,其XML表述的配置內(nèi)容更加豐富,對于命令的處理也由單純的依靠優(yōu)先級判斷變?yōu)榛谟邢逘顟B(tài)機進行命令和運行狀態(tài)轉(zhuǎn)換,系統(tǒng)功能日益完善和提升。
[1] Ferber J, Gutknecht O. A meta-model for the analysis and design of organization in multi-agent systems[C]∥Proc of the 3rd International Conference on Multi-Agent Systems (ICMAS’98), 1998:258-266.
[2] Raymond E S. The art of Unix programming[M]. 2nd edition. Beijing:Electronic Industry Press, 2006.(in Chinese)
[3] Stevens W R. Advanced programming in the Unix environment[M]. Beijing:Posts & Telecom Press, 2000.(in Chinese)
[4] Stevens W R. Unix network programming volume 2:Interprocess communications[M]. Beijing:Posts & Telecom Press, 2010.(in Chinese)
[5] Lin Jun-xuan, Hu Shu. System and process information access in tru64 Unix server[J]. Computer Applications, 2006, 26(z2):316-318.(in Chinese)
[6] Forrest S,Hofmeyr S A,Somayaji A,et al.A sense of self for Unix processes[C]∥Proc of the 1996 IEEE Symposium on Security and Privacy, 1996:120-128.(in Chinese)
[7] Xiang Jian-jun, Bai Xin, Zuo Ji-zhang. A multipletask load balancing algorithm used in real-time cluster system[J]. Computer Engineering, 2003, 29(12):36-38.(in Chinese)
[8] Sekar R, Venkatakrishnan V N. One-way isolation:An effective approach for realizing safe execution environments[C]
∥Proc of the ISOC Network and Distributed Systems Symposium, 2005:265-278.(in Chinese)
[9] Bass L, Clements P C, Kazman R. Software architecture in practice[M].2nd ed. Beijing:Tsinghua University Press, 2003.(in Chinese)
附中文參考文獻:
[2] Raymond E S. UNIX編程藝術(shù)[M]. 第二版.北京:電子工業(yè)出版社,2006.
[3] Stevens W R. UNIX高級環(huán)境編程[M].第二版.北京:人民郵電出版社,2000.
[4] Stevens W R. UNIX網(wǎng)絡(luò)編程(卷二)進程間通信[M]. 北京:人民郵電出版社,2010.
[5] 林俊萱,胡術(shù).Tru64 Unix服務(wù)器中系統(tǒng)及進程信息的獲取方法[J]. 計算機應(yīng)用,2006, 26(z2):316-318.
[6] Forrest S,Hofmeyr S A,Somayaji A,等.自我感覺UNIX進程[C]∥ IEEE計算機學(xué)會安全與隱私研討會, 1996:120-128.
[7] 向建軍,白欣,左繼章.一種用于實時集群的多任務(wù)負載均衡算法[J]. 計算機工程,2003, 29(12):36-38.
[8] Sekar R, Venkatakrishnan V N. 單向隔離:實現(xiàn)安全的執(zhí)行環(huán)境的有效途徑[C]∥國際互聯(lián)網(wǎng)協(xié)會網(wǎng)絡(luò)與分布式系統(tǒng)安全座談會, 2005:265-278.
[9] Bass L, Clements P C, Kazman R.軟件構(gòu)架實踐[M].第二版.北京:清華大學(xué)出版社,2003.