现在的位置: 首页 > 综合 > 正文

提升服务扩展性和冗余的八个编码方向

2014年01月04日 ⁄ 综合 ⁄ 共 1888字 ⁄ 字号 评论关闭

摘要:服务调整中的核心思想就是尽可能的提高其扩展性和冗余,然而怎么样编写才能让程序具备高的可扩展性。Mike Hadlow将其总结为:无状态、粗粒度API、幂等、容错、避免给实例特定的配置、监视、越简单越小越好,并一一发表了自己的5年架构设计的经验之谈。

在过去的5年,Mike Hadlow一直从事与服务架构的实施和调整。在其个人博客上发表了软件扩展设计的相关看法。

以下为译文

服务调整中一个核心思想就是尽可能的加强扩展性和冗余。为了实现这个思想就必须使服务器满足“可扩展”。这意味着什么?

对软件进行扩展我们可以通过两种手段:“横向”和“纵向”。

  • 纵向扩展着眼的是服务中的单个实例。最简单的实现方法就是将软件运行在性能更强的机器上,拥有更快的处理器以及更多的内存;然而在编码的过程中我们同样可以改善软件的性能。而公司最常见的方法就是使用LMAX。但是纵向扩展有着很多弊端:首先,成本的剧增;硬件性能每次提高,其价格都成指数性增长。其次,针对硬件提升做软件优化带来的成本同样相当之大。最重要的是,纵向扩展并不支持冗余;对应用程序进行纵向扩展完全将小的单点故障转换成大的单点故障。
  • 横向扩展。对比专注单个实例的性能,我们可以运行多个应用程序实例。而横向扩展的优势就是:取代购买一个更大、更昂贵的主机,我们只需要购买更多便宜的主机。通过使用合适的架构设计,我们可以进行大量的扩展。同样这也是许多大型互联网公司使用的手段,比如:Facebook、Google、Twitter等等。横向扩展同样带来了更好的冗余,单点故障将不会对整个系统带来影响。出于这个原因,横向扩展是建立高扩展性、冗余的首选方案。

这样的话,建立可扩展性系统的关键就是将其构造成横向扩展服务。为了做到这一点,我们需要遵循一些基本原则:

  • 无状态。任何储存了用于其它服务交互状态的服务都很难被扩展。举个例子:一个内存中包含了请求会话状态的网络服务,通常需要一个复杂的会话负载平衡器。想比之下一个无状态服务,仅仅简单做循环负载平衡就可以了。对于一个网络应用程序(或者服务)你需要避免使用会话状态或者任何静态的以及应用程序级别变量。
  • 粗粒度API。要做到无状态,服务包含的API最好只做单一交互。一个啰嗦的API,东面设置一些数据,西面做一些转换,最后在做结果的返回,这就意味着有状态的设计。服务将需要识别一个会话,然后在多个连续的调用中保持会话信息。对比单一的调用或者是通信,服务需要封装这些操作用到的全部信息才能完成运算。
  • 幂等。可扩展基础设施需要在竞争约束中做权衡,其中之一就是确保交付。基于多种原因,“至少一次”的保证永远比“只有一次”更为简单。如果你可以让应用程序实现同个消息的多样交互,那么扩展起来将变的异常简单。
  • 容错。如果想保证整个服务不会因为单点故障而崩溃,那么必须使用多个服务实例来实现冗余。你必须考虑到故障的发生,将服务和基础设施设计的具有高容错性。这里的观点就是:如果你不想服务崩溃,你必须做好了崩溃的准备。
  • 避免给实例特定的配置。一个可扩展服务应该被设计成各个实例的独立运行,不能将自己特殊化。不需要对一个实例进行区别其它实例的配置。这将包括针对服务特殊实例进行设计的通信机制,或者针对服务特殊实例的需求使用一些非约定协议。取而代之的是,我们应该依靠基础设施(负载均衡器、发布-订阅消息应用等)来管理一组服务之间的通信。
  • 简单的自动化部署。性能满载却不能进行部署,那么扩展的优势也就荡然无存了。必要时扩展系统必须可以自动的进行新实例的部署处理。
  • 监视。我们需要清楚服务的性能是否已经满载以便加入新的服务实例。监视一般涉及到基础设施;我们需要监视CPU、网络、内存的使用情况,在达到触发点后予以提醒。当触发内部触发器时,有些情况下引进特殊的应用程序提醒也是值得的,比如:内存序列中排队项达到一定的数量。
  • 越简单越小越好。对于任何软件项目,这都是个好的建议;与建立可扩展弹性系统更是息息相关。大型单片代码很难被监视和扩展,尽量把系统建立成多个小块,可以轻松单独的处理每个部分。确保服务使用非专属、通用标准的通信,可以避免供应商的锁定;考虑使用异构平台。HTTP JSON就是内部通信上很好的选择;因为每个平台都有HTTP和JSON库,并且有很多可以用于扩展系统的成品基础设施。

原文链接:
How to Write Scalable Services
 (仲浩/编译 王旭东/审校)

欢迎关注@CSDN云计算微博,了解更多云信息。

本文为CSDN编译整理,未经允许不得转载。如需转载请联系 market@csdn.net 

抱歉!评论已关闭.