测试容错代码

时间:2010-05-03 09:09:28

标签: testing fault-tolerance

我目前正致力于服务器应用程序,我们已同意尝试并维持一定的服务水平。我们要保证的服务级别是:如果服务器接受了请求,并且服务器向客户端发送确认,我们要保证请求将发生,即使服务器崩溃。由于请求可以长时间运行并且确认时间需要很短,我们通过持久化请求,然后向客户端发送确认,然后执行各种操作来完成请求来实现。当执行操作时,它们也会被持久化,因此服务器知道启动时请求的状态,并且还有与外部系统的各种协调机制来检查我们日志的准确性。

这一切似乎都运行得相当好,但我们很难说有任何信念,因为我们发现很难测试我们的容错代码。到目前为止,我们已经提出了两个策略,但两者都不完全令人满意:

  • 让外部进程监视服务器代码,然后尝试在外部进程认为是测试中的适当点时将其终止
  • 为应用程序添加代码,使其崩溃某些已知的关键点

我对第一个策略的问题是外部进程无法知道应用程序的确切状态,因此我们无法确定我们是否遇到了代码中最棘手的问题。我的第二个策略的问题,虽然它给出了更多的控制权,但是我不喜欢让代码在我的应用程序中注入错误,即使是可选的编译等等。我担心过于容易看错注射点,让它滑入生产环境。

4 个答案:

答案 0 :(得分:3)

我认为有三种方法可以解决这个问题,如果可以的话,我可以为这些不同的代码段建议一套全面的集成测试,使用依赖注入或工厂对象在这些集成过程中产生破坏的操作。

其次,使用随机kill -9运行应用程序,禁用网络接口可能是测试这些内容的好方法。

我还建议测试文件系统故障。如何做到这一点取决于您的操作系统,在Solaris或FreeBSD上我会在文件中创建一个zfs文件系统,然后在应用程序运行时运行该文件。

如果您正在使用数据库代码,那么我建议也测试数据库的失败。

依赖注入的另一种替代方法,可能是我将使用的解决方案,是拦截器,您可以在代码中启用崩溃测试拦截器,这些将知道应用程序的状态并在正确的时间引入上面列出的故障,或者您可能想要创建的任何其他人。它不需要更改现有代码,只需要一些额外的代码来包装它。

答案 1 :(得分:2)

第一点的可能答案是将实验与外部过程相乘,以便增加影响有问题的代码部分的可能性。然后,您可以分析核心转储文件以确定代码实际崩溃的位置。

另一种方法是通过存根库或内核调用来提高可观察性和/或可命令性,即不修改应用程序代码。

您可以在维基百科的Fault Injection页面上找到一些资源,特别是 Software Implemented Fault Injection 部分。

答案 2 :(得分:2)

您对故障注入的关注不是一个基本问题。您只需要一种万无一失的方法来防止此类代码在部署中结束。一种方法是将故障注入器设计为调试器。即故障由过程外部的过程注入。这已经提供了一定程度的隔离。此外,大多数OS提供某种访问控制,除非特别启用,否则会阻止调试。在最原始的形式中,它通过将其限制为root,在其他操作系统上它需要特定的“调试权限”。当然,在生产过程中没有人会这样做,因此你的故障喷射器甚至不能在生产中运行。

故障注入器可以在特定地址设置断点,即功能或甚至代码行。然后你可以对此作出反应,例如通过在某个断点被击中三次后终止该过程。

答案 3 :(得分:1)

我刚刚写的和Justin一样:)

我建议在测试期间替换的组件可能是日志记录组件(如果你有一个,如果没有,我强烈建议实现一个......)。使用生成错误的代码替换它相对容易,并且记录器通常会获得足够的信息来了解当前的应用程序状态。

此外,确保测试代码不会投入生产似乎也是可行的。我会阻止条件编译,而是使用一些配置文件来选择日志记录组件。

使用“随机”杀戮可能有助于检测错误,但由于其不确定性而不适合进行系统测试。因此我不会将它用于自动测试。

相关问题