google和ebay微服务经验

摘自:http://www.infoq.com/cn/articles/ecosystems-of-microservices前端

多元化(polyglot)微服务是终极游戏

  • 大规模系统和多元化微服务最终必定会有所牵连。其中,多元化的意思是多种语言共同编写。
    • 建立于1995年的eBay共经历了3次架构变动。
      • eBay最先采用的是创始人花费两天时间所编写的Perl程序。
      • 以后,它开始使用由340万行C++代码所编写的程序。
      • 而后,eBay使用Java编写的分布式系统。
      • 如今的ebay仍然使用了大量Java,同时也使用了不少由多种代码编写的多元化微服务。
    • Twitter的架构变动过程相似。
      • 最先,Twitter采用的是Ruby on Rails。
      • 以后,它开始在前端使用JavaScript和Rails,然后端使用了大量的Scala代码。
      • 目前,Twitter也一样依赖于多元化微服务。
    • Amazon的架构变动一样相似。
      • 首先,它使用的是C++程序。
      • 而后,采用了Java和Scala两种语言。
      • 目前,Amazon也依靠多元化微服务。

服务的生态系统

  • 拥有多元化微服务的大规模生态系统运行状况如何呢?
    • eBay和Google采用了数百到数千个单独的服务来协同工做。
    • 如今的大规模系统都是以图的形式,而不是层次式或多个链接的形式来构成服务。
    • 服务之间相互依赖。
    • 只有旧的大规模系统采用高度集成的方式进行组织。

如何建立服务的生态系统

  • 目前运行良好的系统都是不断变革的产物。例如,Google历来没有对系统进行过集中的设计。当前的系统纯粹是适应时代和技术发展演变而成的。
  • 变异和天然选择。当一个新的问题出现,工程师一般选择利用已有的产品或服务来解决。所以,一个服务只有在不断的提供价值、不断被使用的状况下,才能避免被淘汰的命运。
  • 这些大规模系统采用了自底向上的设计方法。
  • 以Google App Enginer(GAE)中所使用的一些服务为例:数据库

     
    • Cloud Datastore嵌套依赖于如下服务:Megastore(一种结构化数据库)→Bigtable(一种集群级的结构化服务)→Colossus(一种集群化文件系统)→Borg(集群管理框架)。
    • 层次关系十分清楚。每一层都添加了下一层中不存在的一些东西。
    • 它采用自底向上的方法设计而成。首先是构建Colossus文件系统最后才是Cloud Datastore。
  • 这是没有架构师的架构。在Goolge,绝大部分的技术决策都是由小团队站在本身的角度所采纳,而非全局角度。编程

  • 2004年的eBay与之截然相反。当时,eBay采用了架构审查的形式,来对全部的大规模项目进行决策。其结果为:后端

    • 一般审查人员都是在没法改变项目的时候才介入。
    • 集中决策很快变成了一个瓶颈。它最大的影响就是在最后关头投出否决票。
  • eBay后来改成把经验丰富的工程师的想法放到审查板上,而后执行多个小团队都会用到的项目。把这些想法封装为员工能够本身使用的一个库、一个服务或者一些指南,而不是在最后关头进行决策。缓存

     

没有架构师的变革如何定义标准

  • 标准化能够在没有集中控制的状况下完成。
    • 标准化倾向于在不一样服务或者架构之间的通讯中产生。
  • 通讯一般会被标准化为:
    • 网络协议。Google采用Stubby协议,而eBay采用REST协议。
    • 数据格式。Google采用Protocol Buffer,而eBay使用JSON。
    • 接口语法标准。Google采用Protocol Buffer,而JSON由本身的语法。
  • 框架中一般会被标准化的通用模块包括:
    • 源码控制。
    • 配置管理。
    • 集群管理者。
    • 监控系统。
    • 警告系统。
    • 诊断工具
    • 全部可以脱离传统的组件。
  • 在一个充满变革的环境,标准是强制执行的:编码、提交、代码审查和代码检索。
  • 鼓励最佳实践的最好方式就是用实际的代码说话。这不是自顶向下的审查或者前卫的设计,而是某我的可以编写出让工做尽快完成的代码。
  • 鼓励是经过团队提供库的方式进行的。
  • 鼓励也经过工程师在支持X协议或Y协议时所依赖的服务进行。
  • Google在代码方面广为人知的是:任何一行代码在进行源码控制时,至少由一个额外的编码人员进行审查。这就是一种你们交流本身经验的良好方式。
  • 绝大部分状况下,Google的每个工程师均可以检索整个代码库。在编程人员规划如何实施一个事情时,代码库能够提供很好的参考。在1万个工程师不停工做的状况下,一个编程人员想作的事情可能已经被其余人提早完成了。这就使得一个好的项目可以经过代码库进行传播。固然,代码中的错误也一样可能会传播。
  • 为了鼓励通用项目和标准化的习惯,应使得作正确的事情简单,而作错误的事情要困难不少。
  • 服务之间是相互独立的。
    • 在Google,服务内部是没有标准化实现的。对于外部而言,服务就是一个黑盒子。
    • 存在习惯和通用库,可是没有编程语言的要求。最经常使用的四种语言为:C++、Go、Java和Python。不少不一样的服务也采用各类各样的语言编写。
    • 没有针对框架或持久力机制的标准化工做。
  • 在一个成熟的服务生态系统中,标准化的应该是图的弧度,而不是节点自己。定义一个通用的形状,而不是一个通用的实现。

建立新的服务

  • 新服务只有在他们的使用被证明的时候才被建立。
  • 一般,一种功能是为一种特别的使用场景而设计。而后,该功能被发现通用并且有效。
    • 造成一个团队,而后服务扩展到它本身单独的单元。
    • 只有当一个功能得到成功,并且适用于多种使用场景时,该状况才会发生。
  • 这些架构经过实用主义的方法进行发展。没有人能够命令某项服务应该被添加。
    • Google文件系统支持搜索引擎。分布式文件系统显然更容易变得通用。
    • Bigtable初始支持搜索引擎,但却没有被普遍使用。
    • Megastore设计的初衷是做为Google应用的存储机制,却被普遍使用。
    • GAE初始是由一群工程师为帮助设计网站而构建。
    • Gmail来源于Google内部常用的一个项目,而后才被推广到外部使用。

弃用过期的服务

  • 若是一个服务再也不被使用会怎么样?
    • 能够被从新定义目标的技术能够被从新使用。
    • 工程师能够被开除或者分配到其余组。
    • Google Wave不是一个成功的市场案例,可是其中的一些技术却应用到了Google App中。例如,支持多人编辑文档的应用就来自于Wave。
    • 一般状况下,核心服务会经历屡次的更新换代,而老的版本就会被抛弃。Google内部就常常发生这样的事情。

构建一个服务

  • 当服务拥有者在构建大规模多元化微服务的系统时,状况是什么样的呢?
  • 在一个大规模框架中执行很好的服务应该是:
    • 目的单一。它应该拥有一个定义良好的接口。
    • 模块化和独立性。也就是所谓的微服务。
    • 不该该共享一个持久层。

服务拥有者的目标是什么?

  • 知足客户需求。在合适的质量水平下提供必要的功能,同时知足协议的性能、维护稳定性和可靠性以及不断的改善服务。
  • 以最小的代价和努力知足需求。
    • 该目标以鼓励通用框架的使用为动机。
    • 每个团队拥有有限的资源,所以应该使用通用的工具、流程、组件和服务。
    • 它也鼓励好的操做行为。自动化服务的构建和部署。
    • 它同时鼓励资源的高效使用。

服务拥有者的责任是什么?

  • 谁构建谁运行。
    • 通常状况下,一个团队,尤为是一个小的团队,负责服务的设计、开发、部署和最后的销毁。
    • 没有额外的运维团队。
    • 团队拥有选择他们本身的技术、方法和工做环境的自由。
    • 团队要为他们的选择负责任。
  • 做为一个有限上下文的服务。
    • 一个团队的认知负载是有限的。
    • 不必理解生态系统中的其余服务。
    • 一个团队须要深度理解其服务和他们所依赖的服务。
    • 这意味着团队规模能够很小、很灵活。一个典型的团队是3-5我的。(如同美国海军陆战队,一个小队包含4个士兵。)
    • 如此小的团队规模意味着团队内的沟通能够很是顺畅。
    • Conway法则能够很好的发挥优点。小团队一般会构建一些小的组件。

不一样服务间的关系如何?

  • 即便是在同一公司内,不一样服务间的关系也如同厂商和客户的关系。
  • 尽可能友好并合做,可是必定要慎重对待服务间的关系。
  • 必定要清楚所属关系。
  • 必定要明确每一个人的分工。定义一个明确的接口,并维护好。
  • 客户能够选择是否使用该服务是调整激励的有效手段。经过客户来鼓励服务朝着正确的方向发展。这也是新服务构建的方式之一。
  • 定义SLA。由于服务提供商向客户提供了必定的保证,客户能够依赖该服务。
  • 使用服务的团队须要支付服务费用。
    • 向服务支付费用能够带来经济上的激励。它能够刺激提供商和客户有效利用资源。
    • 当东西免费时,人们老是不懂得珍惜。
    • 例如,一个内部客户曾无偿使用GAE,并使用了大量资源。要求他们更加高效的使用资源被证明并无论用。可是,在引入收费机制一周后,他们很快就可以经过1-2处的简单修改,减小GAE 90%的资源消耗。
    • 并不是使用GAE的团队不懂得珍惜。他们有本身更应该关注的方面,所以优化GAE的使用并不在他们的目标列表中。然而,事实证实,更加高效的架构可以带来更好的反应时间。
    • 付费也可以刺激服务提供商来保证服务质量。不然,一个内部的客户也可能转而使用其余服务。付费直接带来好的开发和管理项目。代码审查就是一个例子。Google的超大规模设计和测试系统是另一个例子。Google天天都会运行百万次的自动化测试。一旦代码被版本库接收,全部相关代码的接收测试就会被运行。这种方法能够很好的帮助小团队维护服务质量。
    • 一个返利模型能够很好的鼓励小的迭代式变化。小的变化更容易理解。而代码变化的影响是非线性的。一千行代码的变化所带来的风险毫不止一百行代码所带来风险的10倍,而是要100倍左右。
  • 维护接口的全正向/逆向兼容。
    • 绝对不要破坏客户端代码。
    • 这意味着维护多个接口版本。在一些状况下,它意味着维护多个部署:一个用于新版本,其余的用于老的版本。
    • 由于小的增量变化,模型接口一般不会被修改。
  • 拥有一个显式的丢弃策略。服务提供商主动把全部的用户从版本N升级到版本N+1。

操做大规模服务

  • 做为一个服务提供商,操做多元化微服务的大规模系统中的服务是怎样的呢?
    • 可预测的性能是基本要求。
      • 大规模服务很容易出现性能上的变化。
      • 性能的可预测性要远比平均性能重要的多。
      • 没法保证性能的低延迟根本就不能算是低延迟。
      • 当服务提供可预测的性能时,客户更容易针对服务进行编程。
      • 当一个服务使用不少其余的服务来完成相关工做时,延迟最大的服务决定了该服务的性能。
      • 以平均延迟为1ms、最大延迟以0.001%的几率为1s的服务为例:
      • 调用一次该服务就意味着0.01%几率时间延后。
      • 那么,对于一个Google所采用的包含5000台机器的大规模服务而言,延后时间几率就为50%。
      • 例如,内存缓存相关的问题会以百万分之一的几率被追踪到一个底层数据结构的从新分配事件。但延迟出现大的抖动时,这个问题就会浮现到较高的层。然而,底层的细节对于大规模系统才十分重要。
    • 深度的可靠性。
      • 服务中断通常都是人为操做引发,而非硬件或软件错误。
      • 必定要能够应对机器、集群和数据中心的失效。
      • 当使用其余服务时,要实现负载均衡和流量控制
      • 支持快速回滚操做。
      • 增量部署。
      • 不要一次就部署到全部的机器。选择一个系统,把新版本的软件部署上去,而后观察系统工做状况如何。
      • 若是工做状况良好,就把部署的机器规模扩张到10%,而后20%,最后才是全部的机器。
      • 若是部署到50%时出现问题,要可以进行回滚操做。
      • eBay利用特征选项来解耦合代码部署和特征部署。一般状况下,首先关闭特征,而后部署代码,最后再选择打开或关闭特征。这使得代码能够在新的特征打开以前被正确部署。同时,这也意味着,若是新的特征存在bug、性能问题或者业务问题,特征能够在不部署新代码的状况下被关闭。
    • 警告可能会多,但监控却永远不会多。

反模式服务

  • 超级服务:
    • 其实,客户想要的是一个拥有小服务的生态系统。
    • 超级服务难以去理清、扩展、变化,也会构造出更多的上游和下游的依赖。
  • 共享的持久化
    • 在分层模型中,服务放置在应用层,而持久化层则是一个提供给应用的通用服务。
    • eBay也采用了一样的方法,可是无论用。它破坏了服务的封装。应用程序能够经过升级数据库“黑”进服务。它最终会从新引进多个服务。共享数据库不容许松耦合服务。
    • 微服务经过变得小、隔离和独立来预防该问题,也经过这种方式来保证生态系统健康成长。
相关文章
相关标签/搜索