利用云计算
Animoto是一种可以利用人工智能制作专业级音乐视频的应用程序。该程序运行于Amazon EC2上。在一段时间里,它只用了平均40台服务器。但是突然之间,Animoto变得很受欢迎,服务器的使用量也暴增到3500台。显然能进行这种规模扩展的应用是非常有弹性的,而且在不需要的时候可以不用花费多余的成本,确实很方便。
不要仅按目标优化
只根据预测的流量设计扩展性能很容易遇到危险情况。因为一则很难建立准确的模型,二则简化措施和乐观假设也会抵消一些变数。用Taleb的话来说,你不能“用模型的不确定性来设计确定的东西”。还有更大的危险:如果你的网络服务走向成功,那么你就会发现需求要比当初预计的多——虽然可能不会发生在明天的某个黄金时间段,却很可能在后天你最意想不到的时候发生。
充分利用测试
扩展性测试的理想情况应该是:运行在与生产环境完全一样的环境下,并且一直运行到发生故障。常用的故障测试是“波音777机翼负载测试”。除了分析首先发生故障的因素外,我们还要找出能让应用或服务在不使用故障部分的情况下运行的办法;然后再次测试,找到下一个故障点,有时候可能还要与 Monty Python的“黑骑士”场景做对比。
运行大型网络服务的一个难点就在于怎么实现一个高真实度的测试环境。虽然没有什么非常简单的办法,但是我们发现使用计算云中的虚拟资源可以让问题变得比较容易处理。在这种方式下,我们可以获得更高的真实度(运行相同的系统映像)和分离度,获得更高的测试灵活性,得到可供分析的结果或问题,并以更高效的方式使用资源。
几个重要的关注点
要构建一个可扩展的网络服务,最大的挑战就是在面临故障和极端访问模式时怎么处理耐久性、可靠性、性能和成本之间的平衡。
对于持久层来说,这个问题更为严重。亚马逊的Werner Vogels指出“最终一致性”可以解决这个大规模扩展的可靠系统问题。eBay的Dan Pritchett也 从另一个角度讨论了这个耐久性问题。
Sun的Craig Russell也讨论过ORM(对象关系映射层)问题。ORM得到了广泛采用,但同时也带来扩展上的问题。有了ORM,储存在持续层的数据是作为自然对象语言中的对象提供给应用程序,因此简化了持续层的实施,有利于关注点的分离。但ORM带来一个不可避免的副作用,就是缺乏扩展的透明度,无法得到查询的最终结构,无法了解读取多少数据,以及无法得知相关成本。
在构建表示层的时候应该以自动化、面向恢复而且无限制的方式设计扩展性。谷歌的Steve Souders在他的文章中对前端性能进行了详细讨论。他列举了一系列非常好的实践,这些实践除了可以减少延迟外,还能提高前端的扩展性。
还有网络。因为它有“增加价值”的功能,因此随着功能的增加,复杂性也会相应提高。现在的网络有许多与私有信息相关的功能。我们的目标就是使网络尽量简单、稳定、便宜。
最后,浏览网络的方式以及浏览的内容也会影响到网络服务的性能和可扩展性。Akamai Technologies公司的Tom Leighton在文章《提高网络性能》中从比表示层更深的角度评估了转换能力、延迟和可靠性对性能的影响,还介绍了利用内容呈现方式突破瓶颈的方法。
虽然构建可扩展的网络服务要面临许多困难,但是我们应该学会利用最近几年迅速发展起来的各种技术。或许现在的网络服务比以往面临着更多难题,但是很多情况下,我们都无须从零做起,因为我们可以利用已有的成果。