在网络设备软件功能越来越复杂的今天,软件架构的可靠性占有非常重要的地位。没有一个可靠的软件架构,设备的可靠性将无从谈起。本文以H3CComware V7软件平台为例,介绍其采用的软件架构可靠性设计方法。
故障隔离和自愈
软件和Bug是一对伴生的兄弟。在一个庞大的软件系统中,即使是经验再丰富的程序员也无法保证没有任何Bug。硬件设备工作再稳定,如果不幸遇到软件Bug,也会引起异常,设备将无法正常工作。因此,故障隔离和自愈是软件设计中必须要考虑的问题。
故障隔离
故障隔离指在软件发生故障的时候,把故障造成的危害限制在最小范围内。为了达到此目标,Comware V7系统采用了Linux操作系统架构,绝大部分程序都是用户态程序。在Linux系统中,每个用户态程序拥有独立的进程空间,这样,一旦某个程序崩溃,并不会对其他的程序产生影响。我们称这种进程空间独立的架构设计为真正的模块化设计。
举例来说,路由协议中,OSPF是一个独立的用户态程序,IS-IS也是一个独立的用户态程序。运行期间,在某个极其特殊的情况下,OSPF走入某个代码异常分支处理流程,而在这里有一个Bug,运行到这就会引起整个OSPF进程崩溃。但IS-IS作为一个独立的路由协议,拥有独立的进程空间,它的运行不受任何影响,还可以正常运行。
故障自愈
故障自愈是让系统从故障中恢复到正常的工作状态。想要做到自愈,首先要发现错误。Comware V7系统有一套完整的进程运行状态监控机制,可以及时发现某个用户态程序"异常"。其基本工作原理如下
1. 所有的用户态程序都是系统初始化进程SCM(Service Control Manager)的子进程,SCM可以感知所有子进程的状态,一旦发现某个用户态程序崩溃,会主动回收它的资源,然后重新启动一个相同的用户态程序,接替崩溃的程序继续工作。
2. 有时一个用户态程序出了问题,无法正常工作,但还没有达到崩溃的地步,这时Comware系统中另外一套主动检测机制则起作用,过程如图1所示。
图1 进程故障发现与自愈过程
这个特殊的监控程序--Monitor,会周期性的检查各个用户态程序,主动向其他的用户态程序发送查询消息。其他的用户态程序在收到Monitor发来的这个消息后,会进行自检,并将自身的情况回应给Monitor,Monitor根据回复的消息得知某个用户态程序异常。在更为严重的异常情况下,用户态程序无法处理Monitor发来的消息,无法应答,Monitor在一段时间内没有收到应答,则判断这个用户态程序"异常"。
一旦监控进程发现某个用户态程序异常,就会通知SCM,SCM重复步骤一:回收它的资源,然后重新启动一个相同的用户态程序,接替崩溃的程序继续工作。
以上是对故障隔离与自愈机制的简单描述,Comware V7实际的工作方式要复杂的多。因为作为一个通信系统,各个独立的用户态程序之间并不是真正完全"孤立"的,它们之间会进行各种通信,协作完成网络设备的各种功能。所以,想要让重新运行的用户态程序真正的正常工作,还需要记录大量的程序正常工作时的状态信息,以便在重启以后,使其恢复到故障之前的正常状态。
同时,Comware V7拥有EEM(Embedded Event Manager)系统,系统管理员可以编写脚本,在异常发生时通过EEM触发这个脚本。这样,除上述所提到的中止异常程序重新运行的动作外,还能够按照脚本做更为复杂的动作,进行异常的远程上报、进一步的异常诊断分析,或者其他任何可以通过脚本触发的动作。这样,软件系统的可维护性也大大提升。
进程级备份
故障隔离与自愈功能,仅仅是单硬件系统上的行为。单硬件系统是指只有一个硬件主板的集中式系统(大部分盒式产品都属于这种情况),或者是分布式设备上的IO板,没有另外一块单板作为备份(如分布式设备的大部分接口板、业务板)。
在硬件有冗余备份的情况下,则需要进程级备份功能,也称为进程级HA。所谓进程级备份,是相对于单板级HA而言的,主要是指参与备份和倒换的实体不再是整个单板,而是单板上的一个个用户态进程。具体过程如图2所示。
图2 进程级HA倒换过程示意
在主板Master和备板Slave上都有相同的用户态程序OSPF在运行,一个工作在"主"状态,一个工作在"备"状态。初始化时,OSPF的"主"进程运行在Master Board上,"备"进程运行在Slave Board上。一旦"主"状态的程序异常,Master Board上的Monitor发现以后,就会通知本板的HA,同时也通知本板SCM。SCM关闭本端的异常程序,再重新启动,并使其工作在"备"状态;而HA接到通知后,就会通知Slave Board上的HA,Slave Board上的HA在通知本板的OSPF进程由"备"升级为"主"。
可见,进程级HA是在自愈机制的基础上,增加了进程级的主备倒换。那么它能带来哪些额外的好处呢?
自愈过程中,系统会中止"旧"程序、重启"新"程序,而新程序从启动到正常工作需要一段时间,在某些情况下可能会很长。在这段时间内,由于程序还不能够正常工作,无法完成同外界设备的交互,会引起网络上的振荡,造成流量中断。而进程级HA,工作在"备"状态的程序"时刻准备着"接替"主"用程序,一旦发现异常,立即切换工作状态,可以大大缩短切换时间,让外界几乎感觉不到设备曾经"切换过"。
进程级HA的另一个特点是可以通过人为控制,让一部分程序的"主"进程工作在Master Board上,另一部分程序的"主"进程工作在Slave Board上,这样就可以达到负载分担的效果,避免所有的"主"进程都工作在Master上,减轻Master的压力。
当然,进程级HA需要硬件支持冗余备份,因此适用于堆叠产品,或者分布式产品的主控板,分布式产品的接口板或其他集中式产品都不具备这样的硬件条件,因此还要依靠自愈来提升可靠性。
上述两种设计方法配合使用,极大的提升了Comware V7系统的可靠性,并使得Comware V7系统的可靠性设计变得非常富有"弹性",可以适应各种不同产品形态的需要。
结束语
本文介绍了比较直接的提升软件可靠性的机制和方法。实际上,在软件整体架构中,还有其他的提升可靠性的设计原则和方法,目标是设计出真正的高内聚低耦合的软件系统,减少在维护和功能扩展过程中,软件开发人员"犯错误"的机会。总之,良好的软件架构是软件可靠性的基础,是设备可靠性的最重要的保障。
Comware V7是H3C下一代的网络产品软件平台。Comware V7系统构建在Linux体系架构之上,对其中网络协议、通讯接口、分布式和高可靠性的方面进行了彻底的改造和扩展,以适应网络设备的需要。ComwareV7的绝大部分程序都运行在用户态,是真正的模块化系统,***程度的提升了软件系统整体的可靠性。同时,它支持多线程并发和抢占,支持SMP对称多处理,支持64位CPU,支持设备虚拟化,支持进程级备份以及完整的ISSU。