微服务介绍(理论介绍)

做者 前端

Chris Richardson of Eventuate, Inc.  nginx

May 19, 2015web

本人翻译数据库

微服务逐渐获得文章、博客、自媒体和会议的青睐,他们几乎达到发展的顶峰期。同时,一些社区认为微服务不是新鲜的概念,都是之前的概念。怀疑论者认为它仅仅是SOA概念的翻版。尽管有不少的否认者和怀疑论者,微服务架构尤为对于复杂的企业程序和灵活的开发组织具备着明显的益处。后端

建立单体程序缓存

让咱们想象一下你正在建立一个新的相似于UBER和Hailo的出租车新品牌。经过头脑风暴和前期信息的收集,你开始手动建立一个工程或者经过Rails, Spring Boot, Play, or Maven。这个程序具备六边形的架构,以下图所示:服务器

 

这个程序的核心是业务逻辑服务,包括服务定义、域对象和事件等。四周的是与外界的接口适配,例如数据库操做层、消息队列、Web调用适配、UI调用适配和Rest调用适配等。网络

虽然程序划分逻辑块,程序被物理上打包和部署为一个产品。具体的程序依赖于程序的语言和框架结构。例如,Java被打包为War包,不属于Tomcat或者Jetty的容器中。相似的, Rails and Node.js被打包在一个树状结构的文件夹里。架构

这种样式的程序极其普通。由于都在一个集成开发工具里,因此他们开发和部署及其简单。这种程序也易于测试,由于极易建立从前端到后端的测试链条。单体程序易于部署,你仅仅须要拷贝部署包到相应服务器。你能够经过负载均衡实现程序的横向部署。在程序建立的前期,它运转一切良好。负载均衡

 

逐渐走向单体应用地狱

不幸的是,这种应用具备着巨大的限制。成功的产品随着时间的应用,逐渐变得愈来愈大。每一次小功能的改进,研发人员都会加入一些新的代码。几年以后,小的程序将变成巨大的单体应用。我相信运行这个巨大的怪物将会耗费研发人员巨大的精力。

一旦你的程序成为了巨大、复杂的单体应用,你的研发人员将会变得很是难受。灵活的的开发和交付的想法将会变得没有但愿。一个主要的问题是程序变得过于复杂。这个问题很好理解,由于一我的很难理解复杂的项目。所以,修复Bug和开发新功能将会变得困难和耗时。另外,这会致使造成恶性循环。若是代码很难理解,很难作出正确的修改。你将会进入一个巨大的、难于理解的巨大怪物的泥潭。

应用程序的大小将会下降研发效率。程序越大,启动时间越长。例如,最近的一份报告显示启动时间仅仅12分钟。我据说过启动须要40分钟的例子。若是开发者须要常常重启服务,那么会有大量的时间浪费与程序重启,将会致使开发效率下降。

大程序的另一个障碍是持续的部署问题。如今一个Saas程序一天须要修改部署几回。若是对于大程序这将会变得困难,由于一点小的变更将会发布整个程序。再加之以前的启动问题,将会加重问题。.(实际上,单体应用还有一个具体的问题即是耦合性,发布任何一点更新,可能都会对原有的问题产生影响。)

当不一样模块需求资源不一样时,程序的横向扩展将会变得艰难。例如,一部分程序可能须要CPU密集型部署,一部分程序须要IO密集型部署。因为全部的模块集中在一块儿,致使个性化的部署方案将难于推动。

另外,单体应用的问题即是可用性。由于全部的模块运行于一个进程中,任何一个模块的Bug,像程序泄露,都会致使整个进程的崩溃。由于全部程序部署的实例都同样,可能整个程序都会挂掉。

不只如此,单体应用使得吸取新的框架和语言很是困难。由于全部的单体应用使用的语言都是一致的,若是用其余语言开发,则会致使整个框架的从新返工。

总结:若是你有一个关键程序采用单体架构,而且用过期、低效的开发语言编写,这将会使得研发人员开发很是困难。使得灵活应对和快速交付变得困难。

针对此,你能作什么呢?

 

微服务--处理复杂度

许多组织,像Amazon, eBay, and Netflix,经过微服务架构已经成功的解决了这类问题。不是经过构建一个巨大的程序,而是将程序分解为一些列小的、内部相互沟通的程序。

一个服务可以负责不一样的职能或者功能,像订单管理、客户管理等。每一个微服务都是一个小的程序,它具备着六边形的业务逻辑和适配器。一些微服务将会暴漏一些供其余微服务或者客户端调用的API。一些微服务可能执行Web UI操做。运行时,任何的微服务都是一个云虚拟机或者一个Dock容器。

例如,一个协同的架构图以下所示:

 

不一样应用程序的服务运行于他们本身的微服务里面。另外,web程序被分解为几个程序组合(像客户使用一个;司机使用一个)。这使得它能够按照不一样的用户部署不一样的程序。

任何一个后端服务暴漏一个REST API接口,大部分服务消费其余服务的接口。例如司机管理服务用消息服务通知司机一个潜在的订单。UI服务调用其余服务的数据刷新页面数据。服务可能采用异步、消息队列机制通讯。

移动服务会调用司机服务和乘客服务。应用程序将不会直接调用后端服务。相反,服务的调用将会被经过API网管中转。API网管负责负载均衡、缓存、权限控制、监控和接口测量。一般API网管采用Nginx实现。

 

 

 

微服务架构经过伸缩立方体实现伸缩,X轴表明单个服务的水平扩展,例如经过负载均衡实现;Y轴经过不一样的功能将微服务划分为不一样的业务主体;Z轴是指进行数据的分区,也就是说微服务赞同具备独立的运行环境、操做数据。下图为部署到Dock中的一个架构图

 

运行的时候,订单管理服务包含多个微服务。每一个服务是一个Dock容器。为了高可用,容器运行于多个云虚拟机上。在服务实例之间是Ngnix负载均衡器。负载均衡器也会处理其余的功能,像缓存、控制权限、API测量和监控。

微服务架构深深地影响了程序和数据库之间的关系。再也不是多个程序共享一个数据库,而是一个微服务享有一个数据库。另外,这个观点影响了企业数据的架构模型。它常常存在于一些数据的备份。一个服务一个数据库的模式是有必要的,由于它下降了不一样服务之间的耦合性。下图展现了微服务的数据库架构:

 

每一个微服务都有本身的数据库,另外,每一个服务能够根据本身的须要选择最合适的数据库,所以也称之为多语言架构。例如,司机管理服务须要查找离乘客最近的司机,所以须要一个高效的地理位置数据库。

表面上,微服务相似于SOA架构。二者的相同点是都包含许多服务。微服务不像SOA经过WS和ESB通讯,而是经过轻量级的REST服务通讯。

微服务的好处

微服务架构有许多好处。第一,它下降问题的复杂度。它将一个巨大的单体应用分解为不一样的微服务。总体的功能没有改变,可是分解为可管理的不一样应用。每一个服务都有明确的边界,方便RPC或者消息队列调用。微服务使得巨大的单体应用划分为不一样的代码块,使得易于理解和维护。

第二,单个的服务可以使得每一个小组专一于某个功能模块。开发者能够根据须要选择不一样的技术,而且关注与接口契约。固然,大部分的组织避免彻底的技术选择自由。这种自由意味着开发者不用在选择项目开始时过期的技术语言开发。

第三,微服务可以使每一个服务独立部署。开发者不用再协调服务周边的功能。这种功能可以使得开发效率和测试效率大大提升。

最后,微服务可以使得每一个服务独立的伸缩。每一个服务可以根据不一样服务在容量、可用性的限制扩展微服务。另外,你可以采用最佳的硬件配置匹配服务。

微服务的缺陷

Fred Brooks已经书写了30年,没有万能的银弹。像每种技术,微服务存在缺陷。首先微服务就像他的名字,开发团队会关注与程序的大小。实际上微服务的目的是将程序分解为灵活和快速交付的产品,而不该该是以具体的产品大小为目的。

另一个缺陷是来自于拆分后的分布式复杂性。微服务须要实现基于消息或者RPC的线程交流机制。另外,它必须处理传输掉包或者不可达致使的请求失败问题。虽然这些都不是一些高深的科学,可是这比进程内通讯的单体应用复杂的多。

另一个挑战是数据库的分区。业务交易同时更新许多服务在显示业务中很是正常。这些交易在单体应用中很是正常,由于都是基于一个数据库。在微服务里面,你须要更新许多不一样服务的数据库。根据CAP理论,是不存在完整的分布式事务理论。他们都不被如今的NOSQL数据库或者消息服务器支持。你只能采用最终一致性事务理论解决此类问题。

测试微服务也将会较为复杂。例如若是在单体应用中写一个服务,并进行测试可能很是简单。可是在微服务中,须要首先启动其相关的服务,而后才可以测试此服务。这不是高深的科学,可是理解这样作的复杂性很是有必要。

另一个挑战是微服务的更新可能涉及多个服务。例如,一个更新服务涉及A,B和C服务,在单体应用中直接一块更新和部署便可。可是在微服务中,首先应该更新C服务,若是其没有问题,再更新B服务,最后更新A服务。必须作好不一样服务之间的协调和更新服务。

部署微服务也较为复杂。一个单体应用部署相同的服务与负载均衡器以后。每一个服务实例须要部署基础服务的地址(像数据库和消息队列)。微服务的部署包括大量的服务,例如hailo须要160台服务,Netflix须要600台服务器。每一个服务具备多个运行实例。他们有多个部分须要配置、部署、伸缩和监控。另外,你也须要实现一个服务发现机制(让相互通讯的服务之间可以自动发现)。传统的手动操做已经不可以知足这种级别的复杂性。所以,一个成功的服务部署须要更高级别的研发和自动化水平。

一个自动化的方案是采用云部署。一个Pass的服务可以为用户提供简单的部署和管理途径。它可以使得他们从得到和配置IT资源中独立出来。同时,系统和网络专家会按照最佳的实践和企业策略配置Paas平台。另一种方式是开发本身的Pass平台,一种经典的集群策略是采用Kubernetes, 配合Docker技术。

总结

建立一个程序存在其固有的负载型。单体的应用适合程序建立的初期,不适合大型负责的工程。虽然微服务也存在缺陷和挑战,可是在复杂的程序面前仍是较好的一种解决方案。