阿里巴巴什么是微服务架构构到底有多

SOA和微服务架构的区别
<span type="1" blog_id="1878025" userid='
分享到朋友圈
喜欢我的文章,请分享到朋友圈51CTO旗下网站
微服务与SOA之间差了一个ESB
微服务(micro services)这个概念不是新概念,很多公司已经在实践了,例如亚马逊、Google、FaceBook,Alibaba。微服务架构模式(Microservices Architecture Pattern)的目的是将大型的、复杂的、长期运行的应用程序构建为一组相互配合的服务,每个服务都可以很容易得局部改良。 Micro这个词意味着每个服务都应该足够小,但是,这里的小不能用代码量来比较,而应该是从业务逻辑上比较――符合SRP原则的才叫微服务。
作者:翻译:杜琪来源:dockone| 11:08
【原文编者的话】微服务只是最近提出的概念,实际上很多巨头公司(FB、Twitter、AWS等)已经在亲身实践。微服务并不是银弹,但是我们可以参考它的思想来解决自己遇到的问题。对于已经找准市场,业务即将或者马上就要急剧发展的创业公司,适合使用基于微服务的软件架构。
今天阅读了两篇关于微服务的文章,总结一些笔记,简单翻译了一篇文章。说明:并没有严格按照原文一字语句翻译,有部分自己的理解,还有部分是意译。
微服务(micro
services)这个概念不是新概念,很多公司已经在实践了,例如亚马逊、Google、FaceBook,Alibaba。微服务架构模式(Microservices
Architecture Pattern)的目的是将大型的、复杂的、长期运行的应用程序构建为一组相互配合的服务,每个服务都可以很容易得局部改良。
Micro这个词意味着每个服务都应该足够小,但是,这里的小不能用代码量来比较,而应该是从业务逻辑上比较&&符合SRP原则的才叫微服务。
暂且不讨论大小问题,读者朋友你首先要考虑的是如何解决目前技术团队遇到的开发问题、部署问题。正是在解决这些问题的过程中,才渐渐总结提炼出了微服务架构模式的概念。
微服务跟SOA有什么区别呢,可以把微服务当做去除了ESB的SOA。ESB是SOA架构中的中心总线,设计图形应该是星形的,而微服务是去中心化的分布式软件架构。
接下来会讨论以下几个话题:
应用微服务的动机,跟传统巨石应用的比较
微服务的优点与缺点
应用微服务架构设计时可能遇到的关键问题(内部服务通信、分布式数据管理)
一、巨石(monolith)应用
web应用程序发展的早期,大部分web工程是将所有的功能模块(service
side)打包到一起并放在一个web容器中运行,很多企业的Java应用程序打包为war包。其他语言(Ruby,Python或者C++)写的程序也有类似的问题。
假设你正在构建一个在线商店系统:客户下订单、核对清单和信用卡额度,并将货物运输给客户。很快,你们团队一定能构造出如下图所示的系统。
这种将所有功能都部署在一个web容器中运行的系统就叫做巨石型应用。巨石型应用有很多好处:IDE都是为开发单个应用设计的、容易测试&&在本地就可以启动完整的系统、容易部署&&直接打包为一个完整的包,拷贝到web容器的某个目录下即可运行。
但是,上述的好处是有条件的:应用不那么复杂。对于大规模的复杂应用,巨石型应用会显得特别笨重:要修改一个地方就要将整个应用全部部署(PS:在不同的场景下优势也变成了劣势);编译时间过长;回归测试周期过长;开发效率降低等。另外,巨石应用不利于更新技术框架,除非你愿意将系统全部重写(代价太高你愿意老板也不愿意)。
二、巨石应用的拆分
详细一个网站在业务大规模爬升时会发生什么事情?并发度不够?OK,加web服务器。数据库压力过大?OK,买更大更贵的数据库。数据库太贵了?将一个表的数据分开存储,俗称&分库分表&。这些都没有问题,good
job。不过,老外的抽象能力比我们强,看下图Fig2。
这张图从三个维度概括了一个系统的扩展过程:(1)x轴,水平复制,即在负载均衡服务器后增加多个web服务器;(2)z轴扩展,是对数据库的扩展,即分库分表(分库是将关系紧密的表放在一台数据库服务器上,分表是因为一张表的数据太多,需要将一张表的数据通过hash放在不同的数据库服务器上);(3)y轴扩展,是功能分解,将不同职能的模块分成不同的服务。从y轴这个方向扩展,才能将巨型应用分解为一组不同的服务,例如订单管理中心、客户信息管理中心、商品管理中心等等。
将系统划分为不同的服务有很多方法:(1)按照用例划分,例如在线商店系统中会划分出一个checkout
UI服务,这个服务实现了checkout这个用例;(2)按照资源划分,例如可以划分出一个catlog服务来存储产品目录。
服务划分有两个原则要遵循:(1)每个服务应该尽可能符合单一职责原则&&Single Responsible
Principle,即每个服务只做一件事,并把这件事做好;(2)参考Unix命令行工具的设计,Unix提供了大量的简单易用的工具,例如grep、cat和find。每个工具都小而美。
最后还要强调:系统分解的目标并不仅仅是搞出一堆很小的服务,这不是目标;真正的目标是解决巨石型应用在业务急剧增长时遇到的问题。
对于上面的例子,按照功能和资源划分后,就形成下面图3的架构图。分解后的微服务架构包含多个前端服务和后端服务。前端服务包括Catalog
UI(用于商品搜索和浏览)、Checkout
UI(用于实现购物车和下单操作);后端服务包括一些业务逻辑模块,我们将在巨石应用中的每个服务模块重构为一个单独的服务。这么做有什么问题呢?
三、微服务架构的优点与缺点
每个服务足够内聚,足够小,代码容易理解、开发效率提高
服务之间可以独立部署,微服务架构让持续部署成为可能;
每个服务可以各自进行x扩展和z扩展,而且,每个服务可以根据自己的需要部署到合适的硬件服务器上;
容易扩大开发团队,可以针对每个服务(service)组件开发团队;
提高容错性(fault isolation),一个服务的内存泄露并不会让整个系统瘫痪;
系统不会被长期限制在某个技术栈上。
《人月神话》中讲到:没有银弹,意思是只靠一把锤子是盖不起摩天大楼的,要根据业务场景选择设计思路和实现工具。我们看下为了换回上面提到的好处,我们付出(trade)了什么?
开发人员要处理分布式系统的复杂性;开发人员要设计服务之间的通信机制,对于需要多个后端服务的user
case,要在没有分布式事务的情况下实现代码非常困难;涉及多个服务直接的自动化测试也具备相当的挑战性;
服务管理的复杂性,在生产环境中要管理多个不同的服务的实例,这意味着开发团队需要全局统筹(PS:现在docker的出现适合解决这个问题)
应用微服务架构的时机如何把握?对于业务还没有理清楚、业务数据和处理能力还没有开始爆发式增长之前的创业公司,不需要考虑微服务架构模式,这时候最重要的是快速开发、快速部署、快速试错。
四、微服务架构的关键问题
1. 微服务架构的通信机制
(1)客户端与服务器之间的通信
在巨石型架构下,客户端应用程序(web或者app)通过向服务端发送HTTP请求;但是,在微服务架构下,原来的巨石型服务器被一组微服务替代,这种情况下客户端如何发起请求呢?
如图4中所示,客户端可以向micro service发起RESTful
HTTP请求,但是会有这种情况发生:客户端为了完成一个业务逻辑,需要发起多个HTTP请求,从而造成系统的吞吐率下降,再加上无线网络的延迟高,会严重影响客户端的用户体验。
为了解决这个问题,一般会在服务器集群前面再加一个角色:API
gateway,由它负责与客户度对接,并将客户端的请求转化成对内部服务的一系列调用。这样做还有个好处是,服务升级不会影响到客户端,只需要修改 API
gateway即可。加了API gateway之后的系统架构图如图5所示。
(2)内部服务之间的通信
内部服务之间的通信方式有两种:基于HTTP协议的同步机制(REST、RPC);基于消息队列的异步消息处理机制(AMQP-based message
Dubbo是阿里巴巴开源的分布式服务框架,属于同步调用,当一个系统的服务太多时,需要一个注册中心来处理服务发现问题,例如使用ZooKeeper这类配置服务器进行服务的地址管理:服务的发布者要向ZooKeeper发送请求,将自己的服务地址和函数名称等信息记录在案;服务的调用者要知道服务的相关信息,具体的机器地址在ZooKeeper查询得到。这种同步的调用机制足够直观简单,只是没有&订阅&&推送&机制。
AMQP-based的代表系统是Kafka、RabbitMQ等。这类分布式消息处理系统将订阅者和消费者解耦合,消息的生产者不需要消费者一直在线;消息的生产者只需要把消息发送给消息代理,因此也不需要服务发现机制。
两种通信机制都有各自的优点和缺点,实际中的系统经常包含两种通信机制。例如,在分布式数据管理中,就需要同时用到同步HTTP机制和异步消息处理机制。
2. 分布式数据管理
(1)处理读请求
在线商店的客户账户有限额,当客户试图下单时,系统必须判断总的订单金额是否超过他的信用卡额度。信用卡额度由CustomerService管理、下订单的操作由OrderService负责,因此Order
Service要通过RPC调用向Customer Service请求数据;这种方法能够保证每次Order
Service都获取到准确的额度,单缺点是多一次RPC调用、而且Customer Service必须保持在线。
还有一种处理方式是,在OrderService这边存放一份信用卡额度的副本,这样就不需要实时发起RPC请求,但是还需要一种机制保证&&当Customer
Service拥有的信用卡额度发生变化时,要及时更新存放在Order Service这边的副本。
(2)处理更新请求
当一份数据位于多个服务上时,必须保证数据的一致性。
分布式事务(Distributed transactions)使用分布式事务非常直观,即要更新Customer
Service上的信用卡额度,就必须同时更新其他服务上的副本,这些操作要么全做要么全不做。使用分布式事务能够保证数据的强一致,但是会降低系统的可用性&&所有相关的服务必须始终在线;而且,很多现代的技术栈并不支持事务,例如REST、NoSQL数据库等。
基于事件的异步更新(Event-driven asynchronous updates) Customer
Service中的信用卡额度改变时,它对外发布一个事件到&message
broker(消息代理人)&;其他订阅了这个事件的服务受到提示后就更新数据。事件流如图6所示。
五、重构巨石型应用
在实际工作中,很少有机会参与一个全新的项目,需要处理的差不多都是存在这样那样问题的复杂、大型应用。这时候如何在维护老服务的同时,将系统渐渐重构为微服务架构呢?
不要让事情更坏,有新的需求过来时,如果可以独立开发为一个服务,就单独开发,然后为老服务和新服务直接编写胶水代码(Glue
Code)&&这个过程不容易,但这是分解巨型服务的第一步,如图7所示;
识别巨石型应用中的可以分离出来当做单独服务的模块,一般适合分离的模块具有如下特点:两个模块对资源的需求是冲突的(一个是CPU密集型、一个是IO密集型);授权鉴定层也适合单独分离出一个服务。每分离出一个服务,就需要编写对应的胶水代码来与剩下的服务通信,这样,在逐渐演进过程中,就完成了整个系统的架构更新。
关于重构,有篇文章推荐大家阅读&&推倒重来的讲究,关于重构有很多可以写的,希望我能快速进步,多写点总结与大家分享。
微服务并不是治百病的良药,也不是什么新的技术,我从中学到的最大的一点就是scale
cube,从这个坐标轴出发去考虑大规模系统的构建比较容易分析和实践。
原文链接:
【编辑推荐】
【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条头条关注热点头条
24H热文一周话题本月最赞
讲师:874人学习过
讲师:528人学习过
讲师:706人学习过
精选博文论坛热帖下载排行
本书对开发XML应用程序给予了详细指导,其中一些应用程序甚至对于您来说是完全陌生的。这些应用程序包括XML 1.0,以及与XSLT、XQuery和XPat...
订阅51CTO邮刊登录以解锁更多InfoQ新功能
获取更新并接收通知
给您喜爱的内容点赞
关注您喜爱的编辑与同行
966,690 十二月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
微服务架构成功之路
微服务架构成功之路
9&他的粉丝
日. 估计阅读时间:
:开启与Netflix、微软、ThoughtWorks等公司的技术创新之路!
亲爱的读者:我们最近添加了一些个人消息定制功能,您只需选择感兴趣的技术主题,即可获取重要资讯的。
Author Contacted
语言 & 开发
206 他的粉丝
架构 & 设计
543 他的粉丝
93 他的粉丝
37 他的粉丝
微服务架构
15 他的粉丝
2334 他的粉丝
2384 他的粉丝
3 他的粉丝
相关厂商内容
相关赞助商
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
微服务和SOA到底有什么关系?
开发觉得这个不错,可是运维不这么认为。
开发觉得这个不错,可是运维不这么认为。
Re: 微服务和SOA到底有什么关系?
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
架构 & 设计
文化 & 方法
InfoQ.com及所有内容,版权所有 &#169;
C4Media Inc. InfoQ.com 服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
找回密码....
InfoQ账号使用的E-mail
关注你最喜爱的话题和作者
快速浏览网站内你所感兴趣话题的精选内容。
内容自由定制
选择想要阅读的主题和喜爱的作者定制自己的新闻源。
设置通知机制以获取内容更新对您而言是否重要
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。51CTO旗下网站
深度剖析微服务架构的九大特征
微服务架构这个术语在过去几年渐成热门,它把一种特定的软件应用的设计方法描述为能够独立部署的服务的套件。尽管缺乏对这一架构类型的准确定义,但是在业务能力、自动化部署、智能端点、语言和数据的去中心化控制等方面,已经形成了某些普遍特征。
作者:James Lewis
Martin Fowler来源:| 16:23
微服务架构这个术语在过去几年渐成热门,它把一种特定的软件应用的设计方法描述为能够独立部署的服务的套件。尽管缺乏对这一架构类型的准确定义,但是在业务能力、自动化部署、智能端点、语言和数据的去中心化控制等方面,已经形成了某些普遍特征。
微服务,另一个在软件架构领域津津乐道的新词。尽管我们本能上倾向于对它不屑一顾,然而这一专业术语描述了一种目前越来越吸引人的软件系统的风格。我们已经看到近年来有许多项目使用了此类型,结果很鼓舞人心;因而对于我的诸多同事来说,这也就成为他们构建企业级应用时候的首选。然而,当前并没有很多信息来描述什么是微服务,以及如何使用它。
简而言之,微服务架构把一个应用作为一套微服务来开发,这些微服务能运行自己的进程,采用 HTTP Resource API
这样的轻量级机制进行通信。这些微服务围绕着业务能力构建,能够通过完全自动化的部署体系独立部署。这些服务仅有最低限度的中心化管理,用不同的编程语言写成,使用不同的数据存储技术。
要说明微服务,与一体化应用做比较能有助于理解:一体化应用是被当作一个单元来构建的。企业级应用的构建通常包括三部分:客户端用户界面(由 HTML
页面和运行在用户机器上的浏览器里的 javascript
构成)、数据库(由各种表格构成,这些表格被插入到一个通用的关系数据库管理系统里),以及服务器端应用。服务器端应用处理 HTTP
请求,执行域名逻辑、从数据库提取并更新数据,以及选择并填充要被发送到浏览器的 HTML
视图。这个服务器端应用就是个庞然大物&&逻辑单一、可执行。系统有任何修改,都需要重新构建并部署新版本的服务器端应用。
构建这样的系统,一体化服务就是非常适合的方法。所有处理请求的逻辑都运行在单个进程中,能够让你使用语言的基本功能从而把应用划分成不同门类、功能和命名空间。出于某种原因,你能够在开发者的电脑上运行和测试应用,使用部署管道来确保各种修改被正确地测试并部署到生产中。借助负载均衡器,你能够通过运行更多实例来横向扩展这一巨型应用。
一体化应用获得了成功,但是渐渐地,随着更多的应用被部署到云平台,人们的挫败感渐增。更新周期被紧紧绑定&&即便是应用中一个很小部分的改变,也需要整个应用的重构和部署。随着时间推移,保持一个良好的模块化架构也日益困难,牵一发而动全身。一旦要进行扩展,就必须整体扩展,而不能仅仅扩展其中到一部分模块,也就需要更多的资源。
图 1:一体化 vs 微服务
这种情况最后进化为微服务架构:把应用作为一组服务来构建。这些服务能够独立部署和扩展,每个服务提供一个坚实的模型边界,甚至可以用不同的程序语言来写这些服务。当然他们也能被不同的团队来管理。
我们无意鼓吹微服务是新事物或者具有创新性,它植根于 Unix
的设计主旨。不过我们相信并没有很多人思考过微服务架构;如果许多软件开发使用了微服务,那它们的境况就会更好。
微服务架构的特征
我们不能给微服务架构下准确的定义,但是我们可以尝试总结一些通用特征。并不是所有的微服务架构完全符合下文列出的这些特征,不过我们可以预计大部分微服务架构能符合大多数。作为这个松散社区的活跃分子,我们(指两位作者)将尝试描绘我们在工作和我们熟悉的团队中看到的情况。
通过服务实现组件化
我们已经在软件行业浸淫多年,一直期望能够通过拼插组件的方式来构建系统,而不是采用我们在物理世界里常见的方式。在过去的几十年里,我们已经见证了多数语言平台的公共库的汇编已经取得了长足的进步。
谈及组件,要给它下定义并非易事。我们认为,一个组件就是软件的一个单元,能够被独立替换和升级。
微服务架构也会用到库,不过组件化软件的方式是把软件分解为服务。我们把库定义为一个程序中互相连接的组件,调用内存函数,同时这些服务是进程外部的组件,通过网页服务请求或者远程调用通信的方式进行通信。(这与面向对象编程中的服务对象的概念并不相同)
把服务当作组件(而非库)来使用的一大原因在于服务能够独立部署。如果你的应用在单个进程中包含多个库,那对其中任何一部分的改动都会导致重新部署整个应用。如果该应用分解为多个服务,那么可以预计,单个服务改变后可能只需要重新部署该服务即可。当然事无绝对,某些改动可能会改变服务接口,需要进行某些协调。但是,好的微服务架构的目标在于通过紧密结合的服务边界和进化机制,尽可能降低这些影响。
把服务当作组件使用的另一成果就是更为明确的组件接口。大多数语言缺乏良好机制去定义一个准确的发布接口。通常只有文档和规则来阻止客户端去中断组件的封装,结果导致组件的过度耦合。通过使用准确的远程调用机制,服务能轻松避免这些问题。
使用服务也有不足之处。远程调用比进程内调用更昂贵,远程 API
也需要粗粒度,这往往更加难以使用。如果你需要更改组件之间的职责分配,那么在跨越进程边界时就很难进行这样的操作。
乍一看,我们能观察到服务映射到运行时的过程,不过也仅仅是个大概。一个服务可能包含多个进程,它们会永远被开发和部署在一起,那么这样的应用进程和数据库也就只能被这一服务使用。
围绕业务能力组织
要把大型应用拆分为零件,管理人员通常聚焦在技术层面,拆分成 UI
组、服务器端逻辑组和数据库团组。当这些组被这样垂直分割,非常简单的改动就会导致跨组项目,而这需要时间和预算批准。聪明的团队会围绕这点进行优化,两害相权取其轻&&强化逻辑到任意有访问权限的应用。
任何试图设计一个系统(广义定义)的组织将会衍生出一种设计,其结构正是该组织的通信结构的复刻。
& Melvyn Conway, 1967
图 2: Conway 效应在运行
而微服务采用的方法则大不一样,围绕着业务能力拆分并组合。这些服务使用与业务范围相符的软件而实现广泛的技术栈,包括用户界面、持续存储,以及任意的外部协作。因此这些组之间是跨功能的,包括开发所要求的所有技能:用户体验、数据库和项目管理。
图 3:通过团队界限强化服务界限
www.comparethemarket.com
就采用了这种组织方式。跨功能的团队对构建和运行每个产品负责,每个产品又被拆分为大量的单个服务,这些服务通过信息总线通信。
大型的一体化应用也能够围绕业务能力模块化,然而并不常见。当然我们会敦促这些构建一体化应用的大型团队按照业务线来进行分工。然而问题在于,这些业务线倾向于根据诸多环境进行组织。一旦大型应用横跨许多模块,那么对于团队中的个体而言,很难融入他们的工作记忆中。此外我们也看到,这些模块线需要大量的训练去执行。服务组件所需的更为精细的分割也能让团队边界更清晰。
产品而非项目
大多数我们常见的应用开发会使用项目模式:交付软件的部分然后再考虑组合完整。完成后的软件被交付到维护机构,构建此项目的团队不被解散。
微服务的支持者则易于避免此模式,倾向于「在产品的整个生命周期里,开发团队应该拥有此项目」。这一灵感来自于亚马逊的「你构建,你运行」概念。在亚马逊,开发团队对生产环境中的软件负有全部责任。这让开发者每日都能了解自己的软件如何在生产环境运行,增强与用户的接触,也能承担部分支持职责。
这种产品意识与业务能力紧紧联系。与其把软件看作一套需要完成的功能,不如把它们看作一段进行中的关系,其中的关键问题是软件如何帮助用户增强业务能力。
并没有理由表明这一方法不能用于一体化应用,不过颗粒度更小的服务能够更容易地在服务开发者和用户之间建立起个人关系。
智能终端和哑管道
要在不同进程之间构建通信结构,我们已经见过许多产品和方案,它们强调在通信机制内部注入智能,其中优秀案例如 ESB(企业服务总线)。ESB
产品包含复杂的设施,用于信息路由、编排、转化,以及应用业务规则。
微服务社区则喜欢另一种方案:智能终端和哑管道。使用微服务架构的应用致力于在尽可能地解耦合的同时保持关联性&&他们拥有自己的域名逻辑,从经典 Unix
的视角看来更像过滤器&&接收请求,恰当地应用逻辑,生成反应。这些编排使用了简单的 REST 协议而非 WS-Choreography 或者 BPEL
,也没有采用使用中心化工具进行编配。
两种广为使用的协议分别是 HTTP 请求-反应与资源 API,以及轻量级消息。对于前者,最佳描述莫过于
成为 web ,不要隐藏其后
&& 伊恩&罗宾逊
微服务团队使用万维网(往大了说,Unix)依赖的原则和协议。开发者或者运维人员能够以很小的代价缓存经常使用的资源。
第二种方法的通常用法是利用轻量级信息总线进行通知。选定的基础设施是典型的 「哑管道」&& 就像 RabbitMQ 或 XeroMQ
这样无需提供稳定的异步组织的简单实施;而智能终端则在服务内生成并消耗消息。
在大型应用里,组件联机执行,它们之间的通信或者采用方法调用,或者调用函数。在大型应用到微服务的转变中,最大的问题就是通信模式的改变。从内存调用函数的本地对话转为
RPC,可能会变成性能不佳的聊天式通信。并且,你还需要用粗粒度的方法代替原来的精细通信。
去中心化治理
中心化治理的一大后果就是单一技术平台的标准化倾向。经验显示这一方式非常狭隘&&每个问题各有特色,而「马斯洛的锤子」并非万能。我们更喜欢针对工作使用正确的工具,在特定情境下,一体化应用能够发挥不同语言的优势。这并不常见。
把大型应用的组件拆分为服务,那么当我们构建每个部分时就有选择。想用 Node.js 构建一个单个报告页面?用起来!用 C++
写一个格外粗糙的近实时组件?没问题。想交换不同数据库类型,从而更好地适应某个组件的阅读习惯?我们也有重构技术。
当然,能做并不等于要那样做&&不过这种系统切割方法给了你选择权。
构建微服务的团队也愿意使用别的方法达到标准。与其使用纸面上的现成标准,他们更愿意使开发有用的工具,从而别的开发者也能够用来解决相似问题。这些工具通常通过实施收获成果,以包括内部开源模式在内的方式更广泛的群体中分享。现在
git 和 github 已经成为事实上的版本控制系统,开源实践也在机构内部越来越常见。
就是这一理念的最佳践行者。通过库的形式分享有用的、经过时间考验的代码,鼓励别的开发者以相似方法解决相似问题,同时也给别的必要的方法留有机会。共享库关注常用问题,比如数据存储、进程间通信,以及下文将讨论的基础设施自动化。
对微服务社区来说,额外的开销格外讨厌。社区并非不重视服务协议;与之相反,他们使用不同的方式来管理这些协议。Tolerant Reader 和
Consumer-Driven Contracts
这样的模型经常被用于微服务。他们帮助服务协议进行独立进化。通过把执行消费者驱动协议作为构建的一部分,强化了信心,也能就其它微服务是否工作提供快速反馈。我们知道澳大利亚的一支团队就使用消费者驱动协议来推动新服务的构建。他们使用能够定义单个服务协议的简单工具。在新服务的代码写好之前,就成为自动化构建的一部分。服务仅在满足协议时被构建,以优雅的方式避免了「YANGI」(
You Aren&t Going To Need It )悖论。这些技巧和工具围绕着它们成长,降低了对中心化协议管理的需求,减少了服务之间的暂时耦合。
或许去中心化治理的最高点是流行于亚马逊的谁构建谁运行的理念。每个团队都为自己构建的应用的所有方面负责,包括 24*7 不间断地运营软件。
这种层次的责任转变显然不同寻常,然而我们看到越来越多的公司给开发团队灌输这种层次的责任心。Netflix
是另一家采用这种理念的公司。不要在每个凌晨三点被寻呼机吵醒,这绝对是开发者关注代码质量的强大动力。这些理念已经与传统的中心化治理模型相去甚远。
去中心化数据管理
去中心化数据管理的方式多种多样。在最为抽象的层级,这意味着各个系统之间关于世界的概念模型大相径庭。在大型企业进行整合时,这一现象很常见。对客户的看法,销售人员的视角与支持人员的视角不同。销售认为可称为「客户」的某些方面,支持人员却并不认同。他们可能只是具有一些在语言描述上差异很细微的不同属性。
这一现象在应用之间也很普通,也会发生在应用内,特别是当应用被拆分为单独的组件时。 领域模型驱动设计(Domain-Driven Design) 的
Bounded Context 概念非常有助于思考这一问题。DDD
将一个大模型分解为几个较小的模型,并且能够投射出它们之间的关系。这一过程对于一体化架构和微服务架构都非常有益。不过在服务和 context
的边界之间存在自然关系,当我们在描述业务能力单元、强化分离时,这一自然关系有助于明朗化。
除了下放有关模型概念的决策,微服务也下放了数据存储的决策。由于一体化应用喜欢为持续性数据采用单一逻辑的数据库,企业也往往在一系列应用中采用单一数据库。这些决策大多数受厂商的授权商业模式驱动。微服务倾向于让每个服务管理自己的数据库,或者不同的数据库系统,即
Polyglot Persistence。你也可以在一体化应用中使用 Polyglot Persistence,不过它更多见于微服务。
图4:一体化设计:单一数据库 vs 微服务:应用数据库
把跨微服务的数据下放影响了对更新的管理。处理更新的常见方式是在更新多个资源时,通过使用事务来保证一致性。这种方式通常也被用于一体化应用内。
使用诸如这样的事务有助于保持一致,但是带来了显著的短时耦合,对跨多个服务产生问题。分布式事务因难以实施而闻名,随之而来,微服务架构强调了服务之间的事务和谐,明确了一致性只可能为最终一致性,各种问题通过补偿运算来解决。
选择通过该方法来管理不一致对于许多开发团队来说是项新的挑战,不过很符合商业惯例。通常商家为了快速响应需求会对不一致进行不同程度的处理,其中会存在一些处理错误导致的逆转。只要修复错误的代价低于因为一致性而导致业务损失的成本,这种权衡就是值得的。
基础设施自动化
基础设施自动化已经在过去的几年里取得了巨大的进步。云特别是 AWS 的进化格外地降低了构建、部署和运行微服务时的复杂度。
许多采用微服务构建的产品或系统是由在持续交付和其前身&&持续集成方面经验丰富的团队构建的。使用这种方法构建软件的团队需要大量使用基础设施自动化技术。下图展示了构建流程。
图5:基本的构建流程
考虑到本文并不针对持续交付,我们这里只提及几个关键特性。我们需要大量信心来认可自己开发的软件可行,因此会跑大量的自动化测试。要推广可行的软件到流程之上,意味着我们需要把部署每个新环境自动化。
一体化应用能够非常愉快地在这些环境中构建、测试和推送。事实证明,一旦你给一体化应用投入了自动化路径,那部署更多应用也并不那么可怕了。谨记,持续交付的目的之一就是让部署变得单调,所以不管是部署一个还是三个应用,只要依然单调就没有关系。
另一个常见的使用大规模基础设施自动化的领域就是在生产环境中管理微服务。前文我们认为只要部署一如既往地单调,那在一体化和微服务之间相差不会太大;恰恰与此相反,在运行阶段,二者却是相去甚远。
图6:模块部署经常不同
为故障而生
把服务用作组件的一个结果是应用在设计之初就要能容忍技术故障。任何服务调用可能会由于供应商的不可用而失败,而客户端需要尽可能优雅地做出响应。与一体化设计相比,由于引入了额外的复杂性来处理,这是一大不足。其结果是微服务团队不断反省服务故障如何影响用户体验。
Netflix 的 Simian Army 通过测试应用的弹性和监控,减少了工作日的服务故障,甚至数据中心的故障。
这种生产环境中的自动化测试足以让大多数的运营团队望而生畏,通常后者需要提前一周的时间。这并非说一体化架构风格不能尽兴这种精密的监控设置,只是不常见于我们的经验。
既然服务可能随时发生故障,所以能够快速监测并尽可能地自动恢复服务就非常重要。微服务应用侧重于应用的实时监控,检查架构因素(数据库每秒获得多少请求)和业务相关指标(每分钟收到多少订单)。语义监控也可提供早期预警系统,一旦出错就触发开发团队去跟进和调查。
对于微服务架构来说这尤为重要,因为微服务更偏好编配和事件协作导致的自发行为。尽管许多专家认可偶发价值,事实上意外行为并非好事。监控对于发现糟糕的意外行为至关重要,从而能够尽快修复。
一体化也可以像微服务那样透明构建,事实上,他们也应如此。区别在于你必须要了解运行在不同进程的服务们是何时断开的。考虑到相同进程内的库,这种透明度不太可能有用。
微服务团队希望能为每个单独的服务设置精密的监控和记录,这些服务包括在 dashboard
上显示服务启用/宕机状态,以及各种相关的运营和业务指标。与断路器状态、当前吞吐量和延迟的详情都是我们经常遇到的其它例子。
进化的设计
微服务从业者通常具有进化设计的背景,把服务分解视作一个长远的工具,让应用开发者们能够控制应用内的改动,无需让改动慢下来。改动控制并不一定意味着减少&&借助正确的态度和工具,你能够经常快速、有节制地修改软件。
当你试图把一个软件系统分为组件,你要作出如何划分的决定&&哪些是我们切分应用时需要遵守的原则?组件的关键属性是独立替换和升级的概念,也就意味着我们要找到一些立足点,当需要重写某个组件时,也不会影响它的协作者。
按照一体化来设计并构建,却演化为微服务,卫报网站给这样的应用树立了典范。网站的核心仍然是一体化,不过他们更愿意通过调用一体化应用的 API
来构建微服务,从而添加新功能。对于体育赛事的特定页面这样注定短暂的功能来说,这样的方法非常方便。网站上的类似部分能够通过快速开发语言而被迅速地组织起来,一旦赛事结束则可以快速移除。我们在一家金融机构也看到了类似办法,增加新服务以对应新的市场机会,几个月甚至几周后就被放弃。
这种对替代性的强调,也是模块化设计通用原则的一个特例,通常推动模块性来实现改变的方式。你可能想保留同一模块内同一时间的改变。系统内发生更改的部分很少在不同的当前大量流失的服务内。如果你发现自己重复在同时修改两个应用,那表明它们应该被合并。
把组件集成到服务,让更精细的发布计划大有可为。采用一体化,任何修改都需要对整个应用进行一次全面的构建和部署。采用微服务后只需要重新部署修改过的服务。这能够简化并加快发布过程。缺点是你得担忧对一个服务的修改可能破坏它的用户。传统的集成方法是采用版本控制来处理错误,而在微服务的世界里,则把版本控制当作最后的补救办法。通过给服务设计得尽可能强的修改宽容度,我们能够避免大量的版本控制。
微服务是未来吗?我们撰写此文的主要目的是解释微服务的主要思路和原则。通过此篇论述,我们认为微服务的架构风格是一个重要概念,值得企业级应用去认真考虑。我们最近已经采用此风格构建了多个系统,也知道有人也使用并赞同此方法。
我们所知的微服务架构的先驱包括亚马逊(Amazon)、网飞(Negflix)、卫报(Guardian)、英国政府数字化服务部门(UK Government
Digital Service)、realestate.com.au、Forward 和 comparethemarket.com 等。
2013 年的 The Conference Circuit 大会充满了各种公司案例,他们正在迁移到微服务类别的产品和服务,其中包括 Travis
CI。此外也有大量机构一直在做类似微服务的事情,但是并未采用此名称。(通常被标记为 SOA,不过 SOA 以各种矛盾的形态出现)
尽管有这些切实的经验,但是我们并不能坚决肯定微服务就是软件架构未来的发展方向。在微服务方面积累积极经验(与一体化应用相比)的同时,我们仍保持清醒&&微服务还没有经过足够长时间的检验,因而还不能做出完整判断。
我们的同事 Sam Newman 2014年的时候花费了大量时间写书,记录了我们构建微服务的经历。如果你想深入研究此主题,那你下一步也应该这么做。
微服务架构决定的实际效果需要多年后才能显现。我们已经看到一些由对模块化有强烈需求的优秀团队构建的一体化架构的项目,在多年后衰退。由于服务边界明确,且难以修补,许多人认为微服务不可能有此衰退。除非我们能看到足够多上年头的系统,否则还是不能完全评价微服务的成熟度。
当然也有其它原因让人们认为微服务不够成熟。在各种组件化的努力中,成功依赖于软件与组件的相符程度。要弄清组件的边界在哪里,这非常难。自我进化的设计认识到了让边界正确的难度,以及由此而来的让重构保持简单的重要性。不过一旦你的组件是需要远程通讯的服务,那重构要比采用联机库的服务更难。跨服务边界的代码迁移也很困难,任何界面变化都需要在参与者之间协调,也要添加对后端兼容的层,测试也会更复杂。
另一个问题就是,假如组件不能干净地组合,那么你所做的不过是把复杂性从组件内部转移成组件之间的联结。这样做不仅仅是复杂性的迁移,同时也变得更不明确,也更难以控制。如果只是查看一个小而简单的组件内部,而忽略服务之间混乱的联结,那你很容易就觉得更好。
最后,团队技能也是一大因素。新技术很容易被技术熟练的团队采用。不过一项对熟练团队来说更有效的技术,可能并不适合稍逊一筹的团队。我们已经见证了很多技术水平稍逊的团队构建的凌乱的一体化架构;采用微服务会发生怎样的混乱,也需要时间观察。水平不佳的团队会一直创建不太好的系统,在这种情况下,很难说微服务是会减少混乱,还是会让情况更糟。
我们听到的一个合理的说法是你不应该一开始就用微服务架构。相反,以一体化开始,保持模块化,一旦一体化变得麻烦,就将其拆分为微服务。(不过这一建议不甚理想,因为一个好的联机接口通常并不是一个好的服务接口)
我们以谨慎乐观的态度写下此文。到目前为止,我们已经足够了解微服务的风格,也认为值得踏上此路。我们不能肯定地说终点何在,不过软件开发中的一大挑战就是你只能基于当下所掌握的不完整的信息做决定。【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
头条头条头条头条头条
24H热文一周话题本月最赞
讲师:51257人学习过
讲师:108831人学习过
讲师:268498人学习过
精选博文论坛热帖下载排行
SQL Server 2005微软官方权威参考手册。
是Inside Microsoft SQL Server 2005系列书中的第一本,SQL Server类的顶尖之作。
全球公认SQL S...
订阅51CTO邮刊

我要回帖

更多关于 微服务架构与实践 pdf 的文章

 

随机推荐