黃繼杰,林昌年,楊選懷,王蘭香,王國平
(北京科東電力控制系統(tǒng)有限責任公司,北京 100192)
分布式仿真標準IEEE1516基于面向對象技術提出了高層體系架構(HLA)。為了適應面向服務的仿真環(huán)境,IEEE1516-2010版對HLA進行了許多擴展[1-2],并采用WSPRC組件(Web services provider RTI component)技術使HLA/RTI能支持Web環(huán)境下的仿真[3-4]。云計算技術的蓬勃發(fā)展使仿真資源得到更高層次的共享,因而“云仿真”將是未來分布仿真的主要研究方向[5-6]。文獻[7]研究了云仿真技術與HLA Evolved技術進行綜合的問題,采用的技術手段還是對HLA進行擴展。
隨著虛擬化技術的快速發(fā)展,出現(xiàn)了虛擬化容器技術(如Docker[8-9]),并且使基于單體式軟件架構的SaaS層云服務可拆分為許多微服務[10]?;贒ocker和微服務來部署私有云[11]就可采用一臺高性能的服務器,根據(jù)仿真任務的需要啟動Docker容器,并將仿真模型微服務部署其中[12]。這種虛擬化和微服務技術使得HLA與面向服務技術能更好地結合。
HLA的對象模板類(OMT)是其支持聯(lián)邦成員交互的基礎。文中先利用OMT的對象屬性來定義仿真模型微服務的特殊標志及相關信息,并在RTI實現(xiàn)中,當遇到對象屬性名為仿真模型微服務的特殊標志時,由RTI來負責完成對模型微服務的訪問。
隨著虛擬化容器技術的興起,產(chǎn)生了微服務,比如現(xiàn)在非常通用的Docker容器。Docker與虛擬機不同,Docker容器并不是一套硬件虛擬化方案,而是一個操作系統(tǒng)級別的虛擬化技術,僅為應用提供一套隔離的運行時虛擬環(huán)境,而不是整個虛擬的硬件資源。Docker是以容器為資源分割和調(diào)度的基本單元和調(diào)度單位,封裝了整個服務運行時的環(huán)境,用于構建、發(fā)布和運行分布式應用的平臺。它使用Linux內(nèi)核提供的LXC技術實現(xiàn)類似虛擬機的功能,以更節(jié)省的方式利用硬件資源,提供用戶更多更高效的計算資源服務。
在Docker內(nèi)部署的微服務改變了軟件架構模式,使軟件架構從單體式轉向了微服務的架構模式。單體式軟件架構也稱為集中式軟件體系架構,是指所有的功能在一個應用中,各個模塊之間通過相互調(diào)用的方式交互。單體式軟件架構具有以下不足:維護和擴展困難;難于持續(xù)部署;應用伸縮性差和可靠性低。因此,在云平臺中這種單體式架構如今正開始被最新的微服務架構逐漸取代。
微服務軟件架構被定義為:“開發(fā)單個服務組件作為一系列應用的套件,其中每個服務可以使用不同的編程語言實現(xiàn),以及不同的存儲技術獨立運行在自己的進程空間中,圍繞著業(yè)務功能而構建,可通過完全獨立的自動化部署機制進行構建和部署,實現(xiàn)去中心化服務、集中式管理最小化,各個服務之間通過輕量級機制實現(xiàn)通信”。微服務具有以下特點:彼此獨立;原子化;組合和重構?;谖⒎臻_發(fā)的系統(tǒng)其所有的個體由于在概念上是對等的,結構相對模塊化、簡單化,因此具有松散耦合的特點,構成的系統(tǒng)具有更強的可擴展性和魯棒性。
HLA基于OMT來實現(xiàn)聯(lián)邦成員間的數(shù)據(jù)交互,其中對象屬性更新是最常用的方式。而對象屬性的計算常常通過調(diào)用模型的接口來獲得。由于微服務軟件架構相比單體架構具有優(yōu)勢,用于計算對象屬性的模型接口越來越多地采用微服務的接口。在私有云內(nèi)的微服務環(huán)境下進行分布交互仿真一般采用圖1左側的方式,即聯(lián)邦成員先調(diào)用私有云內(nèi)的模型微服務計算對象屬性,再將對象屬性的更新值通過私有云內(nèi)的RTI服務發(fā)布到其他聯(lián)邦成員。
圖1 RTI支持微服務的通信架構
當設計FOM/SOM時,將聯(lián)邦成員計算對象屬性的輸入?yún)?shù)和輸出參數(shù)加入到OMT中,以此代替該原對象需要更新的屬性,其發(fā)布過程如圖1右所示[13]。由于模型服務和RTI服務都位于私有云服務器,而服務器內(nèi)部進程間的通信速度高于局域網(wǎng)中機器間的進程通信速度,故圖1右所示的數(shù)據(jù)交互速度比左圖所表示的更快。
設計OMT時可以像文獻[14]一樣,在OMT具體的FED文件中增加關鍵詞來標示此對象需要RTI訪問的微服務??紤]到與IEEE1516現(xiàn)有標準的一致性,利用對象類名加“_microService”字段來通知RTI,由它先調(diào)用微服務更新對象屬性,再查閱訂購者并將更新值發(fā)給它。以學生對象類(Class Student)為例[15],假設它包含三個屬性(LunchMoney,AmmoAmount和Cleanliness),并通過CalculateStudent函數(shù)來重新計算(LunchMoney,AmmoAmount和Cleanliness )這三個屬性?,F(xiàn)將CalculateStudent函數(shù)封裝為微服務的接口,接口參數(shù)包括代表這三個屬性的輸入和輸出,此外還包括微服務的地址。為此,將學生類對象(新類名為Student_microService)重定義為七個屬性(addr_CalculateStudent,in_LunchMoney,in_AmmoAmount,in_Cleanliness,out_LunchMoney,out_AmmoAmount,out_Cleanliness)。RTI在調(diào)完微服務后將原來數(shù)據(jù)分發(fā)的處理量由(LunchMoney,AmmoAmount和Cleanliness )轉向其中的(out_LunchMoney,out_AmmoAmount和out_Cleanliness)這三個屬性,并可用這三個輸出屬性過濾基于HLA的區(qū)域。OMT中命名統(tǒng)一規(guī)定為:前綴“addr_”表示接口地址,“in_”表示輸入?yún)?shù)屬性,“out_”表示輸出參數(shù)屬性。
在開源CERTI源碼的基礎上進行RTI服務端的修改[16],涉及到對象聲明管理和對象管理兩部分。RTI服務端在處理對象聲明管理時,需要嵌入對類名稱的判斷,若類名字后部包含“_microService”,則該對象類的實例需要由RTI服務端調(diào)用微服務來計算各對象的屬性并完成發(fā)布和訂閱功能。處理流程如圖2所示。
圖2 RTI支持微服務的處理流程
圖2中,當判斷為“否”時,程序流程走的是原RTI服務處理流程;當判斷為“是”時,先設置需調(diào)用微服務接口的標志,然后查看屬性名的前綴是否包含“in_”和“out_”,若包含“in_”為該屬性的輸入?yún)?shù),若包含“out_”為該屬性的輸出參數(shù)。對微服務接口地址參數(shù),通過查看是否包含前綴“addr_”來獲得,如學生對象類所調(diào)的微服務接口,其屬性為:“addr_CalculateStudent”。
在后面的學生對象更新其屬性時,屬性“addr_CalculateStudent”所對應的值由微服務的配置文件和此接口的名構成,如“exchange.inf@startPower Exchange”,其中exchange.inf是配置文件,startPowerExchange是接口名。
RTI實現(xiàn)中將屬性映射為屬性句柄,通過(句柄值和屬性值)來打包傳輸數(shù)據(jù);對于接口的參數(shù)名也需要與屬性的句柄值相關聯(lián)。為此,輸入?yún)?shù)屬性在RTI解析FOM/SOM時會將屬性名映射為屬性句柄,且RTI在分配屬性句柄時是按自動遞增順序來計算句柄值的。故按微服務接口參數(shù)的順序依次定義FOM/SOM中的訪問該微服務的對象類的屬性,則參數(shù)值、屬性句柄值和屬性值是一一對應的關系。RTI在調(diào)用該接口時,先獲得該接口的全部參數(shù),并按對應的屬性句柄大小進行屬性值排隊,從而按此順序將屬性值作為參數(shù)來調(diào)用對應的微服務接口。
同樣,對于輸出參數(shù)屬性,同樣需要此微服務接口在計算完后按輸入?yún)?shù)的順序進行數(shù)據(jù)打包。包格式為:4字節(jié)參數(shù)個數(shù),第一個參數(shù)字節(jié)長度,第一個參數(shù)內(nèi)容,第二個參數(shù)長度,第二個參數(shù)內(nèi)容,以此類推。當RTI服務端調(diào)用此微服務接口后,對獲得的返回值進行上述格式的解包,并按輸出參數(shù)屬性句柄的大小依次賦值給各輸出參數(shù)屬性。
由于只有輸出參數(shù)屬性是需要在聯(lián)邦間交互的值,故對于對象類的訂購處理流程按CERTI的原代碼處理,包括數(shù)據(jù)分發(fā)的區(qū)域過濾也按CERTI的原代碼處理。
當私有云中的微服務支持同一用戶多次訪問時,微服務可采用SaaS的多租戶技術。多租戶技術的實現(xiàn)重點在于不同租戶間應用程序環(huán)境的隔離(application context isolation)以及數(shù)據(jù)的隔離(data isolation),以維持不同租戶間應用程序不會相互干擾,同時數(shù)據(jù)的保密性也夠強。
與訪問微服務的租戶所對應的是RTI中的聯(lián)邦執(zhí)行號、聯(lián)邦成員號和對象實例句柄號[17]。當RTI服務重啟后,RTI服務端對聯(lián)邦執(zhí)行號、聯(lián)邦成員號和對象實例句柄號的賦值又會從1開始遞增編號,故與微服務所用的租戶號不能一一對應。但聯(lián)邦執(zhí)行的名字是唯一的,用戶可多次運行此名字的聯(lián)邦執(zhí)行。用戶每次創(chuàng)建該聯(lián)邦執(zhí)行,表示其要進行一次仿真實驗,用實驗次數(shù)與聯(lián)邦執(zhí)行的名字來唯一確定數(shù)據(jù)表中的一條記錄。對于此次實驗中的每一對象實例,用其實例句柄與上述記錄號而得的二元信息,可唯一標識對象實例對微服務的訪問,也即與租戶號相對應了。所以可用三元組[聯(lián)邦執(zhí)行的名字,實驗次數(shù)號,對象實例句柄號]來查詢租戶表中所對應的租戶號。
為此,RTI服務端在啟動時需要連接上數(shù)據(jù)庫,在創(chuàng)建聯(lián)邦時以聯(lián)邦執(zhí)行的名字為索引到庫表中查找記錄,獲得最大的聯(lián)邦執(zhí)行實驗次數(shù)號,并加1作為新記錄寫入庫表中,同時返回并得該記錄的記錄號FID。當創(chuàng)建對象實例時,將記錄號FID和該實例的句柄號及實例名一起寫入另一庫表,同時返回并得該記錄的記錄號TID,也即是租戶ID。
在構建跨國和跨洲的全球能源互聯(lián)網(wǎng)云仿真實驗中采用文中擴展的RTI功能[18]。全球能源互聯(lián)網(wǎng)由跨洲、跨國骨干網(wǎng)架和各國各電壓等級電網(wǎng)(輸電網(wǎng)、配電網(wǎng))構成,具體的硬件結構如圖3所示。
圖3 全球能源互聯(lián)網(wǎng)電力交易圖
為了保證系統(tǒng)實時運行時的電力平衡,需要進行實時平衡市場的交易。在實時平衡市場中,需求側和供給側交易主體根據(jù)自身交易需求情況,向所在轄區(qū)國的系統(tǒng)運營機構提交競標的價格和數(shù)量,系統(tǒng)運營機構把每小時的報價按照價格排序,然后根據(jù)交易需求對每小時的系統(tǒng)進行匹配。在對各國進行電力交易仿真時,需要根據(jù)電網(wǎng)內(nèi)所有負荷和所有發(fā)電機組的出力及其報價,以電網(wǎng)內(nèi)所有用戶購電費用最小為最優(yōu)化目標,通過線性規(guī)劃算法,最終給出每個發(fā)電廠的發(fā)電量和上網(wǎng)報價。
此實驗采用微服務的設計架構,為此需要構建電力交易微服務。該服務需要設置每個節(jié)點的負荷L,機組個數(shù)Ng及報價Pg和容量Cg,支路(i,j)電抗Xij,最大傳輸有功功率PMij。設決策變量機組g實際出力為Ug,其線性規(guī)劃模型為:
最優(yōu)目標函數(shù)是購電費用最?。?/p>
(1)
約束條件包括:
能量平衡約束:
(2)
機組容量約束:
0≤Ug≤Cg,g=1,2,…,NG
(3)
支路容量約束:
(4)
其中支路容量約束又需要通過計算網(wǎng)絡直流潮流的微服務來獲得,電網(wǎng)直流潮流微服務計算在發(fā)電模塊產(chǎn)生的能量(功率)、負荷模塊消耗的能量(功率)及各條線路的電抗已知的情況下,可以計算節(jié)點模型間能量的流動。
(5)
其中,θi和θj分別為線路兩端的直流電位;Xij(或電納為Bij)是線路的直流電阻。
(6)
用矩陣形式表示為:
[B0][θ]=[P]
(7)
其中,B0為正常運行時的網(wǎng)絡節(jié)點電納矩陣;θ為節(jié)點電壓相位角的向量;P為節(jié)點注入的有功功率向量。當B0和P已知時,用上式可以容易地求得各節(jié)點電壓相位角,進一步可算出各支路的有功功率潮流。
電力交易微服務[19]和直流潮流計算微服務基于ZeroC公司的ICE實現(xiàn)。RTI服務端組件在啟動時連接MySql數(shù)據(jù)庫,在對象實例訪問微服務時,創(chuàng)建ICE的連接,如下:
Ice::CommunicatorHolder
ich(argcEnv,argvEnv,"exchange.inf");
auto twoway=Ice::checkedCast
UgStr=twoway->startPowerExchange(L,NG,Pg,Cg,Xij,PMij,TenantID);
由于電力交易微服務需要獲得參與仿真的各國的輸入?yún)?shù),包括線路阻抗和最大容量,電力網(wǎng)絡各節(jié)點的申報負荷量和申報報價,各節(jié)點機組的申報發(fā)電量和申報價格,而后才能計算。所以各國需要在兩個仿真步長內(nèi)調(diào)用兩次交易對象的屬性更新接口。在第一步長內(nèi),將參數(shù)送電力交易微服務,由微服務將參數(shù)值寫入庫表,并將返回各國對象實例的參數(shù)置為空;在第二步長內(nèi),各國交易對象實例更新參數(shù)時,電力交易微服務通過查庫表可知該值已存在,則表明前面第一次的參數(shù)已全部獲得,故啟動最優(yōu)化計算,并將計算結果寫入數(shù)據(jù)庫表中。
RTI服務端組件調(diào)用電力交易微服務接口,該接口直接從數(shù)據(jù)庫中讀出該對象的信息并返回,RTI服務端組件通過解析返回的數(shù)據(jù)流,獲得對象實例的實際出力Ug和最優(yōu)報價Pg并發(fā)布到各國。發(fā)出更新請求的對象實例也將收到自己的最優(yōu)報價和最優(yōu)發(fā)電量。而之前對象實例更新的輸入?yún)?shù)是各國期望的價格和發(fā)電量,還不能保證實時運行時的電力平衡,只有RTI服務端組件通過調(diào)用微服務而得到的最優(yōu)報價和最優(yōu)發(fā)電量才能滿足實時運行時的電力平衡。
RTI的服務端組件可與微服務共同部署到私有云服務器上,使得聯(lián)邦成員在更新對象實例前訪問私有云中計算微服務的方式,轉變?yōu)橛蒖TI服務端來訪問云中的微服務,減少了數(shù)據(jù)在局域網(wǎng)內(nèi)的傳輸次數(shù)。RTI服務端組件通過與數(shù)據(jù)庫相連,將聯(lián)邦執(zhí)行名、實驗次數(shù)和對象實例與微服務的租戶號相對應,使RTI能調(diào)用微服務計算出對象實例的屬性更新值并發(fā)布出去,從而拓展了RTI與模型服務的結合方式。文中利用IEEE1516的OMT來定義對象類屬性與微服務接口參數(shù)的對應關系,若在OMT中直接定義與微服務接口相關的信息會使HLA與服務化更深度融合,這將是IEEE1516繼續(xù)發(fā)展的一個方向。