Chris Richardson微服务翻译:微服务介绍

做者简介:Chris Richardson,世界著名的软件架构师,经典著做《POJOS IN ACTION》的做者,cloudfoundry.com 的创始人html

微服务目前正受到大量的关注,成为文章、博客、会议讨论的热点。与此同时,也有人质疑微服务并不是新事物,只是SOA(Service Oriented Architecure)的二度封装。不管是追捧仍是质疑,微服务架构拥有巨大的优点,尤为是让敏捷开发和复杂的企业应用支付成为可能。nginx

本系列包含7篇文章,介绍了微服务架构的各个因素,了解微服务模型的优劣,以此来指导微服务是否符合您的项目,如何应用等。程序员

Chris Richardson 微服务系列翻译全7篇连接:web

原文连接:Introduction to Microservices
数据库


构建单体应用

假设咱们要开发一个全新的与 Uber 竞争的打车软件。在需求整理后,须要建立一个新项目,这个应用可应该有以下六边形的架构模块:编程

应用的核心是业务逻辑:它定义了服务、领域对象和事件模块。各类适配器围绕核心与外部交互,适配器包括了数据库访问组件、生产与消费信息的消息组件、以及API或web UI组件。小程序

尽管按模块化进行设计,整个应用仍须要总体打包、部署。实际格式与选择的编程语言和框架相关,例如:Java 应用会打成 War 包部署到 Tomcat 或 Jetty 等服务器;还有一部分会打成 Jar 包;Rails 和 Node.js 应用直接以目录结构的形式部署。后端

这种单一应用能够经过 IDE 工具来方便的构建,也易于部署与测试,扩展应用时只须要添加负载均衡。在项目早起,这样作是颇有效的。缓存

迈向单体的地狱

很不幸,这种简单的方法存在着局限性:服务器

1)一个成功的应用会随着时间而变的的愈来愈大。在每一个敏捷 Sprint 期间,开发团队会实现更多的功能,添加新的代码。几年以后,当初简单的小应用会复杂到任何一个开发者都没法彻底理解,修复 bug 和开发新功能也所以耗时颇多。而且这是一个恶性循环,代码越难理解,正确的修改就越难。最后开发团队则会饱受折磨,苦苦挣扎与敏捷开发和交付中。

2)应用程序越大,启动时间就越长。例如在最近的调查中,很多开发者指出启动时长达12分钟。若是开发过程当中频繁的重启应用,那么就会浪费大量的时间,效率天然就低下。

3)庞大复杂的单体应用另外一问题就是难以持续交付。如今SaaS应用的宗旨是若是有改动,可以天天在生产环境部署屡次。然而要让复杂的单体应用达到这个水平却很困难。若是更新应用的某个部分,必须从新部署整个应用,启动一次的时间就很漫长,并且不能彻底预期修改的影响,不得不进行大量的人工测试。结果就是,持续部署变的不可能。

4)单体应用在多个模块对资源需求有冲突时很难扩展。例如:模块1实现了 CPU密集型的图像处理逻辑,最适合部署到 Amazon EC2 Compute Optimized instances;而模块2须要内存数据库,更适合部署到 EC2 Memory-optimized instances,这两个模块一块儿部署时,不得不在硬件方面进行妥协。

5)单体应用的另外一问题就是可靠性。全部模块运行在同一进程中,任何模块的一个bug(例如:内存泄露)均可能拖垮整个应用。

6)单体应用很难拥抱新的框架和编程语言。例如:你有200万行代码性 XYZ 框架,若是须要使用 ABC 框架重写,将会耗费大量的时间和人力。这就在尝试新技术时候存在巨大的阻碍。
最后总结一下,从一个业务清晰,几个程序员就能理解的小程序,逐步成长为一个臃肿、没法理解的庞然大物。使用过期、效率低下的技术来实现(毕竟技术在进步),招聘都变的困难。整个应用扩展性、可靠性差,敏捷开发和持续交付几乎成为不可能。

面对这些,该何去何从?

微服务-处理这些复杂问题

不少公司,例如Amazon、eBay、Netflix,都已经经过拥抱微服务来解决以上问题了,他们再也不是构建一个可怕的单体应用,而是经过微服务架构将应用拆分为更小的、相互链接的服务。

一个微服务通常完成某个特定的功能,例如:订单管理、客户管理等。每一个微服务都是一个小应用,有自身的逻辑以及适配器来构成六边形架构。有的微服务会暴露 API 供其余微服务或客户使用,有的微服务会实现 Web UI。运行时,每一个实例一般是一个虚拟云主机或 Docker 容器。下面是对上述老架构的拆分:

应用的每一个功能都由自身微服务实现。整个应用被拆分为一系列更小的 Web应用(例如:乘客管理、司机管理)。拆分后更方便为特定用户、设备或案例而单独部署。

每一个后端服务暴露 REST API,也会调用其余服务提供的 API。例如:司机管理服务会使用 通知服务 来告诉司机的行程;UI服务调用其余服务来呈现页面。服务之间也可能使用异步的消息通讯。

部分 REST API 也会提供给司机和乘客的移动 APP 使用,这些应用不能直接访问后端服务器,而是经过 API网关 来协调访问。API网关的职责有:负载均衡、缓存、访问控制、API计费、监控等。

上图是 Scale Cube 的 3D 模型,来自《The Art of Scalability》一书,应用通常以3个维度进行扩展:

  • X轴 :水平扩展,经过克隆的方式扩展。通常是负载均衡后运行多个应用副本,达到某个服务的高吞吐和高可用性。
  • Y轴 :功能拆分,哦经过拆分不一样的事务进行扩展。微服务对应着 Y 轴,将单体应用拆分为微服务。
  • Z轴 :数据分区,经过分隔相同的事务进行扩展,例如:数据库分库分表。

下图展现了行程管理服务采用 Docker镜像部署到 AWS EC2上:

行程管理服务由多个实例组成,每一个实例就是一个 Docker 容器。为了达到高可用,容器会在多个虚拟云主机上。实例前是 Nginx 负载均衡,将请求分发到所有实例,也处理缓存、访问控制、API测量和监控等。

微服务架构也影响应用和数据库之间的关系。每一个服务都有自身的数据库,而不与其余服务共享同一个数据库。这样一来,数据模型会比较奇怪,也会出现部分数据冗余。然而,要想从微服务中受益,这样作仍是颇有必要的,由于微服务提倡的就是松耦合。下图展现了微服务架构下应用的数据架构:

此外,每一个服务还能够选用符合本身特性需求的数据库,例如:司机须要查找附近的乘客,那司机管理服务就须要使用能高效支持地理位置查询的数据库。

表面上看,微服务和 SOA 很是相似,这两种架构都有一系列服务。然而,微服务能够当作没有 web service规范和 EBS套件 约束的 SOA。微服务更青睐采用 REST 这样简单、轻量级的协议,而不是老旧的 web service。微服务也会去避免使用笨重的 EBS 套件而喜欢使用实现 EBS 部分功能的轻量级工具。微服务也避免 SOA 诸如canonical schema 的定义。

微服务的优点

微服务架构有不少好处:

1)经过将巨大的单体应用拆分为多个服务,解决了单体复杂度问题。拆分后总体功能没有改变,但应用变成了多个方便管理的小应用。每一个服务经过 RPC 或 消息驱动的 API定义清晰的服务边界。拆分后的服务能更快的部署,更容易理解、开发和维护。

2)拆分后的服务可由更专一的开发团队来维护。程序员可在 API 约定下自由的选择合适的技术。更重要的是,每一个服务拆分的很小,使用现有技术重写老的服务也不是很困难的事。

3)微服务架构使得独立部署成为可能。开发者不须要协调其余服务部署对本服务的影响(单体应用,该一部分可能对其余部分产生影响,某个更改可能涉及多个模块的协调),这种改变能够加快部署,快速迭代而不用等整个应用部署。微服务使可持续交付成为可能。

4)微服务使得每一个服务独立扩展。能够针对某些有容量和可用性要求的微服务进行扩展,部署多个服务而不是多个单体应用去得到性能提高。能够针对服务需求使用合适的硬件资源,例如:在EC2 Compute Optimized instances 部署 CPU密集型的图片处理服务,在 EC2 memory-optimized instances 上部署有内存数据库需求的服务。

微服务的不足

正如Fred Brooks 30年前所说:『没有银弹』,微服务也有其不足和挑战:

1)劣势之一就是它的名字,微服务过度强调了服务的大小,实际上有开发者号召你们写10-100行代码的微服务。然而微服务更想表达的是一种工具和途径,并非最终目的(为微服务而微服务)。微服务是为了便利敏捷开发和部署而去有效的拆分应用。

2)由单体应用拆分为分布式应用带来的复杂。开发者须要基于消息或 RPC 的方式进行进程间的通讯,还须要写额外的代码去处理请求超时或不可用致使的局部故障。

3)分区的数据库架构。一个事务中更新多个业务记录是常见的,单体应用实现事务比较简单,毕竟是共用同一个数据库。而微服务架构中,就须要更新多个服务的多个数据库,通常不使用分布式事务,不只仅是由于CAP 理论,还由于一些流行的 NoSQL 和 MQ 并不支持这一需求。最终还得使用最终一致性方案,而这对开发者提出了更高的挑战。

4)测试微服务的应用也更加复杂。例如,采用了 Spring Boot 这种框架的单体应用,测试它的 REST API比较容易。而在微服务中,须要启动或 mock 其依赖的服务才能完成。

5)跨服务的改动。例如:假设你完成一个需求,须要修改A、B、C服务,而A 依赖 B,B 依赖 C。单体应用中能够简单的修改对应的模块,而后一块儿部署。而微服务架构下,你须要当心翼翼的计划和协调每一个服务的改动和发布:先更新C,再更新B,最后更新A。

6)部署微服务应用也更加复杂。单体应用都是相同的,拷贝部署到负载均衡后面就好了。而微服务应用由大量的服务组成,例如:NetFlix 有超过 600 个服务。就有不少部分须要去配置、部署、扩展和监控。此外还须要实现服务发现机制,用来让服务找到它须要通讯的服务的地址。最终,成功部署一个微服务应用须要开发者有足够的部署方法并实现高水平的自动化。自动化的方法之一就是使用Cloud Foundry 这样的 PaaS 服务,让开发者无需纠结于购买和配置 IT 资源。另外一种方法是开发本身的 PaaS平台,一般起步方式是使用Mesos 或Kubernetes 这样的集群管理方案,配合 Docker 的容器技术使用。

总结

构建复杂的应用自己就是困难的事情,单体架构在针对简单、轻量级的应用时是好的。但运用在复杂的应用上会变得痛苦不堪。尽管微服务架构有诸多的缺点和挑战,但对于复杂的、演进的应用来说是一个更好的选择。

后续文章中将介绍微服务的几个方面,讨论一些诸如服务发现、服务部署和重构单体应用到微服务的话题。

相关文章
相关标签/搜索