微服务的优缺点

本文来源于我在InfoQ中文站翻译的文章,原文地址是:http://www.infoq.com/cn/news/2014/06/microserviceshtml


近期一段时间以来,社区中环绕着微服务产生了许多争论,也充斥着大量的宣传。过去的10年间,咱们已经实现了许多笨重的SOA解决方式,微服务是业界期待已久的解决方式么?或者说微服务要比整体解决方式更加简单?编程

在讨论这些话题以前,咱们最好先对微服务下个定义。在题为微服务的文章中,做者James LewisMartin Fowler是这样定义微服务架构风格的: 网络

开发单个应用做为一系列小型服务的套件,当中每个服务都执行在本身的进程中,并且经过轻量级的机制实现彼此间的通讯,这通常是HTTP资源API。这些服务是环绕着业务功能构建的,并且可以经过全然本身主动化的部署机制进行独立部署。这些服务的集中式管理作到了最小化,每一种服务都可以经过不一样的编程语言进行编写,并且可以使用不一样的数据存储技术。

微服务的一些优点是显而易见的:架构

  • 每个服务都很easy,仅仅关注于一个业务功能。
  • 每个微服务可以由不一样的团队独立开发。
  • 微服务是松散耦合的。
  • 微服务可以经过不一样的编程语言与工具进行开发。

这些优点使得微服务看起来是很完美的解决方式,只是微服务难道就没有缺点么?负载均衡

Contino的CTO Benjamin Wootton正在基于微服务对一个系统进行架构设计,他遇到了很多困难,并且将遇到的这些问题发表在了题为Microservices - Not A Free Lunch!的文章中。如下是文章的一些摘要。框架

运维成本太高运维

故障恢复后,20个服务可能要占领40——60个进程,同一时候弹性问题也浮现出来了。在加入了负载均衡与消息中间件后,进程的数量还会持续添加。运维与编排所有这些服务是个“使人望而却步的任务”,Wootton说到:异步

实现所有这些需求需要高质量的监控与运维基础设施。保持一台应用server的持续执行就需要专人来负责,但现在咱们还得确保几10、甚至是几百个进程都处于执行状态、不能将磁盘空间耗尽、不能出现死锁,还要保证性能。这真是一个很棘手的任务。

运维的过程需要本身主动化,只是因为“并无多少框架和开源工具可以对此提供支持”,结果就是“使用微服务的团队要在他们编写具备业务价值的第一行代码前需要大量使用本身定义脚本或是进行开发以管理这些进程”。编程语言

DevOps是必须的分布式

Wootton以为实现微服务的组织需要DevOps,这是因为:

你不能简单地将经过这样的风格构建的应用抛给运维团队。开发团队需要很关注运维与产品,因为基于微服务的应用与其环境上下文是很紧密地集成到了一块儿的。

因为许多服务可能都需要本身的数据存储,所以开发人员还需要“搞清楚怎样部署、执行、优化以及支持各类NoSQL产品”。

接口不匹配

服务依赖于彼此间的接口进行通讯。改变一个服务的接口会对其它服务形成影响,Wootton谈到:

改动了契约一方的语法或是语义,那么所有其它服务都需要理解这个改变。在微服务环境下,这意味着简单的交叉改变会致使许多不一样的组件发生变化,这些组件需要以一种协调一致的方式进行公布。

固然了,咱们可以经过向后兼容的方式避免这些变化的发生,只是实际状况倒是业务驱动的需求让咱们无法实现分阶段的公布。

假设彼此协同的服务向前推动并且再也不同步了,比方说使用canary公布方式,那么改动消息格式的效果就难以可视化了。

代码反复

为了不将“同步耦合引入到系统中”,Wootton以为有时需要向不一样服务加入一些代码,这就会致使代码反复,而代码反复“是很很差的,因为每个代码实例都需要进行測试和维护”。一种解决方式是在服务间使用共享库,只是“在多语言环境下这便可不通了,并且引入了耦合就意味着服务需要并行公布来维护彼此间的隐式接口”。

分布式系统的复杂性

做为一种分布式系统,微服务引入了复杂性和其它若干问题,比方说“网络延迟、容错性、消息序列化、不可靠的网络、异步、版本号化、应用层中的负载变化等等”。

异步

Wootton以为微服务常常会使用异步编程、消息与并行,假设要求某个操做必须是同步且具备事务的,那么这就很复杂了,这要求咱们得“管理好相关联的ID以及分布式事务,将各类动做绑定在一块儿”。

測试

使用微服务架构时,測试是还有一个需要考虑的问题,因为“不论是手工測试仍是本身主动化測试,咱们都很难以一致的方式重现环境”,Wootton说到:

当加入了异步与动态消息负载后,要測试以这样的风格构建的系统就难上加难了,同一时候也没法对将要公布到生产的各类服务抱有信心。

咱们可以測试每个服务,只是在这样的动态环境下,很微妙的行为都会从服务间的交互中产生出来,这是难以作到可视化的,也不易想清楚,更没必要说全面的測试了。

Brady评论了Wootton的文章,谈到了他尝试从整体应用向微服务转变的经历:

正在从事的一个项目就在从一个整体应用向微服务迁移,咱们遇到了你在文章中提到的大量问题。最后有大量反复代码(因为这些服务是使用不一样语言和框架构建的),遇到了许多“隐式契约”问题。比方说,将一个服务的User数据映射到还有一个服务上(当中一个服务不必定像还有一个服务同样需要所有的数据)。尽管这样的方式有一些显而易见的优势,只是在使用以前必定要有很精心的规划才行。最后,咱们所採取的方式是对整体应用进行模块化(这样就可以在模块间共享代码仓库、部署和代码了,同一时候依旧保持良好的松散耦合的组件)并将一些模块放到本身独立的微服务中来实现独立的部署与管理,固然了,咱们仅仅在必要的状况下才这么作。

还有一位读者Dennis Ehle也分享了他在微服务方面的经验,他给出的结论是微服务是有代价的:

咱们眼下为一个客户实现了一个CD管道本身主动化框架,有450个开发人员,50个服务(或者叫微服务)。对于我来讲,这样的架构最迷人的地方在于这450个开发人员都不需要编写一行代码来支持顾客的用户界面。UX方面的工做是由一个不一样的小组完毕的。
尽管很灵活、风险小,并且节省了成本,这个客户也很喜欢这一点,直接的结果就是从整体架构全然迁移过来了,只是毋庸置疑的是,因为文中提到的众多因素,使用微服务仍是需要付出额外的成本的。

此外,读者Steve Willcox提到了微服务所引入的一些挑战:

做为从整体Java应用转换为SOA实现过程当中的一名技术领导,我遇到了文中提到的所有问题,只是相对于将其看做是问题,我将他们看做构建更好的软件的机会。

文中提到“需要大量的DevOps技术”,我以为这很好啊。这样,开发人员就有机会了解本身编写的代码是怎样执行的了。採用SOA实现会迫使你成为一名DevOps,服务团队开发人员本身作DevOps,而不像曾经那样“将东西丢给集中化的运维团队”。这对于让开发团队负责本身代码的运维来讲是积极的。

没错,相对于整体应用来讲,採用微服务会有许多其它的服务要构建、測试和部署,只是时至今日,这些事情应该都是本身主动化的了。仅仅要遵循一样的本身主动化模式,2个和20个的工做量事实上区别不大。

关于代码反复,读者Willcox以为结果事实上没那么差:

对于这一点,我过去是很纯粹的,以为所有的代码反复都是很差的,只是接下来我认识到这样的纯粹性有时会致使更高的代价,更复杂的系统。我现在就变得很实际了,简单性也是很重要的一个方面。我很承认Richard Gabriel在 The Rise of Worse is Better一文中对此的论述。

总而言之,微服务架构有许多吸引人的地方,只是在拥抱微服务以前,你需要认清它所带来的挑战。

查看英文原文:The Strengths and Weaknesses of Microservices