一种支持私有云仿真的HLA/RTI实现方法
2019-09-28黄继杰林昌年杨选怀王兰香王国平
黄继杰,林昌年,杨选怀,王兰香,王国平
(北京科东电力控制系统有限责任公司,北京 100192)
0 引 言
分布式仿真标准IEEE1516基于面向对象技术提出了高层体系架构(HLA)。为了适应面向服务的仿真环境,IEEE1516-2010版对HLA进行了许多扩展[1-2],并采用WSPRC组件(Web services provider RTI component)技术使HLA/RTI能支持Web环境下的仿真[3-4]。云计算技术的蓬勃发展使仿真资源得到更高层次的共享,因而“云仿真”将是未来分布仿真的主要研究方向[5-6]。文献[7]研究了云仿真技术与HLA Evolved技术进行综合的问题,采用的技术手段还是对HLA进行扩展。
随着虚拟化技术的快速发展,出现了虚拟化容器技术(如Docker[8-9]),并且使基于单体式软件架构的SaaS层云服务可拆分为许多微服务[10]。基于Docker和微服务来部署私有云[11]就可采用一台高性能的服务器,根据仿真任务的需要启动Docker容器,并将仿真模型微服务部署其中[12]。这种虚拟化和微服务技术使得HLA与面向服务技术能更好地结合。
HLA的对象模板类(OMT)是其支持联邦成员交互的基础。文中先利用OMT的对象属性来定义仿真模型微服务的特殊标志及相关信息,并在RTI实现中,当遇到对象属性名为仿真模型微服务的特殊标志时,由RTI来负责完成对模型微服务的访问。
1 私有仿真云中部署微服务
随着虚拟化容器技术的兴起,产生了微服务,比如现在非常通用的Docker容器。Docker与虚拟机不同,Docker容器并不是一套硬件虚拟化方案,而是一个操作系统级别的虚拟化技术,仅为应用提供一套隔离的运行时虚拟环境,而不是整个虚拟的硬件资源。Docker是以容器为资源分割和调度的基本单元和调度单位,封装了整个服务运行时的环境,用于构建、发布和运行分布式应用的平台。它使用Linux内核提供的LXC技术实现类似虚拟机的功能,以更节省的方式利用硬件资源,提供用户更多更高效的计算资源服务。
在Docker内部署的微服务改变了软件架构模式,使软件架构从单体式转向了微服务的架构模式。单体式软件架构也称为集中式软件体系架构,是指所有的功能在一个应用中,各个模块之间通过相互调用的方式交互。单体式软件架构具有以下不足:维护和扩展困难;难于持续部署;应用伸缩性差和可靠性低。因此,在云平台中这种单体式架构如今正开始被最新的微服务架构逐渐取代。
微服务软件架构被定义为:“开发单个服务组件作为一系列应用的套件,其中每个服务可以使用不同的编程语言实现,以及不同的存储技术独立运行在自己的进程空间中,围绕着业务功能而构建,可通过完全独立的自动化部署机制进行构建和部署,实现去中心化服务、集中式管理最小化,各个服务之间通过轻量级机制实现通信”。微服务具有以下特点:彼此独立;原子化;组合和重构。基于微服务开发的系统其所有的个体由于在概念上是对等的,结构相对模块化、简单化,因此具有松散耦合的特点,构成的系统具有更强的可扩展性和鲁棒性。
2 OMT支持微服务的策略
HLA基于OMT来实现联邦成员间的数据交互,其中对象属性更新是最常用的方式。而对象属性的计算常常通过调用模型的接口来获得。由于微服务软件架构相比单体架构具有优势,用于计算对象属性的模型接口越来越多地采用微服务的接口。在私有云内的微服务环境下进行分布交互仿真一般采用图1左侧的方式,即联邦成员先调用私有云内的模型微服务计算对象属性,再将对象属性的更新值通过私有云内的RTI服务发布到其他联邦成员。
图1 RTI支持微服务的通信架构
当设计FOM/SOM时,将联邦成员计算对象属性的输入参数和输出参数加入到OMT中,以此代替该原对象需要更新的属性,其发布过程如图1右所示[13]。由于模型服务和RTI服务都位于私有云服务器,而服务器内部进程间的通信速度高于局域网中机器间的进程通信速度,故图1右所示的数据交互速度比左图所表示的更快。
设计OMT时可以像文献[14]一样,在OMT具体的FED文件中增加关键词来标示此对象需要RTI访问的微服务。考虑到与IEEE1516现有标准的一致性,利用对象类名加“_microService”字段来通知RTI,由它先调用微服务更新对象属性,再查阅订购者并将更新值发给它。以学生对象类(Class Student)为例[15],假设它包含三个属性(LunchMoney,AmmoAmount和Cleanliness),并通过CalculateStudent函数来重新计算(LunchMoney,AmmoAmount和Cleanliness )这三个属性。现将CalculateStudent函数封装为微服务的接口,接口参数包括代表这三个属性的输入和输出,此外还包括微服务的地址。为此,将学生类对象(新类名为Student_microService)重定义为七个属性(addr_CalculateStudent,in_LunchMoney,in_AmmoAmount,in_Cleanliness,out_LunchMoney,out_AmmoAmount,out_Cleanliness)。RTI在调完微服务后将原来数据分发的处理量由(LunchMoney,AmmoAmount和Cleanliness )转向其中的(out_LunchMoney,out_AmmoAmount和out_Cleanliness)这三个属性,并可用这三个输出属性过滤基于HLA的区域。OMT中命名统一规定为:前缀“addr_”表示接口地址,“in_”表示输入参数属性,“out_”表示输出参数属性。
3 支持微服务的RTI实现方法
在开源CERTI源码的基础上进行RTI服务端的修改[16],涉及到对象声明管理和对象管理两部分。RTI服务端在处理对象声明管理时,需要嵌入对类名称的判断,若类名字后部包含“_microService”,则该对象类的实例需要由RTI服务端调用微服务来计算各对象的属性并完成发布和订阅功能。处理流程如图2所示。
图2 RTI支持微服务的处理流程
图2中,当判断为“否”时,程序流程走的是原RTI服务处理流程;当判断为“是”时,先设置需调用微服务接口的标志,然后查看属性名的前缀是否包含“in_”和“out_”,若包含“in_”为该属性的输入参数,若包含“out_”为该属性的输出参数。对微服务接口地址参数,通过查看是否包含前缀“addr_”来获得,如学生对象类所调的微服务接口,其属性为:“addr_CalculateStudent”。
在后面的学生对象更新其属性时,属性“addr_CalculateStudent”所对应的值由微服务的配置文件和此接口的名构成,如“exchange.inf@startPower Exchange”,其中exchange.inf是配置文件,startPowerExchange是接口名。
RTI实现中将属性映射为属性句柄,通过(句柄值和属性值)来打包传输数据;对于接口的参数名也需要与属性的句柄值相关联。为此,输入参数属性在RTI解析FOM/SOM时会将属性名映射为属性句柄,且RTI在分配属性句柄时是按自动递增顺序来计算句柄值的。故按微服务接口参数的顺序依次定义FOM/SOM中的访问该微服务的对象类的属性,则参数值、属性句柄值和属性值是一一对应的关系。RTI在调用该接口时,先获得该接口的全部参数,并按对应的属性句柄大小进行属性值排队,从而按此顺序将属性值作为参数来调用对应的微服务接口。
同样,对于输出参数属性,同样需要此微服务接口在计算完后按输入参数的顺序进行数据打包。包格式为:4字节参数个数,第一个参数字节长度,第一个参数内容,第二个参数长度,第二个参数内容,以此类推。当RTI服务端调用此微服务接口后,对获得的返回值进行上述格式的解包,并按输出参数属性句柄的大小依次赋值给各输出参数属性。
由于只有输出参数属性是需要在联邦间交互的值,故对于对象类的订购处理流程按CERTI的原代码处理,包括数据分发的区域过滤也按CERTI的原代码处理。
4 RTI对多租户微服务的访问
当私有云中的微服务支持同一用户多次访问时,微服务可采用SaaS的多租户技术。多租户技术的实现重点在于不同租户间应用程序环境的隔离(application context isolation)以及数据的隔离(data isolation),以维持不同租户间应用程序不会相互干扰,同时数据的保密性也够强。
与访问微服务的租户所对应的是RTI中的联邦执行号、联邦成员号和对象实例句柄号[17]。当RTI服务重启后,RTI服务端对联邦执行号、联邦成员号和对象实例句柄号的赋值又会从1开始递增编号,故与微服务所用的租户号不能一一对应。但联邦执行的名字是唯一的,用户可多次运行此名字的联邦执行。用户每次创建该联邦执行,表示其要进行一次仿真实验,用实验次数与联邦执行的名字来唯一确定数据表中的一条记录。对于此次实验中的每一对象实例,用其实例句柄与上述记录号而得的二元信息,可唯一标识对象实例对微服务的访问,也即与租户号相对应了。所以可用三元组[联邦执行的名字,实验次数号,对象实例句柄号]来查询租户表中所对应的租户号。
为此,RTI服务端在启动时需要连接上数据库,在创建联邦时以联邦执行的名字为索引到库表中查找记录,获得最大的联邦执行实验次数号,并加1作为新记录写入库表中,同时返回并得该记录的记录号FID。当创建对象实例时,将记录号FID和该实例的句柄号及实例名一起写入另一库表,同时返回并得该记录的记录号TID,也即是租户ID。
5 私有云中构建基于RTI扩展的实验
在构建跨国和跨洲的全球能源互联网云仿真实验中采用文中扩展的RTI功能[18]。全球能源互联网由跨洲、跨国骨干网架和各国各电压等级电网(输电网、配电网)构成,具体的硬件结构如图3所示。
图3 全球能源互联网电力交易图
为了保证系统实时运行时的电力平衡,需要进行实时平衡市场的交易。在实时平衡市场中,需求侧和供给侧交易主体根据自身交易需求情况,向所在辖区国的系统运营机构提交竞标的价格和数量,系统运营机构把每小时的报价按照价格排序,然后根据交易需求对每小时的系统进行匹配。在对各国进行电力交易仿真时,需要根据电网内所有负荷和所有发电机组的出力及其报价,以电网内所有用户购电费用最小为最优化目标,通过线性规划算法,最终给出每个发电厂的发电量和上网报价。
此实验采用微服务的设计架构,为此需要构建电力交易微服务。该服务需要设置每个节点的负荷L,机组个数Ng及报价Pg和容量Cg,支路(i,j)电抗Xij,最大传输有功功率PMij。设决策变量机组g实际出力为Ug,其线性规划模型为:
最优目标函数是购电费用最小:
(1)
约束条件包括:
能量平衡约束:
(2)
机组容量约束:
0≤Ug≤Cg,g=1,2,…,NG
(3)
支路容量约束:
(4)
其中支路容量约束又需要通过计算网络直流潮流的微服务来获得,电网直流潮流微服务计算在发电模块产生的能量(功率)、负荷模块消耗的能量(功率)及各条线路的电抗已知的情况下,可以计算节点模型间能量的流动。
(5)
其中,θi和θj分别为线路两端的直流电位;Xij(或电纳为Bij)是线路的直流电阻。
(6)
用矩阵形式表示为:
[B0][θ]=[P]
(7)
其中,B0为正常运行时的网络节点电纳矩阵;θ为节点电压相位角的向量;P为节点注入的有功功率向量。当B0和P已知时,用上式可以容易地求得各节点电压相位角,进一步可算出各支路的有功功率潮流。
电力交易微服务[19]和直流潮流计算微服务基于ZeroC公司的ICE实现。RTI服务端组件在启动时连接MySql数据库,在对象实例访问微服务时,创建ICE的连接,如下:
Ice::CommunicatorHolder
ich(argcEnv,argvEnv,"exchange.inf");
auto twoway=Ice::checkedCast
UgStr=twoway->startPowerExchange(L,NG,Pg,Cg,Xij,PMij,TenantID);
由于电力交易微服务需要获得参与仿真的各国的输入参数,包括线路阻抗和最大容量,电力网络各节点的申报负荷量和申报报价,各节点机组的申报发电量和申报价格,而后才能计算。所以各国需要在两个仿真步长内调用两次交易对象的属性更新接口。在第一步长内,将参数送电力交易微服务,由微服务将参数值写入库表,并将返回各国对象实例的参数置为空;在第二步长内,各国交易对象实例更新参数时,电力交易微服务通过查库表可知该值已存在,则表明前面第一次的参数已全部获得,故启动最优化计算,并将计算结果写入数据库表中。
RTI服务端组件调用电力交易微服务接口,该接口直接从数据库中读出该对象的信息并返回,RTI服务端组件通过解析返回的数据流,获得对象实例的实际出力Ug和最优报价Pg并发布到各国。发出更新请求的对象实例也将收到自己的最优报价和最优发电量。而之前对象实例更新的输入参数是各国期望的价格和发电量,还不能保证实时运行时的电力平衡,只有RTI服务端组件通过调用微服务而得到的最优报价和最优发电量才能满足实时运行时的电力平衡。
6 结束语
RTI的服务端组件可与微服务共同部署到私有云服务器上,使得联邦成员在更新对象实例前访问私有云中计算微服务的方式,转变为由RTI服务端来访问云中的微服务,减少了数据在局域网内的传输次数。RTI服务端组件通过与数据库相连,将联邦执行名、实验次数和对象实例与微服务的租户号相对应,使RTI能调用微服务计算出对象实例的属性更新值并发布出去,从而拓展了RTI与模型服务的结合方式。文中利用IEEE1516的OMT来定义对象类属性与微服务接口参数的对应关系,若在OMT中直接定义与微服务接口相关的信息会使HLA与服务化更深度融合,这将是IEEE1516继续发展的一个方向。