王锦
(安徽电子信息职业技术学院 信息与智能工程系,安徽 蚌埠 233000)
云应用程序可以被视为由运行互连软件组件的一组虚拟机(虚拟机)组成的分布式应用程序。部署这些应用程序后,可能需要进行一些重新配置操作,例如实例化新虚拟机,动态复制其中一些以实现负载平衡(弹性),销毁或替换虚拟机等。但是,设置、监视和重新配置分布式应用程序在云中是复杂的任务,因为软件涉及许多依赖关系,这些依赖关系要求以某种顺序进行任何更改以保持应用程序的一致性。此外,部分任务可以以时间并行的方式执行,以进一步优化性能,但是这也不能手动实现。因此,需要一种健壮的算法,其在分布于多个虚拟机中运行的应用程序上完全自动化重新配置任务。本文提出了一个完全自动且可靠的算法,旨在重配置运行时云应用程序。
为了便于理解,从几个实现细节中抽象出来,例如IP地址或配置参数。所考虑的应用程序模型由一组虚拟机组成。从功能的角度来看,每个虚拟机都托管一组组件,其中包含应用程序的功能部分。组件有启动和停止两种状态,可以提供或请求服务。采用符号import表示组件请求的服务,符号export表示组件提供的服务。import可以是可选的,也可以是强制的。当连接到匹配的export并且启动export的组件时,则认为import被满足,这个过程也称为绑定。组件可以从托管在同一虚拟机上的组件import服务,也可以从托管在另一个虚拟机中import服务。当满足所有强制的import时,可以启动并运行组件。对于可选的import,即使不完全满足,组件也可以启动并运行。
图1web应用程序模型
将使用典型的三层Web应用程序作为示例,如图1所示。虚拟机1托管了两个组件:前端Web服务器(Nginx)[1]和分析组件。虚拟机2托管了应用程序服务器(IIS)[2]和对象缓存组件。虚拟机3则托管了数据库管理系统(SQLite)[3]。这些组件使用本地或远程绑定进行连接。这些绑定涉及可选的import或强制import。
重配置算法具有四个主要的重要设计特征,即完全自动化、去中心化、健壮和可靠。每个虚拟机都配有一个虚拟机管理器,负责自动执行虚拟机级别的重配置任务。所有虚拟机管理器均在无人为干预的情况下工作。云管理器发布由云用户提供或编码为脚本语言的重配置操作。因此,云管理器也不需要人与运行的系统和应用程序进行操作。虚拟机管理器负责启动和停止自己的组件。该算法遵循松耦合的设计原则,这是因为每个虚拟机管理器都没有应用程序当前状态的全局视图。然而,虚拟机管理器需要交换信息以便连接远程组件上的绑定或让某些组件知道其他组件已经启动或停止。交换组件启动/通知信息的唯一方法是通过异步消息传递进行交互。每个虚拟机都配有两个队列缓冲区,一个用于传入消息,另一个用于传出消息。虚拟机以点对点的方式进行交互,以避免网络通信瓶颈的出现。
重配置算法包括了一个云管理器和一组虚拟机管理器。云管理器通过实例化/销毁虚拟机以及请求添加/删除组件/绑定操作来进行应用程序重配置。分布式应用程序中的每个虚拟机均配备有虚拟机管理器,该管理器在云管理器发布的虚拟机实例化/销毁操作时负责连接绑定和启动/停止组件。参与者(即云管理器和虚拟机管理器)之间的通信通过FIFO队列异步实现。当参与者需要发布消息时,它会将该消息放入其输出队列中。当它想要读取消息时,它会在其输入队列中获取消息。消息随时从输出队列传输到其收件人的输入队列。
云管理器向正在运行的应用程序提交重配置操作,并跟踪已部署的虚拟机和组件的激活状态。考虑重配置操作如下:虚拟机的实例化/销毁、在现有虚拟机上添加/删除组件以及添加/抑制绑定。为了确保算法的正确执行,云管理器会对操作进行验证。例如,在销毁虚拟机前需要验证该虚拟机是否已经被实例化。重配置机制由云管理器发布的一系列操作触发。
该算法定义了“上升”和“下降”的阶段操作。与上面介绍的原子重构操作相比,阶段操作具有更粗的粒度。上升阶段对应于用于启动的一组重配置操作(例如,虚拟实例化或绑定添加)。当云管理器实例化虚拟机时,它会创建该虚拟机的映像,并且虚拟机开始自行执行。当云管理器向正在运行的应用程序添加一组必需的绑定时,它会向受这些更改影响的所有虚拟机提交消息,即托管这些绑定中涉及的组件的所有虚拟机。这些消息附带了虚拟机管理器为绑定目的所需的一些配置信息。下降阶段涉及关闭的操作(例如,虚拟机销毁或绑定移除)。当云管理器决定销毁虚拟机时,它会向该虚拟机发送一条消息。虚拟机销毁消息意味着销毁该虚拟机上托管的组件上的所有绑定。云管理器还会跟踪系统中运行的所有虚拟机的当前激活状态(实例化的虚拟机以及它们是否已启动)。当虚拟机上的所有组件都启动时,则该虚拟机已启动。
图2上升和下降阶段示例
上升和下降阶段按顺序交替,云管理器负责启动新阶段,阶段对于用户而言是完全透明的。在开始新阶段之前,云管理器等待来自前一阶段中的确认消息(ACK)。当云管理器收到所有ACK后,它可以启动新阶段。
图2显示了云管理器如何通过应用连续的上升和下降阶段。首先实例化所有虚拟机并且添加所需的绑定(即图1中的绑定集)。然后,决定删除SQLite组件,并采用新版本替换它。最后,在虚拟机3上添加这个新组件,并添加一个将IIS组件连接到新SQLite组件的绑定。
当云管理器实例化其虚拟机时,虚拟机的管理器便启动了。虚拟机管理器负责在虚拟机中进行绑定、解除绑定、启动和停止组件的操作。在本节的其余部分中,将介绍两种最常用的重配置操作,即虚拟机的实例化和销毁。
绑定和启动虚拟机中包含了许多组件,在实例化虚拟机时,每个组件都是处于关闭转态。图3显示了新实例化的虚拟机如何绑定端口和启动组件。在实例化之后,虚拟机管理器可以立即启动没有import的组件或仅启用可选的import。如果组件涉及强制import,则只有在满足所有强制import时(即所有这些import均绑定到已启动的组件),才能启动该组件。启动组件时,该组件的虚拟机管理器会向远程使用该组件的虚拟机管理器发送组件启动消息。如果虚拟机的所有组件都已启动,则其虚拟机管理器会发送消息通知云管理器,否则它将开始从其输入队列读取消息。
图3虚拟机管理器的上升阶段操作
当虚拟机从云管理器接收到绑定请求(包括本地和远程绑定),管理器首先建立本地绑定。在export端启动远程绑定:当绑定中涉及其中一个组件的export时,虚拟机管理器将export连接信息(例如,IP地址)发送到托管该组件的虚拟机(即组件的import端)。如果虚拟机收到远程绑定消息,则表示绑定中涉及其某个组件的import。收到该消息后,虚拟机管理器使绑定生效。当收到组件启动消息时,虚拟机管理器都会检查是否可以启动相应的组件。
解除绑定和关闭:虚拟机管理器负责在虚拟机被销毁时停止一些本地组件或其所有组件。此时,需要停止托管在该虚拟机上的所有组件,并且需要删除这些组件的所有绑定(到import或export的连接)。如果关闭过程中涉及的组件未提供任何服务(没有连接组件),则可以立即停止,并且可以删除这些组件的所有绑定。否则,在强制import上与其连接的所有组件都已经自行解除之前,该组件无法停止。为此,将被销毁虚拟机的管理器首先将解除绑定所需的消息发送到所有托管组件的虚拟机。然后,将被销毁虚拟机的管理器收集接触绑定的确认消息,并在强制import时使用该组件的所有组件已停止和未绑定时停止相应的组件。只要组件停止,就会发送解除绑定的确认消息。当所有组件都停止时,虚拟机被销毁并通知云管理器。
在销毁的过程中,其他虚拟机管理器可以从其伙伴虚拟机接收消息。收到解绑请求消息后,虚拟机管理器会停止并取消绑定某些组件,或者为强制imoprt的所有远程组件发送类似的消息。当虚拟机管理器停止并解除绑定组件时,它可能会向云管理器发送一条消息,提示虚拟机未完全运行。它还向以前向该组件提供服务的所有远程伙伴组件发送消息,让他们知道该组件已停止/未绑定。
绑定在可选import上的组件只需要解除绑定,但不需要停止。本地绑定由虚拟机管理器在本地处理,但这些更改可能会影响其他远程组件,在这种情况下,可能会发出其他未绑定的必需消息。组件关闭意味着非绑定所需消息的向后传播,并且当第一次传播结束时(在没有导出或仅具有可选导入的组件上),解绑确认消息的第二次向前传播开始让组件知道断开已实际实现。这些传播终止是因为没有强制导入的绑定循环。
由于人为错误或客户需求激增导致的安全漏洞,许多不同类型的基础架构故障可能会影响云应用程序的正常运行。重配置操作可能由于许多不同原因(从硬件故障到凭证故障)而失败。本文主要研究由虚拟机故障导致的失败。
假设虚拟机在任何时候都可能出现故障,而云管理器能检测到这样的故障。当检测到故障时,云管理器首先通过删除故障虚拟机来更新活动系统的模型。然后云管理器清除缓冲区,删除来自或发送到故障虚拟机的所有消息。最后,云管理器警告受影响的虚拟机(连接到故障虚拟机)发送故障警报消息。
在接收到报告邻居虚拟机故障的故障警报消息后,虚拟机管理器清除缓冲区,并通过解除绑定和停止受影响的组件来更改其本地组件的当前状态。最后,关闭组件消息发送到包含连接到其关闭组件的虚拟机的所有虚拟机管理器。
当虚拟机管理器收到导致故障传播的关闭组件消息时,它会停止受影响的本地组件并向本地和远程发送该关闭消息。值得注意的是,可能发生多个虚拟机故障。当虚拟机已经处理涉及另一个虚拟机的故障(级联故障)时,也可能发生故障。在最坏的情况下,所有组件都会停止。
在本节中展示了算法如何在图1所示的Web应用程序的简单重新配置方案中工作。假设所有虚拟机上的所有组件都已启动。提供了新版本的SQLite数据库管理系统,决定将该组件升级到这个新版本。
在接收到移除组件消息时,虚拟机3向虚拟机2发送解除绑定所需的消息,请求从SQLite组件解除绑定IIS组件。当虚拟机2收到此消息时,它无法立即取消绑定,因为远程组件(Nginx)使用了IIS,因此它也向虚拟机1发送了一个解除绑定的必需消息。收到该消息后,虚拟机1管理器将停止Nginx组件,因为没有其他组件连接到该组件,然后从IIS组件中取消绑定Nginx组件。虚拟机1向虚拟机2发送确认消息,指示已实现断开连接。虚拟机1还向云管理器发送虚拟机停止消息,指示其组件不再启动。当虚拟机2收到解除绑定确认消息时,其管理器将停止IIS并将其与SQLite解除绑定。从虚拟机2向虚拟机3发送确认,并将虚拟机停止消息发送到云管理器。一旦虚拟机3收到确认消息,其管理器就会停止SQLite组件,并向云管理器发送一条确认消息,指示虚拟机也已停止。请注意,需要停止IIS和Nginx以保留体系结构不变量:已启动的组件无法连接到停止组件。
在删除SQLite之后,应用程序的组件Nginx和IIS处于关闭状态,但其分析组件和对象缓存是处于打开的状态。
现在考虑这样一个场景:云管理器在虚拟机3上添加新版本的SQLite组件(添加消息)以及添加新版本与IIS组件之间的绑定。虚拟机3可以立即启动SQLite组件,因为该组件不需要来自其他组件的任何服务(无import)。虚拟机3知道虚拟机2需要将其组件连接到SQLite的组件,因此虚拟机3管理器将带有连接信息的发送export消息发布到虚拟机2。收到后,虚拟机2管理器可以连接两个组件。虚拟机3管理器还向虚拟机2指示其SQLite组件已启动,并向虚拟机指示虚拟机3已启动。收到发送导出消息后,虚拟机2管理器将启动IIS组件。虚拟机2向虚拟机1发送export消息和已启动消息,因为虚拟机2管理器知道Nginx组件与IIS组件之间的依赖关系。同时云管理器会接收到虚拟机2的启动消息。虚拟机1管理器最终将Nginx绑定到IIS,启动Nginx组件,并通知云管理器虚拟机1也已启动。因此,系统恢复运行,所有组件再次处于活动状态。
假设虚拟机3发生故障,首先,云管理器检测到此故障,更新应用程序的当前模型,清除其缓冲区,并向虚拟机2发送故障警报消息。收到此消息后,虚拟机2管理器将清除其缓冲区并通过停止和取消绑定IIS组件来恢复其本地一致性。然后,它向虚拟机1发送关闭组件消息。收到此消息后,虚拟机1管理器将停止并取消绑定Nginx组件。两个虚拟机管理器还向云管理器发送消息,以让它知道它们不再启动。
选择Maude[4]来实现本研究的重配置算法,由于篇幅所限,此处便不展示具体的实现过程。使用Maude的线性时序逻辑(LTL)显式状态模型检查器(Eker等,2002)来分析给定应用程序模型和重配置方案。Maude的模型检查器允许我们检查从给定初始模型开始的每个可能行为是否满足给定的LTL属性。当初始状态的可到达状态集是有限时,它可用于检查重写系统的安全性和活跃性。无限状态系统中不变量的完全验证可以通过在原始无限状态系统的有限状态抽象(Meseguer等,2003)上验证它们,也就是说,在可达状态是有限的原始系统商值(system's quotient)上进行验证。定义了算法需要保持的属性,如表1所示。
表1 属性定义
在300个示例上验证重配置算法,示例是由具有不同大小和连接结构的典型多层Web应用程序组成的。由于篇幅所限,此处仅展示2个示例的实验结果,这两个示例详情如表2所示。表3显示了验证属性R1-R7的实验结果。对于每个应用程序模型,给出了这个7属性的验证时间。在单个执行路径之后,模拟时间在所有情况下都不到5毫秒。状态空间的大小取决于应用程序的大小及其复杂性。应用程序模型的大小由其虚拟机的数量、组件、组件数量、每个虚拟机中的本地绑定和远程绑定的数量。组件由三元组(A-B-C)表示,其中A、B和C分别是强制import,可选import和export的数量。
表2 应用程式模型详情
表3 实验结果
表格中没有显示应用程序的复杂性,理解为强制/可选进口和出口之间的绑定是多么复杂,尽管它在数字中清楚地反映出来。两个模型示例的大小非常相似,但它们的绑定非常不同。不同场景中的上升/下降的复杂性可能非常不同。例如,特定虚拟机的销毁可以通过传播引起许多(关闭)操作,而另一个虚拟机(例如,托管组件而没有任何导出的虚拟机)的销毁将不会产生任何附加操作。
提出了一种用于自动重配置云应用程序的算法,该算法不仅支持虚拟机实例化和组件启动,还支持虚拟机销毁和组件关闭。该算法具有可靠性,它检测虚拟机故障并使应用程序恢复全局一致状态。使用Maude的基于重写逻辑的语言实现了它,并使用Maude的统计模型检查器来分析算法。