本文已收录GitHub,更有互联网大厂面试真题,面试攻略,高效学习资料等git
微服务是近几年很是火热的架构设计理念,大部分人认为是 Martin Fowler 提出了微服务概念,但事实上微服务概念的历史要早得多,也不是 Martin Fowler 创造出来的,Martin只是将微服务进行了系统的阐述。不过不可否认 Martin 在推进微服务起到的做用,微服务能火,Martin 功不可没。github
微服务的定义相信你早已耳熟能详,参考维基百科,我就来简单梳理一下微服务的历史吧面试
- 2005 年:Dr. Peter Rodgers 在 Web Services Edge 大会上提出了“Micro-Web-Services”的概念。
- 2011 年:一个软件架构工做组使用了“microservice”一词来描述一种架构模式。
- 2012 年:一样是这个架构工做组,正式肯定用“microservice”来表明这种架构。
- 2012 年:ThoughtWorks 的 James Lewis 针对微服务概念在 QCon San Francisco2012 发表了演讲。
- 2014 年:James Lewis 和 Martin Fowler 合写了关于微服务的一篇学术性的文章,详细阐述了微服务。
因为微服务的理念中也包含了“服务”的概念,而 SOA 中也有“服务”的概念,咱们天然而然地会提出疑问:微服务与 SOA 有什么关系?有什么区别?为什么有了 SOA 还要提微服务?这几个问题是理解微服务的关键,不然若是只是跟风拿来就用,既不会用,也用很差,用了不但没有效果,反而还可能有反作用。shell
本文就来深刻理解微服务,究竟是银弹仍是焦油坑。数据库
对于了解过 SOA 的人来讲,第一次看到微服务这个概念确定会有所疑惑:为什么有了 SOA还要提微服务呢?等到简单看完微服务的介绍后,可能不少人更困惑了:这不就是 SOA吗?网络
关于 SOA 和微服务的关系和区别,大概分为下面几个典型的观点。架构
微服务是 SOA 的实现方式app
以下图所示,这种观点认为 SOA 是一种架构理念,而微服务是 SOA 理念的一种具体实现方法。例如,“微服务就是使用 HTTP RESTful 协议来实现 ESB 的 SOA”“使用 SOA 来构建单个系统就是微服务”和“微服务就是更细粒度的 SOA”。运维
微服务是去掉 ESB 后的 SOAide
以下图所示,这种观点认为传统 SOA 架构最广为人诟病的就是庞大、复杂、低效的 ESB,所以将 ESB 去掉,改成轻量级的 HTTP 实现,就是微服务。
微服务是一种和 SOA 类似但本质上不一样的架构理念
以下图所示,这种观点认为微服务和 SOA 只是有点相似,但本质上是不一样的架构设计理念。类似点在于下图中交叉的地方,就是二者都关注“服务”,都是经过服务的拆分来解决可扩展性问题。本质上不一样的地方在于几个核心理念的差别:是否有 ESB、服务的粒度、架构设计的目标等。
以上观点看似都有必定的道理,但都有点差异,到底哪一个才是准确的呢?单纯从概念上是难以分辨的,我来对比一下 SOA 和微服务的一些具体作法,再来看看到底哪种观点更加符合实际状况。
1.服务粒度
总体上来讲,SOA 的服务粒度要粗一些,而微服务的服务粒度要细一些。例如,对一个大型企业来讲,“员工管理系统”就是一个 SOA 架构中的服务;而若是采用微服务架构,则“员工管理系统”会被拆分为更多的服务,好比“员工信息管理”“员工考勤管理”“员工假期管理”和“员工福利管理”等更多服务。
2.服务通讯
SOA 采用了 ESB 做为服务间通讯的关键组件,负责服务定义、服务路由、消息转换、消息传递,整体上是重量级的实现。微服务推荐使用统一的协议和格式,例如,RESTful 协议、RPC 协议,无须 ESB 这样的重量级实现。Martin Fowler 将微服务架构的服务通信理念称为“Smart endpoints and dumb pipes”,简单翻译为“聪明的终端,愚蠢的管道”。之因此用“愚蠢”二字,其实就是与 ESB 对比的,由于 ESB 太强大了,既知道每一个服务的协议类型(例如,是 RMI 仍是 HTTP),又知道每一个服务的数据类型(例如,是 XML 仍是 JSON),还知道每一个数据的格式(例如,是 2017-01-01 仍是 01/01/2017),而微服务的“dumb pipes”仅仅作消息传递,对消息格式和内容一无所知。
3.服务交付
SOA 对服务的交付并无特殊要求,由于 SOA 更多考虑的是兼容已有的系统;微服务的架构理念要求“快速交付”,相应地要求采起自动化测试、持续集成、自动化部署等敏捷开发相关的最佳实践。若是没有这些基础能力支撑,微服务规模一旦变大(例如,超过 20 个微服务),总体就难以达到快速交付的要求,这也是不少企业在实行微服务时踩过的一个明显的坑,就是系统拆分为微服务后,部署的成本呈指数上升。
4.应用场景
SOA 更加适合于庞大、复杂、异构的企业级系统,这也是 SOA 诞生的背景。这类系统的典型特征就是不少系统已经发展多年,采用不一样的企业级技术,有的是内部开发的,有的是外部购买的,没法彻底推倒重来或者进行大规模的优化和重构。由于成本和影响太大,只能采用兼容的方式进行处理,而承担兼容任务的就是 ESB。
微服务更加适合于快速、轻量级、基于 Web 的互联网系统,这类系统业务变化快,须要快速尝试、快速交付;同时基本都是基于 Web,虽然开发技术可能差别很大(例如,Java、C++、.NET 等),但对外接口基本都是提供 HTTP RESTful 风格的接口,无须考虑在接口层进行相似 SOA 的 ESB 那样的处理。
综合上述分析,我将 SOA 和微服务对好比下:
所以,咱们能够看到,SOA 和微服务本质上是两种不一样的架构设计理念,只是在“服务”这个点上有交集而已,所以二者的关系应该是上面第三种观点。
其实,Martin Fowler 在他的微服务文章中,已经作了很好的提炼:
In short, the microservice architectural style is an approach todeveloping a single application as a suite of small services, eachrunning in its own process and communicating with lightweightmechanisms, often an HTTP resource API. These services are builtaround business capabilities and independently deployable by fullyautomated deployment machinery.
上述英文的三个关键词分别是:small、lightweight、automated,基本上浓缩了微服务的精华,也是微服务与 SOA 的本质区别所在。
经过前面的详细分析和比较,彷佛微服务本质上就是一种比 SOA 要优秀不少的架构模式,那是否意味着咱们都应该把架构重构为微服务呢?
其实否则,SOA 和微服务是两种不一样理念的架构模式,并不存在孰优孰劣,只是应用场景不一样而已。咱们介绍 SOA 时候提到其产生历史背景是由于企业的 IT 服务系统庞大而又复杂,改形成本很高,但业务上又要求其互通,所以才会提出 SOA 这种解决方案。若是咱们将微服务的架构模式生搬硬套到企业级 IT 服务系统中,这些 IT 服务系统的改形成本可能远远超出实施 SOA 的成本。
单纯从上面的对比来看,彷佛微服务大大优于 SOA,这也致使了不少团队在实践时不加思考地采用微服务——既不考虑团队的规模,也不考虑业务的发展,也没有考虑基础技术的支撑,只是以为微服务很牛就赶忙来实施,觉得实施了微服务后就什么问题都解决了,而一旦真正实施后才发现掉到微服务的坑里面去了。
咱们看一下微服务具体有哪些坑:
1.服务划分过细,服务间关系复杂
服务划分过细,单个服务的复杂度确实降低了,但整个系统的复杂度却上升了,由于微服务将系统内的复杂度转移为系统间的复杂度了。
从理论的角度来计算,n 个服务的复杂度是 n×(n-1)/2,总体系统的复杂度是随着微服务数量的增长呈指数级增长的。下图形象了说明了总体复杂度:
粗粒度划分服务时,系统被划分为 3 个服务,虽然单个服务较大,但服务间的关系很简单;细粒度划分服务时,虽然单个服务小了一些,但服务间的关系却复杂了不少。
2.服务数量太多,团队效率急剧降低
微服务的“微”字,自己就是一个陷阱,不少团队看到“微”字后,就想到必须将服务拆分得很细,有的团队人员规模是 5 ~ 6 我的,然而却拆分出 30 多个微服务,平均每一个人要维护 5 个以上的微服务。
这样作给工做效率带来了明显的影响,一个简单的需求开发就须要涉及多个微服务,光是微服务之间的接口就有 6 ~ 7 个,不管是设计、开发、测试、部署,都须要工程师不停地在不一样的服务间切换。
3.调用链太长,性能降低
因为微服务之间都是经过 HTTP 或者 RPC 调用的,每次调用必须通过网络。通常线上的业务接口之间的调用,平均响应时间大约为 50 毫秒,若是用户的一块儿请求须要通过 6 次微服
务调用,则性能消耗就是 300 毫秒,这在不少高性能业务场景下是难以知足需求的。为了支撑业务请求,可能须要大幅增长硬件,这就致使了硬件成本的大幅上升。
4.调用链太长,问题定位困难
系统拆分为微服务后,一次用户请求须要多个微服务协同处理,任意微服务的故障都将致使整个业务失败。然而因为微服务数量较多,且故障存在扩散现象,快速定位究竟是哪一个微服务故障是一件复杂的事情。下面是一个典型样例。
Service C 的数据库出现慢查询,致使 Service C 给 Service B 的响应错误,Service B 给Service A 的响应错误,Service A 给用户的响应错误。咱们在实际定位时是不会有样例图中这么清晰的,最开始是用户报错,这时咱们首先会去查 Service A。致使 Service A 故障的缘由有不少,咱们可能要花半个小时甚至 1 个小时才能发现是 Service B 返回错误致使的。因而咱们又去查 Service B,这至关于重复 Service A 故障定位的步骤……如此循环下去,最后可能花费了几个小时才能定位到是 Service C 的数据库慢查询致使了错误。
若是多个微服务同时发生不一样类型的故障,则定位故障更加复杂,以下图所示。
Service C 的数据库发生慢查询故障,同时 Service C 到 Service D 的网络出现故障,此时究竟是哪一个缘由致使了 Service C 返回 Error 给 Service B,须要大量的信息和人力去排查。
5.没有自动化支撑,没法快速交付
若是没有相应的自动化系统进行支撑,都是靠人工去操做,那么微服务不但达不到快速交付的目的,甚至还不如一个大而全的系统效率高。例如:
6.没有服务治理,微服务数量多了后管理混乱
信奉微服务理念的设计人员老是强调微服务的 lightweight 特性,并举出 ESB 的反例来证实微服务的优越之处。但具体实践后就会发现,随着微服务种类和数量愈来愈多,若是没有服务治理系统进行支撑,微服务提倡的 lightweight 就会变成问题。主要问题有:
若是以上场景都依赖人工去管理,整个系统将陷入一片混乱,最终的解决方案必须依赖自动化的服务管理系统,这时就会发现,微服务所推崇的“lightweight”,最终也发展成和ESB 几乎同样的复杂程度。