什么是微服务?微服务架构的优缺点、应⽤
什么是微服务?微服务架构的优缺点、应⽤?
微服务(micro services)这个概念不是新概念,很多公司已经在实践了,例如亚马逊、Google、FaceBook、Alibaba。微服务架构模式(Microservices Architecture Pattern)的⽬的是将⼤型的、复杂的、长期运⾏的应⽤程序构建为⼀组相互配合的服务,每个服务都可以很容易得局部改良。 Micro这个词意味着每个服务都应该⾜够⼩,但是,这⾥的⼩不能⽤代码量来⽐较,⽽应该是从业务逻辑上⽐较——符合SRP原则的才叫微服务。
暂且不讨论⼤⼩问题,读者朋友你⾸先要考虑的是如何解决⽬前技术团队遇到的开发问题、部署问题。正是在解决这些问题的过程中,才渐渐总结提炼出了微服务架构模式的概念。
微服务跟SOA有什么区别呢,可以把微服务当做去除了ESB的SOA。ESB是SOA架构中的中⼼总线,设计图形应该是星形的,⽽微服务是去中⼼化的分布式软件架构。
接下来会讨论以下⼏个话题:
应⽤微服务的动机,跟传统巨⽯应⽤的⽐较
微服务的优点与缺点
应⽤微服务架构设计时可能遇到的关键问题(内部服务通信、分布式数据管理)
1、巨⽯(monolith)应⽤
web应⽤程序发展的早期,⼤部分web⼯程是将所有的功能模块(service side)打包到⼀起并放在⼀个web容器中运⾏,很多企业的Java 应⽤程序打包为war包。其他语⾔(Ruby、Python或者C++)写的程序也有类似的问题。
假设你正在构建⼀个在线商店系统:客户下订单、核对清单和信⽤卡额度,并将货物运输给客户。很快,你们团队⼀定能构造出如下图所⽰的系统。
这种将所有功能都部署在⼀个web容器中运⾏的系统就叫做巨⽯型应⽤。巨⽯型应⽤有很多好处:IDE都是为开发单个应⽤设计的、容易测试——在本地就可以启动完整的系统、容易部署——直接打包为⼀个完整的包,拷贝到web容器的某个⽬录下即可运⾏。
但是,上述的好处是有条件的:应⽤不那么复杂。对于⼤规模的复杂应⽤,巨⽯型应⽤会显得特别笨重:要修改⼀个地⽅就要将整个应⽤全部部署(PS:在不同的场景下优势也变成了劣势);编译时间过长;回归测试周期过长;开发效率降低等。另外,巨⽯应⽤不利于更新技术框架,除⾮你愿意将系
统全部重写(代价太⾼你愿意⽼板也不愿意)。
2、巨⽯应⽤的拆分
详细⼀个⽹站在业务⼤规模爬升时会发⽣什么事情?并发度不够?OK,加web服务器。数据库压⼒过⼤?OK,买更⼤更贵的数据库。数据库太贵了?将⼀个表的数据分开存储,俗称“分库分表”。这些都没有问题,good job。不过,⽼外的抽象能⼒⽐我们强,看下图Fig2。
这张图从三个维度概括了⼀个系统的扩展过程:(1)x轴,⽔平复制,即在负载均衡服务器后增加多个web服务器;(2)z轴扩展,是对数据库的扩展,即分库分表(分库是将关系紧密的表放在⼀台数据库服务器上,分表是因为⼀张表的数据太多,需要将⼀张表的数据通过hash放在不同的数据库服务器上);(3)y轴扩展,是功能分解,将不同职能的模块分成不同的服务。从y轴这个⽅向扩展,才能将巨型应⽤分解为⼀组不同的服务,例如订单管理中⼼、客户信息管理中⼼、商品管理中⼼等等。
将系统划分为不同的服务有很多⽅法:(1)按照⽤例划分,例如在线商店系统中会划分出⼀个checkout UI服务,这个服务实现了checkout这个⽤例;(2)按照资源划分,例如可以划分出⼀个catlog服务来存储产品⽬录。
浏览web是什么意思服务划分有两个原则要遵循:(1)每个服务应该尽可能符合单⼀职责原则——Single Responsible Principle,即每个服务只做⼀件事,并把这件事做好;(2)参考Unix命令⾏⼯具的设计,Unix提供了⼤量的简单易⽤的⼯具,例如grep、cat和find。每个⼯具都⼩⽽美。
最后还要强调:系统分解的⽬标并不仅仅是搞出⼀堆很⼩的服务,这不是⽬标;真正的⽬标是解决巨⽯型应⽤在业务急剧增长时遇到的问题。
对于上⾯的例⼦,按照功能和资源划分后,就形成下⾯图3的架构图。分解后的微服务架构包含多个前端服务和后端服务。前端服务包括Catalog UI(⽤于商品搜索和浏览)、Checkout UI(⽤于实现购物车和下单操作);后端服务包括⼀些业务逻辑模块,我们将在巨⽯应⽤中的每个服务模块重构为⼀个单独的服务。这么做有什么问题呢?
3、微服务架构的优点与缺点
1优点
每个服务⾜够内聚,⾜够⼩,代码容易理解、开发效率提⾼;服务之间可以独⽴部署,微服务架构让持续部署成为可能;每个服务可以各⾃进⾏x扩展和z扩展,⽽且,每个服务可以根据⾃⼰的需要部署
到合适的硬件服务器上;容易扩⼤开发团队,可以针对每个服务(service)组件开发团队;提⾼容错性(fault isolation),⼀个服务的内存泄露并不会让整个系统瘫痪;系统不会被长期限制在某个技术栈上。
2缺点
《⼈⽉神话》中讲到:没有银弹,意思是只靠⼀把锤⼦是盖不起摩天⼤楼的,要根据业务场景选择设计思路和实现⼯具。我们看下为了换回上⾯提到的好处,我们付出(trade)了什么?
开发⼈员要处理分布式系统的复杂性;开发⼈员要设计服务之间的通信机制,对于需要多个后端服务的user case,要在没有分布式事务的情况下实现代码⾮常困难;涉及多个服务直接的⾃动化测试也具备相当的挑战性;服务管理的复杂性,在⽣产环境中要管理多个不同的服务的实例,这意味着开发团队需要全局统筹(PS:现在docker的出现适合解决这个问题);应⽤微服务架构的时机如何把握?对于业务还没有理清楚、业务数据和处理能⼒还没有开始爆发式增长之前的创业公司,不需要考虑微服务架构模式,这时候最重要的是快速开发、快速部署、快速试错。
4、微服务架构的关键问题
1、微服务架构的通信机制
客户端与服务器之间的通信
在巨⽯型架构下,客户端应⽤程序(web或者app)通过向服务端发送HTTP请求;但是,在微服务架构下,原来的巨⽯型服务器被⼀组微服务替代,这种情况下客户端如何发起请求呢?
如图4中所⽰,客户端可以向micro service发起RESTful HTTP请求,但是会有这种情况发⽣:客户端为了完成⼀个业务逻辑,需要发起多个HTTP请求,从⽽造成系统的吞吐率下降,再加上⽆线⽹络的延迟⾼,会严重影响客户端的⽤户体验。
为了解决这个问题,⼀般会在服务器集前⾯再加⼀个⾓⾊:API gateway,由它负责与客户度对接,并将客户端的请求转化成对内部服务的⼀系列调⽤。这样做还有个好处是,服务升级不会影响到客户端,只需要修改API gateway即可。加了API gateway之后的系统架构图如图5所⽰。
内部服务之间的通信
内部服务之间的通信⽅式有两种:基于HTTP协议的同步机制(REST、RPC);基于消息队列的异步消息处理机制(AMQP-based message broker)。
Dubbo是阿⾥巴巴开源的分布式服务框架,属于同步调⽤,当⼀个系统的服务太多时,需要⼀个注册中⼼来处理服务发现问题,例如使⽤ZooKeeper这类配置服务器进⾏服务的地址管理:服务的发布者要向ZooKeeper发送请求,将⾃⼰的服务地址和函数名称等信息记录在案;服务的调⽤者要知道服务的相关信息,具体的机器地址在ZooKeeper查询得到。这种同步的调⽤机制⾜够直观简单,只是没有“订阅——推送”机制。
AMQP-based的代表系统是Kafka、RabbitMQ等。这类分布式消息处理系统将订阅者和消费者解耦合,消息的⽣产者不需要消费者⼀直在线;消息的⽣产者只需要把消息发送给消息代理,因此也不需要服务发现机制。
两种通信机制都有各⾃的优点和缺点,实际中的系统经常包含两种通信机制。例如,在分布式数据管理中,就需要同时⽤到同步HTTP机制和异步消息处理机制。
2、分布式数据管理
处理读请求
在线商店的客户账户有限额,当客户试图下单时,系统必须判断总的订单⾦额是否超过他的信⽤卡额度。信⽤卡额度由CustomerService 管理、下订单的操作由OrderService负责,因此Order Service要通过RPC调⽤向Customer Service请求数据;这种⽅法能够保证每次Order Service都获取到准确的额度,单缺点是多⼀次RPC调⽤、⽽且Customer Service必须保持在线。
还有⼀种处理⽅式是,在OrderService这边存放⼀份信⽤卡额度的副本,这样就不需要实时发起RPC请求,但是还需要⼀种机制保证——当Customer Service拥有的信⽤卡额度发⽣变化时,要及时更新存放在Order Service这边的副本。
处理更新请求
当⼀份数据位于多个服务上时,必须保证数据的⼀致性。
分布式事务(Distributed transactions) 使⽤分布式事务⾮常直观,即要更新Customer Service上的信⽤卡额度,就必须同时更新其他服务上的副本,这些操作要么全做要么全不做。使⽤分布式事务能够保证数据的强⼀致,但是会降低系统的可⽤性——所有相关的服务必须始终在线;⽽且,很多现代的技术栈并不⽀持事务,例如REST、NoSQL数据库等。
基于事件的异步更新(Event-driven asynchronous updates) Customer Service中的信⽤卡额度改变时,它对外发布⼀个事件
到“message broker(消息代理⼈)”;其他订阅了这个事件的服务受到提⽰后就更新数据。事件流如图6所⽰。
5、重构巨⽯型应⽤
在实际⼯作中,很少有机会参与⼀个全新的项⽬,需要处理的差不多都是存在这样那样问题的复杂、⼤型应⽤。这时候如何在维护⽼服务的同时,将系统渐渐重构为微服务架构呢?
不要让事情更坏,有新的需求过来时,如果可以独⽴开发为⼀个服务,就单独开发,然后为⽼服务和新服务直接编写胶⽔代码(Glue Code)——这个过程不容易,但这是分解巨型服务的第⼀步,如图7所⽰;识别巨⽯型应⽤中的可以分离出来当做单独服务的模块,⼀般适合分离的模块具有如下特点:两个模块对资源的需求是冲突的(⼀个是CPU密集型、⼀个是IO密集型);授权鉴定层也适合单独分离出⼀个服务。每分离出⼀个服务,就需要编写对应的胶⽔代码来与剩下的服务通信,这样,在逐渐演进过程中,就完成了整个系统的架构更新。
关于重构,有篇⽂章推荐⼤家阅读——推倒重来的讲究,关于重构有很多可以写的,希望我能快速进步,多写点总结与⼤家分享。
以上就是关于什么是微服务?微服务架构的优缺点、应⽤的知识介绍,微服务并不是治百病的良药,也不是什么新的技术,我从中学到的最⼤的⼀点就是scale cube,从这个坐标轴出发去考虑⼤规模系统的构建⽐较容易分析和实践。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论