伸缩性和可用性反模式

这篇文章讲了伸缩性和可用性方面的反模式,也按照自己的理解翻译了一下,欢迎各位探讨。

1 单点失败(Single Point of Failure)

大部分的人都坚持在单一的设备上部署我们的应用,因为这样部署的费用会比较低,但是我们要清楚任何的硬件设备都会有失败的风险的,这种单点失败会严重的影响用户体验甚至是拖垮你的应用,因此除非你的应用能容忍失败带来的损失,否则得话应该尽量的避免单点风险,比如做冗余,热备等。

2 同步调用

同步调用在任何软件系统中都是不可避免的,但是我们软件工程师必须明白同步调用给软件系统带来的问题。如果我们将应用程序串接起来,那么系统的可用性就会低于任何一个单一组件的可用性。比如组件A同步调用了组件B,组件A的可用性为99.9%,组件B的可用性为99.9%,那么组件A同步调用组件B的可用性就是99.9% * 99.9%=99.8%。同步调用使得系统的可用性受到了所有串接组件可用性的影响,因此我们在系统设计的时候应该清楚哪些地方应该同步调用,在不需要同步调用的时候尽量的进行异步的调用(而我这里所说的异步是一种基于应用的异步,是一种设计上的异步,因为J2EE目前的底层系统出了JMS是异步API以外,其它的API都是同步调用的,所以我们也就不能依赖于底层J2EE平台给我们提供异步性,我们必须从应用和设计的角度引入异步性)

3 不具备回滚能力

虽然对应用的每个版本进行回滚能力测试是非常耗时和昂贵的,但是我们应该清楚任何的业务操作都有可能失败,那么我们必须为这种失败作好准备,需要对系统的用户负责,这就要求系统一定要具有回滚的能力,当失败的时候能进行及时的回滚。(说到回滚大家可能第一时间想到的是事务的回滚,其实这里的回滚应该是一种更宽泛意义的回滚,比如我们记录每一次的失败的业务操作,这样在出现错误的时候就不是依靠于事务这种技术的手段,而是通过系统本身的回滚能力来进行回滚失败业务操作)。

4 不记录日志

日志记录对于一个成熟稳定的系统是非常重要的,如果我们不进行日志记录,那么我就很难统计系统的行为。

5 产品质量依赖于测试

测试固然重要,但是软件系统的质量应该从设计支持就融入进来,而不是靠以后测试出问题,然后再修复。测试验证系统的行为和预期的一致,并且要保证在引入新的功能特性以后不会影响到系统的其它部门。因此希望在测试中发现性能,伸缩性和可怕用户体验的问题,然后再修复它是一种没有效果并且浪费时间和精力的不佳实践。因此我们需要在设计之初就关注系统的伸缩性和可用性,而不是依赖于测试。

6 无切分的数据库

随着系统规模的慢慢变大,我们就需要打破单一数据的限制,需要对其进行切分。

7 无切分的应用

系统在规模小的时候,也许感觉不出无切分的应用带来的问题,但是在目前互联网高速发展的时代,谁能保证一个小应用在一夜或者是几夜以后还是小应用呢?说不定哪天,我们就发现应用在突如其来的访问量打击的支离破碎。因此我们就需要让我们的系统和我们一样具有生命力,要想让系统具有应付大负载的能力,这就要求我们的应用具有很好的伸缩性,这也就要求应用需要被良好的切分,只有进行了切分,我们才能对单一的部门进行伸缩,如果应用是一块死板的话,我们是没有办法进行伸缩的。就好比火车一样,如果火车设计之初就把他们设计为一体的,那么我们还怎么对火车的车厢进行裁剪?因此一个没有切分的应用是一个没有伸缩性和没有可用性的应用。

8 将伸缩性依赖于第三方厂商

如果我们的应用系统的伸缩性依赖于第三方的厂商,比如依赖于数据库集群,那么我们就为系统的伸缩性埋下了一个定时炸弹。因为只有我们自己最清楚我们自己的应用,我们应该从应用和设计的角度出发去伸缩我们的应用,而不是依赖于第三方厂商的特性。

9 没有卓越文化
如果我们没有一种对待错误的优秀的文化,那么我很难保证同一个失败不发生第二次。因此我们需要一种确保同样的失败不发生第二次,这需要通过我们认真的对待每一次系统的失败,从中找出问题,而不是每次修修补补,能解决问题就行,如果这样,我们会发现,最终系统会变得遍体鳞伤,体无完肤。

原文:http://akfpartners.com/techblog/2009/05/12/scaling-availability-anti-patterns/

我觉得好像有些话我以前说过,不过保证之前没有看到过这篇文章,思想碰撞发生火花,乐趣就在这里,当然,还是老外说得有系统,说得更好,更有说服力。

曾经有句话:现在最缺的是并行计算程序员,虽然并行计算不一定是异步,但是异步思维首先是并行计算的开始。