余 航,邢长友,许 博,丁 科
(陆军工程大学 指挥控制工程学院,江苏 南京210007)
微服务化的软件系统,其组成部分是众多相对独立的微服务[1],微服务以其松散耦合的特性,为软件系统增强其韧性提供了强大支撑。传统的单体架构存在可靠性低、可重用性差、体量臃肿等问题[2],这使得软件系统的部署、开发、应用都更加困难。相对于前者而言,微服务具有敏捷部署、独立开发、多语言支持等优势[3],这使得微服务能够基于冗余和多样性技术手段[4],允许跨地理分布的服务集群实现快速配置和更新集群状态,有助于增强软件系统韧性的同时,降低分布式服务集群的部署成本。对用户而言,系统本身的韧性能力反映在系统为用户分配的服务链上。
微服务架构下,服务链是指由若干个执行不同功能的微服务组件相互协同组成,用于满足用户需要,响应用户请求的有机整体。组成服务链的各微服务组件独立工作、互不干扰、可自由组合。服务链中各微服务之间松散耦合的特性使得其韧性能力可以视为各服务组件的韧性能力之和,微服务组件本身所具有的属性和所使用的技术手段决定了组件运行给系统带来的韧性增强。此外,对于系统运维而言,各微服务组件所采取的技术手段越多,系统复杂度越高,维护成本和复杂性也随之上升。
本文所研究的韧性编排问题是指确定和选择最佳微服务组件实例,组成一个完整的服务链(Service Chain,SC),在满足软件系统功能的条件下,使得系统韧性得到增强的工作流程。在微服务化的软件系统中,编排问题是最亟需解决的重点问题之一。
为解决上述问题,本文提出了一种韧性驱动的微服务编排框架RMOF,框架针对微服务组件本身的韧性能力水平和服务链整体复杂性进行了考察。本文的主要贡献包括:
(1) 建立了一套基于不同韧性目标,以用户满意度作为导向的微服务韧性编排数学优化模型。并在此基础上设计了综合考虑系统的韧性目标、风险、应对技术以及实现代价的微服务编排模型。
(2) 提出了GA -PP 算法,对微服务的编排问题进行优化,能够在保证优化编排方案的同时兼顾计算效率。
传统解决编排问题的一般方法通常包括轮询法、随机化方法或由专家根据经验确定优先级来解决等[5],以上方法存在可靠性不足和严重依赖专业经验的问题。并且在微服务化软件系统中,随着微服务组件数量的增加,问题解决的难度也随之上升[6],此外传统方法不具备足够的通用性,推广意义较为有限。
早期关于服务编排机制的工作主要基于服务质量(Quality of Service,QoS) 感知开展。QoS 属性通常包括响应时间、可用性、可靠性和价格成本等,文献[7-9]专注于基于QoS 感知的服务组合及其在中间件中的实现,不足之处在于没有定量地描述带有风险的安全目标,并在实际的云环境中解决它们。大量研究侧重于单个服务链的QoS 优化,而忽略了实例之间的共享和竞争。为了解决这个问题,Ding等人提出了一种基于列表调度的微服务选择算法(Microservice Service Selection algorithm,MSS)[10]。该算法采用工作流模型来对服务链进行描述,分析实例的处理速度、网络传输速度和任务并发程度,计算每个任务的分期限,根据分期限和其他信息,实时计算和更新每个任务的调度紧迫性。最后,提出了基于分期限和紧迫性的两种服务选择策略,以完成微服务实例选择,构成服务链。
大规模分布式云环境的高度复杂性导致了大量的不确定性,而这些不确定性无法通过常规信息安全方法的可用性来建模[11]。Wen 等人创新地从安全性角度出发,针对内部安全威胁和外部环境不确定性进行建模,并在Spark 上采用了新颖的分布式并行遗传算法框架GA-Par[12]来提供可靠的微服务编排并处理所涉及的计算效率问题,以降低大规模部署下执行编排算法的时间耗费,旨在为异地部署的数据中心微服务编排提供最佳解决方案。
因此,随着当前微服务化的不断推进以及系统韧性重要程度日渐上升,迫切需要一种用以量化微服务化软件系统韧性的通用机制,为实现韧性编排提供有力支撑。
关于编排问题的计算解决方案,研究人员已经证明,在大规模云环境中,问题的复杂度将随着系统规模扩张而爆炸式上升,诸如混合整数非线性规划(MINLP) 或线性规划(MIP) 等方法是不可行的[6],而遗传算法等启发式算法已被广泛用于优化资源调度、服务编排和任务分配[12-14]。
图1 描述了一个实时信息系统。用户在通过代理到达Web 前端后,可以分别通过用户注册、用户注销、用户登录的微服务组件实现注册、注销和登录,而这些操作又要通过后续负责数据库管理的微服务组件和后端用户信息数据库交互来得以实现,从而使得业务系统得以持续。在该系统中,整个系统的韧性程度可以看作是各个服务链上单个微服务组件的韧性能力之和,以及微服务组件之间的相互影响因素。
图1 实时信息系统架构
图2 所示是微服务化的软件系统架构,图中基础设施层每个部署节点上都维护一个服务注册表,注册代理发现各微服务组件(如Service,DBMS 等) 并完成注册。各微服务组件通过心跳报文在完成注册后向节点上的代理上报当前状态等信息。表示用户的Client 向请求代理Agent 发起服务请求后,Agent对请求进行解析,随后根据各部署节点上报的服务名单选择相应的服务实例执行,从而形成服务链,并根据相应的编排结果生成路由表项,下发至各SDN 交换机,以流控制的方式使系统中的业务流根据控制中心给出的方案进行执行。
图2 微服务化软件系统架构
为了实现韧性编排,需要处理以下问题:
(1) 如何表征存在损害系统韧性的可能风险,同时不同版本、基于不同技术实现、旨在实现同一功能目标的微服务组件为集群带来的韧性增益是不同的,如何利用可能存在的风险和韧性增强技术来量化微服务编排中的韧性目标满意度?
(2) 如何处理软件系统在不同韧性阶段所侧重目标一致的问题?
(3) 如何评估为增强系统韧性所需付出的代价,即如何对系统复杂性进行合理量化?
(4) 如何应对在系统规模扩张下不断增加的计算复杂性?
微服务韧性被认为是未来互联网的基本设计属性[15],是网络在面对正常运行下产生的故障和挑战时提供和维持可接受的服务水平的能力[16]。在软件系统中,韧性是一个总体概念,脱离系统整体来考虑单个微服务组件的韧性能力是没有意义的。
多样性和冗余技术手段的运用,使得对于每个微服务而言,都有一组微服务组件可以实现相应的功能。而在软件系统运行的不同阶段、不同步骤中,单个微服务组件对整个软件系统产生的韧性增益是不同的,因此需要提出一套合理的韧性评价体系,对于不同情况下对每个候选微服务组件进行韧性评价,选择最符合需求的微服务组件进入服务链中。本文从用户的角度出发,基于多种韧性目标,根据评估体系对候选微服务组件韧性计算用户满意度,从而对各组件进行评价。
为了处理2.1 节所提问题(1)、(2),本文首先对不同阶段的韧性目标进行明确,并说明韧性阶段、韧性目标、风险、韧性技术、用户满意度之间的关系。由于多种原因,现实中软件系统的韧性能力可能会面临一些风险,例如内存耗尽、隔离失效、恶意软件、恶意内部人员、错误删除等。但是,各种不同的微服务组件由于使用了多样化的技术手段对风险进行削弱或遏制,使得软件系统的韧性得以增强。因此,在不同的韧性阶段,各韧性目标的实现既取决于潜在的风险,同时又取决于各组件所使用的技术对风险的缓解程度。而用户满意度则来源于候选组件使用技术手段对风险的缓解程度与用户期望之间的差距。
(1) 不同阶段的韧性目标
在Kott 等人的《Cyber Resilience of Systems and Networks 》[17]一书中,系统韧性需求根据系统运行时所处于的不同阶段,被划分成预测、抵抗、恢复、适应四个阶段,各阶段所侧重的韧性目标有所不同,其对应关系如表1 所示。
根据表1 所示,在软件系统运行的不同阶段,用户对韧性目标有着不同的需求,因此t阶段的总体韧性指标可以表示为:
表1 各阶段系统韧性目标
其中,DSR (Degree of Service Resilience) 表示总体韧性程度,通过用户对微服务组件sih的满意度来计算,t表示软件运行的阶段,nt表示该阶段所考虑的韧性目标数量,Mq(u,sih) 表示在第t阶段用户u对微服务sih在第q个韧性目标上的满意度,wqi(t) 表示t阶段不同韧性目标的权重,即重要程度。
(2) 韧性目标与风险之间的映射
Kott 等人[17]提出韧性目标集合共包括七大目标,韧性目标与主要风险间的映射情况如表2 所示。
表2 韧性目标风险映射表
(3) 单风险下微服务组件韧性
本文利用各微服务组件所使用的风险预防技术来衡量它们的韧性增益。表3 显示了本文的部分符号释义。
表3 部分符号释义
假设微服务的韧性水平取决于所使用的相应技术手段的数量和质量,例如,可以通过多种技术或策略来防止某种类型的风险,并且当独立使用这些技术手段时,它们分别具备多种功能。此外,假设通过将更合适的技术应用于微服务会对系统韧性产生增益效果。下面将详细介绍如何计算微服务的韧性水平。
根据假设,某微服务组件可以通过一组技术和策略TechRk处理风险Rk,因此,该组件使用技术手段或策略缓解风险Rk,从而增强系统韧性的能力可以量化为:
其中Vj表示降低风险Rk的技术j的性能。如果微服务S提供了一系列技术和政策TechS,那么微服务S缓解风险Rk的能力可以表示为:
(4) 微服务组件韧性评估
再次以图1 中的实时信息系统为例,实际运行中,既需要保证微服务本身的韧性增益,同时需要确保微服务之间的信息传递满足韧性目标要求。
由于冗余和多样性的使用,同一微服务对应有一组实现相同功能的组件,本文的工作就是要建立适合的评估模型,对微服务链上的这一组微服务组件进行韧性评估,选出最能增强系统韧性的组件进入服务链。本文定义了一个服务韧性程度指标(Degree of Service Resilience,DSR),该指标描述了被评估组件所能提供的韧性能力与用户需求之间的比值,即用户满意程度,用以衡量韧性能力水平。在这一背景下,假设t阶段被选中的某个微服务组件sih可以完全满足用户的需求,那么DSR 需要满足以下条件:
DSR 的具体计算方式由下式确定:
而Mq(u,sih) 表示用户u对候选微服务组件sih在第q个目标上的满意度,其计算方法如下:
关于韧性代价问题,即2.1 节中所提问题(3 ),上文中已经提到,软件系统微服务化带来的最大问题在于复杂性提高带来的运维开销和困难[18],因此本节需要对系统复杂性进行建模。代价建模相关指标如表4 所示。
表4 代价建模相关指标
在形式上,微服务化的软件系统提供服务的服务链可以表示为有向无回路图G=(S,E)。如图3 所示,顶点S(如Service A1) 对应于微服务组件,而边E对应于在它们之间传输的数据或消息。
图3 业务流DAG 图
具体来说,软件系统中的每类微服务i都有一组候选微服务Si,其中候选h用sih∈Si表示,该候选组件所使用技术集合的表示符号为,因此单个微服务组件的韧性代价可以表示为该组件所使用的技术数量,即其复杂性指标,可用符号表示。
由于每个候选微服务组件sip在不同阶段在不同微服务之间可能具有不同的复杂性关系,本文将使用编排得到的服务链总体技术多样性度量作为指标对韧性代价进行建模。因此对于图中的某一条服务链SC,其韧性代价可以表示为该链上所有微服务组件所使用的技术种类数量,即并集的元素数量,与可使用的技术总量之比,如式(9) 所示:
其中,|TechA| 表示系统内微服务组件可选用的技术全集的元素数量,即:
在单微服务组件编排的情况下,对用户u 而言,t阶段在微服务Si的候选组件中选择sih的总体效用函数可以表示为式(11):
其中,λ 表示影响因子,即考虑韧性成本对编排结果产生影响的重要性程度。
由于单编排问题中,服务链中只有一个微服务组件,因此在考虑韧性代价时不需要考虑链中的其他微服务:
优化的目标在于使得在提高服务链韧性的同时,尽可能控制所需付出的代价。因此,其优化目标可以写成:
在多微服务组件编排的情况下,由于服务链中包含多个微服务组件,因此在讨论解决方案时需对整个服务链上的所有微服务组件进行考虑,假设该服务链SC 长度为n,每个微服务的候选者数量为m。对用户u 而言,t 阶段通过编排得到服务链SC 的总体效用函数可以表示为:
其中,需要注意的是:
为了解决2.1 节中所提问题(4),本文提出了一种部分保留的遗传算法GA -PP 。本节将简要概述这一解决方案,并对算法结构设计和实现做详细介绍。
(1) 算法概述
关于问题的求解,在本文的问题背景下,当需要通过编排得到的服务链SC 长度为n,每个微服务的候选组件数量为m 时,将问题命名为Arrangement(n,m)。问题Arrangement (n,m) 的解空间大小,就是所有微服务组件所能组合形成的服务链数量,因此其解空间大小为mn,是一个NP 难问题,显然使用简单的搜索算法是无法在有效时间内得到解决的。同时,由于整数非线性规划(MINLP) 或线性规划(MIP) 等方法是不可行的,因此需要使用启发式算法解决[19-20]。
遗传算法是一种典型的启发式算法,通常用于解决此类最优化问题[21]。但遗传算法存在收敛性问题[22],由于其选择、交叉、突变机制无法保证向着优化的方向变化,因此难以确保收敛。Eiben 等人[23]已经证明,合适的选择策略能够使遗传算法不断收敛。本文提出了一种部分保留的遗传算法GA -PP,该算法旨在得到问题Arrangement(n,m) 的一个较优的可行解。
在GA-PP 中,每个染色体代表一个服务链个体,即一种解决方案,每个染色体上都有固定长度的多个基因,每个基因代表服务链中的一个微服务组件。根据3.1 节中给出的优化目标,本文将优化目标Value 作为遗传算法的适应度函数。GA-PP 主要包含四个阶段: 选择、交叉、突变、保留。通过每一轮迭代筛选出种群中的精英,保留部分较优的精英直接进入下一代种群中,通过不断迭代最终得到一个可行解。
(2) 算法实现
传统的遗传算法中,突变过程中基因突变方向是不确定的,这对于连续且变化程度不过于剧烈的函数而言并不会造成太大影响,只要在数次突变中有若干次突变朝着结果优化的方向发展,就能将优秀的基因保留下来。而在本文所讨论的问题Arrangement(n,m) 中,无论是染色体(服务链SC)、基因(微服务组件) 还是适应度函数(Value) 都是离散的,并且无论是选择、交叉还是突变,都有可能导致优秀基因的流失,这对于遗传算法的收敛性提出了更高的要求。
为了更直观地描述GA-PP 算法,本文将算法流程绘制如图4 所示。图中描述了一种引入“ 精英保留” 机制的遗传算法,在每一代次种群计算完适应度Value 后,都将其中的优秀染色体保留下来,同时“ 记住” 表现较差的个体,在每一轮突变结束后即将进入下一轮种群Value 值计算之前,将之前“ 记住”的较差个体用保留下来的优秀个体进行替换。对于表现差的个体而言,该染色体上绝大部分基因都是表现不佳的,因此无论是否经过交叉还是突变,都难以使其从表现较差的个体转变成“ 精英”,因此使用保留下来的精英个体对其进行替换,既能将优秀的染色体保留到下一代次,确保其不断收敛,同时起到基因筛选的效果。
图4 详细说明了GA -PP 算法执行的全过程。Arrangement (n,m) 问题下,每个染色体长度为n,染色体个体上每个基因有m 种表达。种群在完成初始化后,首先使用0-1 编码的方式对种群中每个染色体和基因进行编码,每个基因的编码长度为log2m 。通过计算种群中每个个体的适应度Value,可以得到种群中最优、最劣的部分个体,这部分个体将在种群完成选择、交叉、突变三个遗传算法的传统过程后完成替换,将最劣的部分个体替换成最优的部分个体,从而使得最优个体,即精英能够顺利进入下一代次的迭代中,保证迭代结果能够一直向着更优的方向发展。
图4 算法流程图
其中核心步骤包括图4 中标注的①~④四个步骤:
①选择: 本文使用轮盘赌法对每一代次的种群进行淘汰选择,目的是使表现好的染色体进入到后续的遗传过程中;
②交叉:种群中的相邻个体以一定的概率杂交,以选择得到的 “好” 染色体为基础,产生新的染色体;
③突变: 以一定概率使得染色体中的个别基因发生突变,以期得到可能的更好的染色体;
④保留: 将每一代次中的精英保留下来直接进入下一代次,保证迭代过程中新产生的种群中最高的Value 值至少不会低于上一代次,防止算法无法收敛。
GA-PP 算法伪代码如下:
(1) 平台。本文所有实验均在ThinkPad T470p 上执行,其处理器为Intel®CoreTMi7-7700HQ CPU @2.80 GHz×8,内存大小为16 GB,使用Ubuntu 16.04操作系统。
(2) 数据。除了上文表1 、表2 中提到的两组映射关系外,本文所使用的数据还包括了13000 条请求与技术映射记录,以及风险- 技术映射表。
(3) 方法。本文通过运行随机选择(Random)、传统遗传算法(GA) 和GA -PP 对服务链进行编排,针对不同韧性阶段、不同问题规模、不同服务链长度下求解Arrangement (n,m) 问题,比较Random 、GA 、GA -PP 三种算法编排下得到目标服务链Value 值在4个韧性阶段下的均值,评估本文所给出的韧性编排算法的有效性。
(4) 指标。根据3.1 节给出的计算最终Value 值公式,分别在4个韧性阶段,通过应用不同算法得到服务链编排结果,对4个韧性阶段得到的Value值求均值,作为最终比较的效用指标。
在本节中,将通过运用三种算法在不同情况下解决Arrangement (n,m) 问题,以此来研究在定量韧性测量框架下使用GA -PP 算法带来的效用改善,并评估使用不同方案可获得的效用值。
(1) 不同韧性阶段的算法表现
图5 所示是在(n,m)=(10,64) 的情况下,Random、GA 、GA-PP 三种算法在不同韧性阶段的迭代情况,横坐标为迭代轮次,纵坐标为编排得到的目标服务链的Value 值。可以看出,三种算法中,由于Random不存在迭代问题,因此其表现在三种算法中较差。对比普通的GA 算法与本文所提的GA -PP,GA 在迭代过程中始终难以收敛,并且存在较大波动,但相较Random 而言更能得到一个较好的解,而GA - PP由于在迭代过程中保留了种群精英,能在较少的迭代轮次下收敛到一个更优的解,编排得到的服务链Value 值基本可以收敛到0.90 附近。
图5 Arrangement(10,64) 问题在不同韧性阶段的表现情况
(2) 不同候选组件数下的算法表现
图6 描述了在不同问题规模下三种算法的表现情况,本文在服务链长度n 为10 的条件下,分别选取候选组件数m 的值为16,32,64,128,256,取四个阶段编排结果Value 值的平均值作为对比指标,考察三种算法在五种不同候选组件数情况下的表现情况。
由图6 可以观察到,三种算法中GA-PP 始终比另外两种算法有更好的表现,利用GA-PP 算法来解决本文所提的编排问题可以得到更加优化的结果,即获得更能满足用户需求的服务链。此外,根据图6显示可以发现,候选组件数量的变化并未对算法结果产生太大干扰,不直接影响服务链Value 值的计算。
图6 不同问题规模下三种算法的表现情况
(3) 不同服务链长度下的算法表现
图7 描述了不同服务链长度下三种算法的表现,本文在每个微服务候选组件数m 的值为16 的情况下,分别选取服务链长度n 的值为2,3,5,10,15,取四个阶段编排结果Value 的均值作为对比指标,考察三种算法在五种不同服务链长度情况下的表现情况。
根据图7 可以观察到,总体上来看,GA -PP 始终比另外两种算法有更好的表现,利用GA-PP 算法来解决本文所提的编排问题可以得到更加优化的结果。此外,根据图7 显示可以发现,随着服务链长度的增长,三种算法的表现都随之下降,可见服务链长度n 对Value 值的优化计算具有较大影响。原因在于本问题的解空间大小为mn,相较于m 增大给问题规模带来的影响,n 的增大将使得问题复杂度的扩张更为剧烈。
图7 不同长度服务链下三种算法的表现情况
本文通过考虑微服务组件所使用的韧性增强技术和所产生的韧性代价,描述了一种基于韧性的微服务编排框架RMOF 。RMOF 充分考虑了系统韧性实现的目标、所面临的风险以及微服务组件所使用的应对风险的技术,同时使用技术应用给系统带来的复杂性作为韧性代价,从用户角度出发,综合考虑韧性增益和代价进行评估。为解决编排的计算问题,本文提出了一种部分保留的遗传算法GA-PP,以获得更好的收敛效果和编排结果。通过本文的框架构建和算法实践,可以得出以下重要发现和结论:
(1) 随着微服务架构的大规模应用,以及系统韧性的重要性日益突出,构建一套适用于微服务架构下基于韧性的编排框架显得越来越重要。
(2) 对于开发者而言,紧贴用户需求是十分必要的,应该从用户角度出发,充分考虑用户需求。
(3) 对于韧性系统的编排问题而言,其解空间爆炸的特性使得问题无法通过一般的搜索算法得到解决,必须借助遗传算法等启发式算法进行解决。
(4) 传统的遗传算法对于离散数据存在难以收敛的问题,需要采取其他策略诸如精英保留、精英选择等,来使得其不断收敛。