(转)够了,不要一上来就把微服务说的神乎其神

[本文((转)够了,不要一上来就把微服务说的神乎其神)原始地址]http://xcoder.me/2017-06/architecture/[转]够了,不要一上来就把微服务说的神乎其神/

以下为转载自微信公众号:聊聊架构的文章片段

我们为微服务做好准备了吗?

在讨论架构选型时,人们经常会忽略这个问题,但其他却是最重要的。高级技术人员在了解了开发人员或业务人员的抱怨或痛点之后,开始在网上找寻找解决方案,他们总是宣称能解决这些问题。但在这些信誓旦旦的观点背后,有很多需要注意的地方。微服务有利也有弊。如果你的企业足够成熟,并且具有一定的技术积累,那么采用微服务所面临的挑战会小很多,并且能够带来更多正面好处。那么怎样才算已经为微服务做好准备了呢?Martin Fowler 在多年前表达了他对微服务先决条件的看法,但是从我的经验来看,大多数成长型初创公司完全忽略了他的观点。Martin 的观点是一个很好的切入点,让我们来逐个说明。
我敢说,大部分成长型初创公司几乎连一个先决条件都无法满足,更不用说满足所有的条件了。如果你的技术团队不具备快速配置、部署和监控能力,那么在迁移到微服务前必须先获得这些能力。接下来让我们更详细地讨论这些先决条件。

  • 快速配置
    如果你的开发团队里只有少数几个人可以配置新服务、虚拟环境或其它配套设施,那说明你们还没有为微服务做好准备。你的每个团队里都应该要有几个这样的人,他们具备了配置基础设施和部署服务的能力,而且不需要求助于外部。要注意,光是有一个 DevOps 团队并不意味着你在实施 DevOps,开发人员应该参与管理与应用程序相关的组件,包括基础设施。
    类似的,如果你没有灵活的基础设施(易于伸缩并且可以由团队里的不同人员来管理)来支撑当前的架构,那么在迁移到微服务前必须先解决这个问题。你当然可以在裸机上运行微服务,以更低的成本获得出众的性能,但在服务的运维和部署方面也必须具备灵活性。
  • 基本的监控
  • 快速部署
    如果你的单体系统没有一个很好的持续集成流程和部署系统,那么要集成和部署好你的微服务几乎是件不可能的事。想象一下这样的场景:10 个团队和 100 个服务,它们都需要进行手动测试和部署,然后再将这些工作与测试和部署一个单体所需要的工作进行对比。100 个服务会出现多少种问题?而单体系统呢?这些先决条件很好地说明了微服务的复杂性。
    Phil Calcado 在 Fowler 的先决条件清单里添加了一些东西,不过我认为它们更像是重要的扩展,而不是真正的先决条件。

本该在文章最前面的内容

  • 关于微服务的优势和劣势已经有过太多的讨论,不过我仍然看到很多成长型初创公司对它进行着“盲目崇拜”。冒着“重复发明轮子”的风险(Martin Fowler 已经写过“Microservice Premium”的文章),我想把我的一些想法写下来,在必要的时候可以发给客户,也希望能够帮助人们避免犯下我之前见过的那些错误。在进行架构或技术选型时,将网络上找到的一些所谓的最佳实践文章作为指南,一旦做出了错误的决定,就要付出惨重的代价。如果能够帮助哪怕一个公司避免犯下这种错误,那么写这篇文章都是值得的。

  • 如今微服务是个热门技术,微服务架构一直以来都存在(面向服务架构也算是吧?),但对于我所见过的大部分公司来说,微服务不仅浪费了他们的时间,分散了他们的注意力,而且让事情变得更糟糕。

  • 这听起来似乎很奇怪,因为大部分关于微服务的文章都会肯定微服务的各种好处,比如解耦系统、更好的伸缩性、移除开发团队之间的依赖,等等。如果你的公司有 Uber、Airbnb、Facebook 或 Twitter 那样的规模,那么就不存在什么问题。我曾经帮助一些大型组织转型到微服务架构,包括搭建消息系统和采用一些能够提升伸缩性的技术。不过,对于成长型初创公司来说,很少需要这些技术和微服务。

  • Russ Miles 在他的《让微服务失效的八种方式》这篇文章中表达了他的首要观点,而在我看来,这些场景却到处可见。成长型初创公司总是想模仿那些大公司的最佳实践,用它们来弥补自身的不足。但是,最佳实践是要视情况而定的。有些东西对于 Facebook 来说是最佳实践,但对于只有不到百人的初创公司来说,它们就不一定也是最佳实践。

  • 如果你的公司比那些大公司小一些,你仍然能够在一定程度上从微服务架构中获得好处。但是,对于成长型初创公司来说,大规模地迁移到微服务是一种过错,而且对技术人来说是不公平的。

  • 切记不要混淆了解耦和分布式二者的含义。由模块和接口组成的单体可以帮助你达到解耦的目的,而且你也应该这么做。你没有必要把应用程序拆分成分布式的多个独立服务,在模块间定义清晰的接口也能达到解耦的目的。

如果我们具备了这些先决条件呢?

就算具备了这些条件,仍然需要注意微服务的负面因素,确保微服务能够为你的业务带来真正的帮助。事实上,很多技术人员对微服务中存在的分布式计算谬论视而不见,但为了确保能够成功,这些问题是必须要考虑到的。对于大部分成长型初创公司来说,基于各种原因,他们应该避免使用微服务。

  • 运营成本的增加
    快速部署这一先决条件已经涵盖了一部分成本,除此之外,对微服务进行容器化(可能使用 Docker)和使用容器编排系统(比如 Kubernetes)也需要耗费很多成本。Docker 和 Kubernetes 都是很优秀的技术,但是对于大部分成长型初创公司来说,它们都是一种负担。我见过初创公司使用 rsync 作为部署和编排工具,我也见过很多的初创公司陷入运维工具的复杂性泥潭里,他们因此浪费了很多时间,而这些时间本来可以用于为用户开发更多的功能。
  • 你的应用会被拖慢
    如果你的单体系统里包含了多个模块,并且在模块间定义了良好的 API,那么 API 之间的交互就几乎没有什么额外开销。但对于微服务来说就不是这么一回事了,因为它们一般运行在不同的机器上,它们之间需要通过网络进行交互。这样会在一定程度上拖慢整个系统。如果一个请求需要多个服务进行同步的交互,那么情况会变得更加糟糕。我曾经工作过的一个公司,他们需要调用将近 10 个服务才能处理完某些请求。处理请求的每一个步骤都需要额外的网络开销和延迟,但实际上,他们可以把这些服务放在单个软件包里,按照不同的模块来区分,或者把它们设计成异步的。这样可以为他们节省大量的基础设施成本。
  • 本地开发变得更加困难
    如果你有一个单体应用,后端只有一个数据库,那么在开发过程中,在本地运行这个应用是很容易的。如果你有 100 个服务,并使用了多个数据存储系统,而且它们之间互相依赖,那么本地开发就会变成一个噩梦。即使是 Docker 也无法把你从这种复杂性泥潭中拯救出来。虽然事情原本可以简单一些,不过仍然需要处理依赖问题。理论上说,微服务不存在这些问题,因为微服务被认为是相互独立的。不过,对于成长型初创公司来说,就不是这么一回事了。技术人员一般需要在本地运行所有(或者几乎所有)的服务才能进行新功能的开发和测试。这种复杂性是对资源的巨大浪费。
  • 难以伸缩
    对单体系统进行伸缩的最简单方式是在负载均衡器后面部署单体系统的多个实例。在流量增长的情况下,这是一种非常简单的伸缩方式,而且从运维角度来讲,它的复杂性是最低的。你的系统在编排平台(如 Elastic Beanstalk)上运行的时间越长越好,你和你的团队就可以集中精力构建客户需要的东西,而不是忙于解决部署管道问题。使用合适的 CI/CD 系统可以缓解这个问题,但在微服务生态系统里,事情要复杂得多,而且这些复杂性所造成的麻烦已经超过了它们所能带来的好处。

本该优先考虑的方向

 如果你刚好处在一个成长型初创公司里,需要对架构做一些调整,而微服务似乎不能解决你的问题,这个时候应该怎么办?
 Fowler 提出的先决条件可以说是技术领域的能力成熟度模型,Fowler 在他的文章里对成熟度模型进行过介绍。如果这种成熟度模型对于公司来说是说得通的,那么我们可以按照 Fowler 提出的先决条件,并使用其他的一些中间步骤为向微服务迁移做好准备。下面的内容引用自 Fowler 的文章。

1
关键你要认识到,成熟度模型的评估结果并不代表你的当前水平,它们只是在告诉你需要做哪些工作才能朝着改进的目标前进。你当前的水平只是一种中间工作,用于确定下一步该获得什么样的技能。

 那么,我们该做出怎样的改进,以及如何达成这些目标?我们需要经过一些简单的步骤,其中前面两步就可以解决很多在向微服务迁移过程中会出现的问题,而且不会带来相关的复杂性。

  • 清理应用程序。确保应用程序具有良好的自动化测试套件,并使用了最新版本的软件包、框架和编程语言。
  • 重构应用程序,把它拆分成多个模块,为模块定义清晰的 API。不要让外部代码直接触及模块内部,所有的交互应该通过模块提供的 API 来进行。
  • 从应用程序中选择一个模块,并把它拆分成独立的应用程序,部署在相同的主机上。你可以从中获得一些好处,而不会带来太多的运维麻烦。不过,你仍然需要解决这两个应用之间的交互问题,虽然它们都部署在同一个主机上。不过你可以无视微服务架构里固有的网络分区问题和分布式系统的可用性问题。
  • 把独立出来的模块移动到不同的主机上。现在,你需要处理跨网络交互问题,不过这样可以让这两个系统之间的耦合降得更低。
  • 如果有可能,可以重构数据存储系统,让另一个主机上的模块负责自己的数据存储。
     在我所见过的公司里,如果他们能够完成前面两个步骤就算万事大吉了。如果他们能够完成前面两个步骤,那么剩下的步骤一般不会像他们最初想象的那么重要了。如果你决定在这个过程的某个点上停下来,而系统仍然具有可维护性和比刚开始时更好的状态,那么就再好不过了。
小英雄雨来 wechat
扫码二维码或搜索"架构演进之旅"订阅微信公众号
enjoy?donate!