Page 124 - 《软件学报》2021年第5期
P. 124

1348                                     Journal of Software  软件学报 Vol.32, No.5,  May 2021

                    14: instSizeMap←calcInstNum(S n ,D n )   //计算满足给定用户需求所需的实例数量
                    15: while (s←getNextSvc(T s ))≠null do   //优先部署不被其他服务调用的服务
                    16: if deployInsts(ns,n,s,instSizeMap[s])=true then
                    17: S n ←S n \{s}
                    18: end if
                    19: T s ←T s \{s}
                    20: end while
                    21: unDeployedSvc←unDeployedSvc∪S n
                    22: end for
                    23: for s in unDeployedSvc do
                    24: if otherNodesCanSupply(s)=false then
                    25: deployOnMostCloseNode(s,ns)   //部署在最近的,有着足够计算资源的节点上
                    26: end if
                    27: end for
                    28: return calcDiff(ns,os), rules
                    该算法的基本思想是,尝试以最低的演化代价为每个边缘节点都提供最低的平均响应时间.因此,算法 1 先
                 对每个节点进行规划(第 4 行~第 22 行),然后再针对无法满足的用户需求进行全局规划(第 23 行~第 27 行).第 6
                 行~第 10 行针对所有的用户需求,在不考虑服务之间的版本依赖的情况下,挑选出能够以最少计算资源服务最
                 多用户的服务.pickOneService(⋅)遍历服务集合,并返回所需计算资源以及能够满足的用户数量的比值最小的服
                 务.getMetDemand(⋅)在挑选出服务 s 能够满足的用户需求集合时,会自动扩展版本依赖关系,通过版本号中的
                 Major 来判断不同版本服务接口之间的兼容性,并允许使用兼容版本满足用户需求.buildMiniSvcTree(⋅)用于从
                 服务集合 S 中计算出满足服务集合 S n 内服务依赖的最小服务集合.通过对 S n 中的所有服务按照广度优先依次
                 选择满足最多用户且消耗较少资源的服务,已经出现在集合 S n 中的服务优先选中.路由规则为树的边缘与叶子
                 节点组成的键值对集合.
                    第 14 行的 calcInstNum(⋅)通过每个版本的服务的最大用户数量与分配给该服务的用户数量,计算出集合中
                 的每个服务需要部署的实例数量.考虑到调用一个服务接口时,该接口可能会多次调用其他接口,该函数利用上
                 一时间窗内的 Gateway 存储的请求转发历史数据,计算出每个服务接口被调用一次导致的调用其他服务接口
                 的平均次数最为调用,并在计算服务之间的调用时,乘上该系数.例如:用户 A 请求了服务 s j 的接口 i m ,调用一次该
                 接口会调用服务 s k 的接口 i n 平均 2.8 次,则服务 s k 满足的用户数量增加 2.8.在存在着更长的调用链时,以此类推.
                 在第 15 行~第 20 行部署实例时,getNextSvc(⋅)返回服务集合中没有别其他服务调用且能够利用最少资源服务最
                 多用的服务.如果该节点上没有足够的资源部署剩余服务,则部署到其他节点(第 23 行~第 27 行).
                    运行阶段,算法通过查询规划阶段生成的路由规则,为每个带版本依赖的请求选择合适的服务,并在当前系
                 统中选择一个距离用户最近,且同时服务的用户数量不超过最大数量的实例作为目标实例.
                 2.2   支持DevOps流程中部署需求的自适应算法
                    系统中复杂的服务依赖,让服务的部署、删除、版本升级等 DevOps 流程中相关的操作变得更加复杂,开发
                 人员需要耗费大量的精力来确保 DevOps 过程中系统的正确性.该部分自适应算法考虑了 DevOps 过程中的常
                 见操作,能够在确保服务依赖被满足的情况下,自动执行相关指令.本文在 DevOps 自适应过程中,仅仅考虑
                 DevOps 流程中部署需求,不涉及到用户需求.
                 2.2.1    抽象描述
                    考虑到不同场景下的复杂需求,每个不同的操作均提供了响应的布尔值类型的标记位,用于表征是否考虑
                 服务之间的依赖关系.由于部分操作对原有系统中稳定的依赖关系具有一定的破坏性,如删除一个被其他服务
                 依赖的服务实例,这里仅遵守 DevOps 流程中部署的操作指令,不考虑因该操作指令导致的依赖缺失.
   119   120   121   122   123   124   125   126   127   128   129