From 88a66346935f0974bc74f63263d8901efb6825e4 Mon Sep 17 00:00:00 2001 From: oopsguy <474608426@qq.com> Date: Mon, 9 Oct 2017 21:42:36 +0800 Subject: [PATCH] Re-proofread content --- 0-foreword.md | 18 ++--- 1-introduction-to-microservices.md | 72 +++++++++---------- ...factoring-a-monolith-into-microservices.md | 30 ++++---- 3 files changed, 60 insertions(+), 60 deletions(-) diff --git a/0-foreword.md b/0-foreword.md index 20ae5d9..518fd33 100644 --- a/0-foreword.md +++ b/0-foreword.md @@ -1,17 +1,17 @@ # 前言 Floyd Smith -近年来,微服务在应用开发和部署方面取得了显著的进步。将应用开发或者重构成微服务以分离服务,通过 API 以明确的方式来相互“对话”。例如,每个微服务都是自包含(self-contained),各自维护自己的数据存储(这具有重要影响),可以独立更新其他服务。 +近年来,微服务在应用开发和部署方面取得了显著的进步。将应用开发或者重构成微服务以分离服务,通过 API 以明确的方式来相互“对话”。例如,每个微服务都是自包含(self-contained),各自维护自己的数据存储(这非常有意义),可以独立更新其他服务。 -使用基于微服务的方式使得应用程序开发变得更快更容易管理,它只需要较少的人力就能实现更多的功能,可以更快更容易地部署。把应用程序设计成一个微服务集合,更加容易在多台具有负载均衡的服务器上运行,使其能够轻松应对需求高峰、由于时间推移而平稳增长的需求和由于硬件或者软件问题导致的宕机事故。 +使用基于微服务的方式使得应用程序开发变得更快更容易管理,它只需要较少的人力就能实现更多的功能,可以更快更容易地部署。把应用程序设计成一套微服务,更加容易在多台具有负载均衡的服务器上运行,使其能够轻松应对需求高峰、由于时间推移而平稳增长的需求和由于硬件或者软件问题导致的宕机事故。 微服务的最大进步在于改变了我们的工作方式。敏捷软件开发技术、应用迁移云端、DevOps 文化、持续集成与持续部署(CI/CD)和容器应用都使用了微服务来革新应用开发与交付。 -无论是作为反向代理还是高性能的 web 服务器,NGINX 软件都与微服务和上述列出的所有技术有着紧密联系。NGINX 使得基于微服务的应用更加易于开发,确保微服务解决方案能顺利运行。 +无论是作为反向代理还是高性能的 web 服务器,NGINX 软件都与微服务和上述列出的所有技术有着紧密联系。NGINX 使得基于微服务的应用更加易于开发,确保了微服务解决方案能顺利运行。 -随着 NGINX 与微服务之间的关系日渐紧密,我们已经在 NGINX 网站上运行了一个由 Chris Richardson 所写的七部分系列微服务。他很早就参与了设计与实现,他的博文主要涵盖了微服务应用设计与开发方面的内容,包括了如何从单体应用迁移至微服务。博文提供了关于微服务问题的全面概述,非常受欢迎。 +随着 NGINX 与微服务之间的关系日渐紧密,我们已经在 NGINX 网站上运行了一个由 Chris Richardson 所编写的七部分系列微服务。他很早就参与了设计与实现,他的博文主要涵盖了微服务应用设计与开发方面的内容,包括了如何从单体应用迁移至微服务。博文提供了关于微服务问题的全面概述,非常受欢迎。 -在本书中,我们已经将全篇博文转换成章节,并在每一章节添加了一栏以展示 NGINX 实现微服务的相关内容。如果您认真听取建议,您将解决许多潜在的开发时甚至是在编写代码之前可能产生的问题。此书在关于 [NGINX 微服务参考架构](https://www.nginx.com/blog/introducing-the-nginx-microservices-reference-architecture/) 方面也是一本非常不错的书籍,其实现了以下提出的大部分理论。 +在本书中,我们已经将全篇博文转换成章节,并在每一章节添加了尾栏以展示 NGINX 实现微服务的相关内容。如果您认真听取建议,您将解决许多潜在的开发时甚至是在编写代码之前可能会遇到的问题。此书在关于 [NGINX 微服务参考架构](https://www.nginx.com/blog/introducing-the-nginx-microservices-reference-architecture/) 方面也是一本非常不错的书籍,其实现了以下提出的大部分理论。 本书章节: @@ -21,7 +21,7 @@ Floyd Smith 2. **使用 API 网关** - API 网关是整个微服务应用的单入口,它为每一个微服务提供了 API。NGINX Plus 可以很好地应用在 API 网关,提供了负载均衡和静态文件缓存等功能。 + API 网关是整个微服务应用的单入口,它为每一个微服务提供了 API。NGINX Plus 可以很好地应用于 API 网关,提供了负载均衡和静态文件缓存等功能。 3. **微服务架构中的进程间通信** @@ -33,16 +33,16 @@ Floyd Smith 5. **微服务事件驱动数据管理** - 每个微服务维护着自己特有的数据展示与存储,而不是共享一个统一、跨越一个(或两个)单体应用的数据存储。虽然这给予了您很大的灵活性,但也可能导致变得复杂。本章可以帮助您理清这些问题。 + 每个微服务维护着自己特有的数据展示与存储,而不是共享一个统一、跨越一个(或两个)单体应用的数据存储。虽然这能给予您很大的灵活性,但也可能导致变得复杂。本章可以帮助您理清这些问题。 6. **选择微服务部署策略** - 在 DevOps 世界中,您怎样做事与您最初要做的事一样重要。Chris 讲解了微服务部署的主要模式,以便您可以为您的应用作出明智的选择, + 在 DevOps 世界中,您怎样做与您最初要做的事一样重要。Chris 讲解了微服务部署的主要模式,以便您可以为您的应用作出合理的选择, 7. **重构单体应用为微服务** 在理想世界里,我们不会缺少时间与金钱,因此可以将核心软件转化为最新最好的技术、工具和方法。然而您可能会发现自己正在将一个单体应用转化为微服务,而且进展非常缓慢……。Chris 在本章将为您讲解明智的做法。 -我们认为您会发现本书的每一章都是值得阅读的,我们希望当您在开发自己的微服务应用时,能应用到本书的内容。 +我们认为您将会发现本书的每一章都是值得阅读的,我们希望当您在开发自己的微服务应用时,能应用到本书的内容。 Floyd Smith,NGINX 公司 \ No newline at end of file diff --git a/1-introduction-to-microservices.md b/1-introduction-to-microservices.md index 4f5c29f..759c6f4 100644 --- a/1-introduction-to-microservices.md +++ b/1-introduction-to-microservices.md @@ -1,14 +1,14 @@ # 1、微服务简介 -如今微服务倍受关注:文章、博客、社交媒体讨论和会议演讲。微服务正在迅速朝向[加德纳技术成熟度曲线(Gartner Hype cycle)](http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp)的高峰前进。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认[微服务架构模式](http://microservices.io/patterns/microservices.html)具有非常明显的优势 — 特别是在实施敏捷开发和复杂的企业应用交付方面。 +如今微服务倍受关注:文章、博客、社交媒体讨论和会议演讲。微服务正在迅速朝着[加德纳技术成熟度曲线(Gartner Hype cycle)](http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp)的高峰前进。与此同时,也有持怀疑态度的软件社区人员认为微服务没什么新鲜可言。反对者声称它的思想只是面向服务架构(SOA)的重塑。然而,无论是炒作还是怀疑,不可否认,[微服务架构模式](http://microservices.io/patterns/microservices.html)具有非常明显的优势 — 特别是在实施敏捷开发和复杂的企业应用交付方面。 -本书的七个章主要介绍如何设计、构建和部署微服务,这是本书的第一章。在此章节中,您将了解到微服务的由来和与传统[单体应用模式](http://microservices.io/patterns/monolithic.html)的对比。这本电子书描述了许多关于微服务架构方面的内容。无论是在项目意义还是实施方面,您都能了解到微服务架构模式的优点与缺点。 +本书的七个章节主要介绍如何设计、构建和部署微服务,这是本书的第一章。在此章节中,您将了解到微服务的由来和与传统[单体应用模式](http://microservices.io/patterns/monolithic.html)的对比。这本电子书描述了许多关于微服务架构方面的内容。无论是在项目意义还是实施方面,您都能了解到微服务架构模式的优点与缺点。 我们先来看看为什么要考虑使用微服务。 ## 1.1、构建单体应用 -我们假设,您开始开发一个打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流和需求收集,您将手动或者使用类似 Rails、Spring Boot、Play 或者 Maven 等平台来生成一个新项目。 +我们假设,您开始开发一个打车应用,打算与 Uber 和 Hailo 竞争。经过初步交流和需求收集,您开始手动或者使用类似 Rails、Spring Boot、Play 或者 Maven 等平台来生成一个新项目。 该新应用是一个模块化的六边形架构,如图 1-1 所示: @@ -18,35 +18,35 @@ 尽管有一个逻辑模块化架构,但应用程序被作为一个单体进行打包和部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包成 WAR 文件部署在如 Tomcat 或者 Jetty 之类的应用服务器上。其他 Java 应用程序被打包成自包含(self-contained)的可执行 JAR。类似地,Rails 和 Node.js 应用程序被打包为有目录层次的结构。 -以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具就是专注于构建单体应用。这些应用程序也很容易测试。您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署。你只需拷贝打包好的应用程序到服务器。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它可以良好运作。 +以这种风格编写的应用是很常见的。他们很容易开发,因为我们的 IDE 和其他工具就是专注于构建单体应用。这些应用程序也很容易测试,您可以通过简单地启动并使用如 Selenium 测试包来测试 UI 以轻松地实现端到端(end-to-end)测试。单体应用同样易于部署,你只需拷贝打包好的应用程序到服务器上。您还可以通过运行多个副本和结合负载均衡器来扩展应用。在项目的早期阶段,它可以良好运作。 ## 1.2、走向单体地狱 -不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。您的开发团队在每个冲刺阶段都要实现了更多的用户需求,这意味着需要添加了许多行代码。几年之后,小而简单的应用将会逐渐成长成一个[庞然大物似的单体][3]。为了给出一个极端示例,我最近和一位开发者做了交谈,他正在编写一个工具,该工具用于从他们的数百万行代码(lines of code,LOC)应用中分析出数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造出了这样的野兽。 +不幸的是,这种简单的方法有很大的局限性。成功的应用有一个趋势,随着时间推移而变得越来越臃肿。您的开发团队在每个冲刺阶段都要实现更多的用户需求,这意味着需要添加许多行代码。几年之后,小而简单的应用将会逐渐成长成一个[庞大的单体][3]。为了给出一个极端示例,我最近和一位开发者做了交谈,他正在编写一个工具,该工具用于从他们的数百万行代码(lines of code,LOC)应用中分析出数千个 JAR 之间的依赖。我相信这是大量开发者在多年齐心协力下创造出了这样的野兽。 -一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能会陷入了一个痛苦的世界,敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在是非常复杂。对于任何一个开发人员来说,这实在太过庞大,这是可以理解的。最终,正确修复 bug 和实现新功能变得非常困难而耗时。此外,这个趋势就像是往下的螺旋。如果基本代码都难以理解,那么改变也不会变得正确,您最终得到的将是一个巨大且不可思议的[大泥球][4]。 +一旦您的应用程序成为了一个庞大、复杂的单体,您的开发组织可能会陷入了一个痛苦的境地,敏捷开发和交付的任何一次尝试都将原地徘徊。一个主要问题是应用程序实在非常复杂,其对于任何一个开发人员来说显得过于庞大,这是可以理解的。最终,正确修复 bug 和实现新功能变得非常困难而耗时。此外,这种趋势就像是往下的螺旋。如果基本代码都令人难以理解,那么改变也不会变得正确,您最终得到的将是一个巨大且不可思议的[大泥球][4]。 应用程序的规模也将减缓发展。应用程序越大,启动时间越长。我[调查][5]过开发者们的单体应用的大小和性能,一些报告的启动时间为 12 分钟。我也听说过应用程序启动需要 40 分钟以上的怪事。如果开发人员经常要重启应用服务器,那么很大一部分时间都是在等待中度过,他们的生产力将受到限制。 -另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了每天可多次将变更推送到生产环境中。这对于复杂的单体非常困难,因为您需要重新部署整个应用程序才能更新其中任何一部分。对于我之前提到的漫长启动时间,这也不会是什么好事。此外,因变化所产生的影响通常不是很明确,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。 +另一个大问题是,复杂的单体应用本身就是持续部署的障碍。如今,SaaS 应用发展到了可以每天多次将变更推送到生产环境。这对于复杂的单体来说非常困难,因为您需要重新部署整个应用程序才能更新其中任何一部分。联想到我之前提到的漫长启动时间,这也不会是什么好事。此外,因变更所产生的影响通常不是很明确,您很可能需要做大量的手工测试。因此,持续部署是不可能做到的。 -当不同模块存在资源需求冲突时,单体应用可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 [Amazon EC2 Compute Optimized 实例][6]中。另一个模块可能是一个内存数据库,最适合部署到 [EC2 Memory-optimized 实例][7]。然而,因为这些模块被部署在一起,您必须在硬件选择上做出妥协。 +当不同模块存在资源需求冲突时,单体应用可能难以扩展。例如,一个模块可能会执行 CPU 密集型图像处理逻辑,理想情况下是部署在 [Amazon EC2 Compute Optimized 实例][6]中。另一个模块可能是一个内存数据库,最适合部署到 [EC2 Memory-optimized 实例][7]。然而,由于这些模块被部署在一起,您必须在硬件选择上做出妥协。 -单体应用的另一个问题是可靠性。因为所有模块运行在同一进程中。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有实例都是相同的,该错误将影响到整个应用的可用性。 +单体应用的另一个问题是可靠性。因为所有模块都运行在同一进程中。任何模块的一个 bug,比如内存泄漏,可能会拖垮整个进程。此外,由于应用程序的所有实例都是相同的,该错误将影响到整个应用的可用性。 -最后但同样重要,单体应用使得采用新框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。如果使用较新的 ABC 框架来重写整个应用,这将非常昂贵(在时间和成本方面),即使框架非常好。因此,这对于采用新技术是一个非常大的障碍。您在项目开始时无论选择何种新技术都会感到困扰。 +最后但同样重要,单体应用使得采用新框架和语言变得非常困难。例如,我们假设您有 200 万行代码使用了 XYZ 框架编写。如果使用较新的 ABC 框架来重写整个应用,这将非常昂贵(在时间和成本方面),即使框架非常好。因此,这对于采用新技术是一个非常大的障碍。在项目开始时,您无论选择何种新技术都会感到困扰。 -总结一下:您有一个成功的关键业务应用程序,它已经发展成为一个只有少数开发人员(如果有的话)能够理解的巨大单体。它使用了过时、非生产性技术编写,这使得招聘优秀开发人员变得非常困难。应用程序难以扩展,不可靠。因此敏捷开发和应用交付是不可能的。 +总结一下:您有一个成功的关键业务应用程序,它已经发展成为一个只有少数开发人员(如果有的话)能够理解的巨大单体。它使用了过时、非生产性技术编写,这使得招聘优秀开发人员变得非常困难。应用程序变得难以扩展,不可靠。因此敏捷开发和应用交付是不可能的。 那么您能做些什么呢? ## 1.3、微服务 — 解决复杂问题 -许多组织,如 Amazon、eBay 和 [Netflix][8],已经采用现在所谓的[微服务架构模式][9]解决了这个问题,而不是构建一个臃肿的单体应用。它的思路是将应用程序分解成一套较小的互连服务。 +许多如 Amazon、eBay 和 [Netflix][8] 这样的组织,已经采用现在所谓的[微服务架构模式][9]解决了这个问题,而不是构建一个臃肿的单体应用。它的思路是将应用程序分解成一套较小的互连服务。 -一个服务通常实现了一组不同的特性或者功能,例如订单管理、客户管理等。每一个微服务都是一个迷你应用,它自己的六边形架构包括了业务逻辑以及多个适配器。 +一个服务通常实现了一组不同的特性或功能,例如订单管理、客户管理等。每一个微服务都是一个迷你应用,它自己的六边形架构包括了业务逻辑以及多个适配器。 一些微服务会暴露一个供其他微服务或应用客户端消费的 API。其他微服务可能实现了一个 web UI。在运行时,每个实例通常是一个云虚拟机(virtual machine,VM)或者一个 Docker 容器。 @@ -54,13 +54,13 @@ ![图 1-2、一个单体应用分解成微服务][image-2] -应用程序的每个功能区域现在都由自己的微服务实现。此外,Web 应用程序被分为一组更简单的 Web 应用程序。例如,以我们的出租车为例,一个是乘客的,一个是司机的。这使得它更容易地为特定的用户、司机、设备或者专门的用例部署不同的场景。每个后端服务暴露一个 REST API,大部分的服务消费由其他服务提供的 API。例如,Driver Management 使用了 Notification 服务器来告知一个可用司机关于一个可选路程。UI 服务调用了其他服务来渲染页面。服务也可以使用异步、基于消息的通信。本电子书后面将会[更加详细](3-inter-process-communication.md)介绍服务间的通信。 +应用程序的每个功能区域现在都由自己的微服务实现。此外,Web 应用程序被划分为一组更简单的应用。例如,以我们的出租车为例,一个是乘客的应用,一个是司机的应用。这使得它更容易地为特定的用户、司机、设备或者专门的用例部署不同的场景。每个后端服务暴露一个 REST API,大部分的服务消费的 API 由其他服务提供。例如,Driver Management 使用了 Notification 服务器来通知可用司机一个可选路程。UI 服务调用了其他服务来渲染页面。服务也可以使用异步、基于消息的通信。本电子书后面将会[更加详细](3-inter-process-communication.md)介绍服务间通信。 -一些 REST API 也暴露给移动端应用供司机和乘客使用。然而,应用不能直接访问后端服务。相反,他们之间的通信是由一个称为 [API 网关][10](API Gateway)的中介负责。API 网关负责负载均衡、缓存、访问控制、API 计量和监控,[可以通过使用 NGINX 来实现][11]。[第二章](2-using-an-api-gateway.md)将详细讨论 API 网关。 +一些 REST API 也暴露给移动端应用以供司机和乘客使用。然而,应用不能直接访问后端服务。相反,他们之间的通信是由一个称为 [API 网关][10](API Gateway)的中介负责。API 网关负责负载均衡、缓存、访问控制、API 计量和监控,[可以通过使用 NGINX 来实现][11]。[第二章](2-using-an-api-gateway.md)将详细讨论 API 网关。 -![图 1-3、开发和交付中的缩放立方(Scale Cube)][image-3] +![图 1-3、开发和交付中的伸缩立方(Scale Cube)][image-3] -微服务架构模式相当于此缩放立方的 Y 轴坐标,此立方是一个来自[《架构即未来》][12]的三维伸缩模型。另外两个坐标轴是由运行多个相同应用程序副本的负载均衡器组成的 X 轴坐标和 Z 轴坐标(或数据分区),其中请求的属性(例如,一行记录的主键或者客户标识)用于将请求路由到特定的服务器。 +微服务架构模式相当于此伸缩立方的 Y 轴坐标,此立方是一个来自[《架构即未来》][12]的三维伸缩模型。另外两个坐标轴是由运行多个相同应用程序副本的负载均衡器组成的 X 轴坐标和 Z 轴坐标(或数据分区),其中请求的属性(例如,一行记录的主键或者客户标识)用于将请求路由到特定的服务器。 应用程序通常将这三种类型的坐标方式结合一起使用。Y 轴坐标将应用分解成微服务,如图 1-2 所示。 @@ -68,11 +68,11 @@ ![图 1-4、使用 Docker 部署 Trip Management 服务][image-4] -在运行时,Trip Management 服务由多个服务实例组成,每个服务实例是一个 Docker 容器。为了实现高可用,容器是在多个云虚拟机上运行的。服务实例的之前是一个[如 NGINX 的负载均衡器][13],用于跨实例分发请求。负载均衡器也可以处理其他问题,如[缓存][14]、[访问控制][15]、[API 度量][16]和[监控][17]。 +在运行时,Trip Management 服务由多个服务实例组成,每个服务实例是一个 Docker 容器。为了实现高可用,容器是在多个云虚拟机上运行的。服务实例之前是一个[类似 NGINX 的负载均衡器][13],用于跨实例分发请求。负载均衡器也可以处理其他问题,如[缓存][14]、[访问控制][15]、[API 度量][16]和[监控][17]。 -微服务架构模式明显影响到了应用程序与数据库之间的关系。与与其他共享单个数据库模式(schema)服务有所不同,每一个服务都有自己的数据库模式。一方面,这种做法与企业级数据库数据模型的想法相背,此外,它经常导致部分数据冗余。然而,如果您想从微服务中受益,每一个服务都应该有自己的数据库模式。因为它能实现松耦合。图 1-5 展示了数据库架构示例应用程序。 +微服务架构模式明显影响到了应用程序与数据库之间的关系,与其他共享单个数据库模式(schema)服务有所不同,其每一个服务都有自己的数据库模式。一方面,这种做法与企业级数据库数据模型的想法相背,此外,它经常导致部分数据冗余。然而,如果您想从微服务中受益,每一个服务都应该有自己的数据库模式,因为它能实现松耦合。图 1-5 展示了数据库架构示例应用程序。 -每个服务都有自己的数据库。而且,服务可以使用一种最适合其需求、号称多语言持久架构(polyglot persistence architecture)的数据库。例如,Driver Management,找到与潜在乘客接近的司机必须使用支持高效地理查询的数据库。 +每个服务都拥有各自的数据库。而且,服务可以使用一种最适合其需求、号称多语言持久架构(polyglot persistence architecture)的数据库。例如,Driver Management,要找到与潜在乘客接近的司机,就必须使用支持高效地理查询的数据库。 ![图 1-5、打车应用的数据库架构][image-5] @@ -81,38 +81,38 @@ ## 1.4、微服务的优点 -微服务架构模式有许多非常好的地方。第一,它解决了复杂问题。它把可能会变得庞大的单体应用程序分解成一套服务。虽然功能数量不变,但是应用程序已经被分解成可管理的块或者服务。每个服务都有一个明确定义的边界的方式,如远程过程调用(RPC)驱动或者消息驱动的 API。微服务架构模式强制一定程度的模块化,实际上,使用单体代码来实现是极其困难的。因此,个体服务能被更快地开发,并更容易理解与维护。 +微服务架构模式有许多非常好的地方。第一,它解决了复杂问题。它把可能会变得庞大的单体应用程序分解成一套服务。虽然功能数量不变,但是应用程序已经被分解成可管理的块或者服务。每个服务都有一个明确定义边界的方式,如远程过程调用(RPC)驱动或消息驱动 API。微服务架构模式强制一定程度的模块化,实际上,使用单体代码来实现是极其困难的。因此,使用微服务架构模式,个体服务能被更快地开发,并更容易理解与维护。 -第二,这种架构使得每个服务都可以由一个团队独立专注开发。开发者可以自由选择任何符合服务 API 契约的技术。当然,更多的组织是希望通过技术选型限制来避免完全混乱的状态。然而,这种自由意味着开发人员不再有可能在这种自由的新项目开始时使用过时的技术。当编写一个新服务时,他们可以选择当前的技术。此外,由于服务比较小,使用当前技术重写旧服务将变得更加可行。 +第二,这种架构使得每个服务都可以由一个团队独立专注开发。开发者可以自由选择任何符合服务 API 契约的技术。当然,更多的组织是希望通过技术选型限制来避免完全混乱的状态。然而,这种自由意味着开发人员不再有可能在这种自由的新项目开始时使用过时的技术。当编写一个新服务时,他们可以选择当前的技术。此外,由于服务较小,使用当前技术重写旧服务将变得更加可行。 -第三,微服务架构模式可以实现每一个微服务独立部署。开发人员根本不需要去协调部署本地变更到它们的服务。这些变更一经测试即可立即部署。比如,UI 团队可以执行 A|B 测试,并快速迭代 UI 变更。微服务架构模式使得持续部署成为可能。 +第三,微服务架构模式可以实现每个微服务独立部署。开发人员根本不需要去协调部署本地变更到服务。这些变更一经测试即可立即部署。比如,UI 团队可以执行 A|B 测试,并快速迭代 UI 变更。微服务架构模式使得持续部署成为可能。 最后,微服务架构模式使得每个服务能够独立扩展。您可以仅部署满足每个服务的容量和可用性约束的实例数目。此外,您可以使用与服务资源要求最匹配的硬件。例如,您可以在 EC2 Compute Optimized 实例上部署一个 CPU 密集型图像处理服务,并且在 EC2 Memory-optimized 实例上部署一个内存数据库服务。 ## 1.5、微服务的缺点 -就像 Fred Brooks 近 30 年前写的[《人月神话》][20]说的,没有银弹。与其他技术一样,微服务架构模式也存在着缺点。其中一个缺点就是名称本身。微服务这个术语的重点过多偏向于服务的规模。事实上,有些开发者主张构建极细粒度的 10 至 100 LOC(代码行) 服务虽然对于小型服务可能比较好,但重要的是要记住,小型服务只是一种手段,而不是主要目标。微服务的目标在于充分分解应用程序以方便应用敏捷开发和部署。 +就像 Fred Brooks 30 年前左右写的[《人月神话》][20]说的,**没有银弹**。与其他技术一样,微服务架构模式也存在着缺点。其中一个缺点就是名称本身。微服务这个术语的重点过多偏向于服务的规模。事实上,有些开发者主张构建极细粒度的 10 至 100 LOC(代码行) 服务,虽然这对于小型服务可能比较好,但重要的是要记住,小型服务只是一种手段,而不是主要目标。微服务的目标在于充分分解应用程序以方便应用敏捷开发和部署。 -微服务另一个主要的缺点是由于微服务是一个分布式系统,使得整体变得复杂。开发者需要选择和实现基于消息或者 RPC 的进程间通信机制。此外,由于目标请求可能很慢或者不可用,他们还必须编写代码来处理局部故障。虽然这些都不是很复杂高深,但模块间通过语言级方法/过程调用相互调用,这比单体应用要复杂得多。 +微服务另一个主要缺点是由于微服务是一个分布式系统,其使得整体变得复杂。开发者需要选择和实现基于消息或者 RPC 的进程间通信机制。此外,由于目标请求可能很慢或者不可用,他们必须要编写代码来处理局部故障。虽然这些并不是很复杂、高深,但模块间通过语言级方法/过程调用相互调用,这比单体应用要复杂得多。 -微服务的另一个挑战是分区数据库架构。更新多个业务实体的业务事务是相当普遍的。这些事务在单体应用中的实现显得微不足道,因为只存在一个单独的数据库。在基于微服务的应用程序中,您需要更新不同服务所用的数据库。通常不会选择分布式事务,不仅仅是因为 [CAP 定理][21]。他们根本不支持如今高度可扩展的 NoSQL 数据库和消息代理。您最后不得不使用基于最终一致性的方法,这对于开发人员来说更具挑战性。 +微服务的另一个挑战是分区数据库架构。更新多个业务实体的业务事务是相当普遍的。这些事务在单体应用中的实现显得微不足道,因为单体只存在一个单独的数据库。在基于微服务的应用程序中,您需要更新不同服务所用的数据库。通常不会选择分布式事务,不仅仅是因为 [CAP 定理][21]。他们根本不支持如今高度可扩展的 NoSQL 数据库和消息代理。您最后不得不使用基于最终一致性的方法,这对于开发人员来说更具挑战性。 -测试微服务应用程序也很复杂。例如,使用现代的框架如 Sprig Boot,只需要编写一个测试类来启动一个单体 web 应用程序并测试其 REST API。相比之下,一个类似的测试类对于微服务来说需要启动该服务及其所依赖的任何服务,或者至少为这些服务配置存根。再次声明,虽然这不是一件高深的事情,但不要低估了这样做的复杂性。 +测试微服务应用程序也很复杂。例如,使用现代框架如 Sprig Boot,只需要编写一个测试类来启动一个单体 web 应用程序并测试其 REST API。相比之下,一个类似的测试类对于微服务来说需要启动该服务及其所依赖的所有服务,或者至少为这些服务配置存根。再次声明,虽然这不是一件高深的事情,但不要低估了这样做的复杂性。 -微服务架构模式的另一个主要的挑战是实现了跨越多服务变更。例如,我们假设您正在实现一个变更服务 A、服务 B 和 服务 C 的需求,其中 A 依赖于 B,且 B 依赖于 C。在单体应用程序中,您可以简单地修改相应的模块、整合变更并一次性部署他们。相反,在微服务中您需要仔细规划和协调出现的变更至每个服务。例如,您需要更新服务 C,然后更新服务 B,最后更新服务 A。幸运的是,大多数变更只会影响一个服务;需要协调的多服务变更相对较少。 +微服务架构模式的另一个主要挑战是实现了跨越多服务变更。例如,我们假设您正在实现一个变更服务 A、服务 B 和 服务 C 的需求,其中 A 依赖于 B,且 B 依赖于 C。在单体应用程序中,您可以简单地修改相应的模块、整合变更并一次性部署他们。相反,在微服务中您需要仔细规划和协调出现的变更至每个服务。例如,您需要更新服务 C,然后更新服务 B,最后更新服务 A。幸运的是,大多数变更只会影响一个服务,需要协调的多服务变更相对较少。 -部署基于微服务的应用程序也是非常复杂。一个单体应用可以很容易地部署到基于传统负载均衡器的一组相同服务器上。每个应用程序实例都配置有基础设施服务的位置(主机和端口),比如数据库和消息代理。相比之下,微服务应用程序通常由大量的服务组成。例如,据 [Adrian Cockcroft][22] 了解到,Hailo 拥有 160 个不同的服务,Netflix 拥有的服务超过 600 个。 +部署基于微服务的应用程序也是相当复杂的。一个单体应用可以很容易地部署到基于传统负载均衡器的一组相同服务器上。每个应用程序实例都配置有基础设施服务的位置(主机和端口),比如数据库和消息代理。相比之下,微服务应用程序通常由大量的服务组成。例如,据 [Adrian Cockcroft][22] 了解到,Hailo 拥有 160 个不同的服务,Netflix 拥有的服务超过 600 个。 -每个服务都有多个运行时实例。还有更多的移动部件需要配置、部署、扩展和监控。此外,您还需要实现[服务发现机制](4-service-discovery.md),使得服务能够发现需要与之通信的任何其他服务的位置(主机和端口)。比较传统麻烦的基于票据(ticket-based)和手动操作方式无法扩展到如此复杂程度。因此,成功部署微服务应用程序要求开发人员能高度控制部署方式和高度自动化。 +每个服务都有多个运行时实例。还有更多的移动部件需要配置、部署、扩展和监控。此外,您还需要实现[服务发现机制](4-service-discovery.md),使得服务能够发现需要与之通信的任何其他服务的位置(主机和端口)。比较传统麻烦的基于票据(ticket-based)和手动的操作方式无法扩展到如此复杂程度。因此,要成功部署微服务应用程序,需要求开发人员能高度控制部署方式和高度自动化。 -一种自动化的方式是使用现成的平台即服务(PaaS),如 [Cloud Foundry][23]。PaaS 为开发人员提供了一种简单的方式来部署和管理他们的微服务。它让开发人员避开了诸如采购和配置 IT 资源等烦恼。同时,配置 PaaS 的系统与网络专业人员可以确保达到最佳实践以落实公司策略。 +一种自动化方式是使用现成的平台即服务(PaaS),如 [Cloud Foundry][23]。PaaS 为开发人员提供了一种简单的方式来部署和管理他们的微服务。它让开发人员避开了诸如采购和配置 IT 资源等烦恼。同时,配置 PaaS 的系统人员和网络专业人员可以确保达到最佳实践以落实公司策略。 -自动化微服务部署的另一个方式是开发自己的 PaaS。一个普遍的起点是使用集群方案,如 [Kubernetes][24],与 Docker 等容器技术相结合。在本书最后我们将看到[基于软件的应用交付][25]方式如 NGINX 是如何在微服务级别处理缓存、访问控制、API 计量和监控,这些可以帮助解决此问题。 +自动化微服务部署的另一个方式是开发自己的 PaaS。一个普遍的起点是使用集群方案,如 [Kubernetes][24],与 Docker 等容器技术相结合。在本书最后我们将看到如 NGINX 的[基于软件的应用交付][25]方式是如何在微服务级别处理缓存、访问控制、API 计量和监控,这些可以帮助解决此问题。 ## 1.6、总结 -构建复杂的微服务应用程序本质上是困难的。单体架构模式只适用于简单、轻量级的应用程序,如果您使用它来构建复杂应用,您最终会陷入一个痛苦的境地。微服务架构模式是复杂、持续发展应用的一个更好的选择。尽管它存在着缺点与实现挑战。 +构建复杂的微服务应用程序本质上是困难的。单体架构模式只适用于简单、轻量级的应用程序,如果您使用它来构建复杂应用,您最终会陷入痛苦的境地。微服务架构模式是复杂、持续发展应用的一个更好的选择。尽管它存在着缺点和实现挑战。 在后面的章节中,我将介绍微服务架构的方方面面并探讨诸如服务发现、服务部署方案以及将单体应用重构为服务的策略。 @@ -122,11 +122,11 @@ By Floyd Smith -[10000 个网站中有超过 50%][26] 使用 NGINX,这主要是因为它具有作为反向代理服务器的能力。您可以把 NGINX 放在当前应用程序甚至是数据库服务器之前以获取各种功能 — 更高的性能、更高的安全性、可扩展性、灵活性等。你现有的应用程序只需要配置代码和作出很少或无需改变。但对于存在性能压力的站点,或者预计未来存在高负荷,效果看起来似乎没那么神奇。 +[10000 个网站中有超过 50%][26] 使用 NGINX,这主要是因为它具有作为反向代理服务器的能力。您可以把 NGINX 放在当前应用程序甚至是数据库服务器之前以获取各种功能 — 更高的性能、更高的安全性、可扩展性、灵活性等。你现有的应用程序只需要配置代码和作出很少或无需改变。然而,对于存在性能压力的站点,或者预计未来存在高负荷,使用 NGINX 的效果看起来可能没那么神奇。 -那么这与微服务有什么关系呢?实现一个反向代理服务器,并使用 NGINX 的其他功能来为您提供架构灵活性。反向代理服务器、静态和应用文件缓存、SSL/TLS 和 HTTP/2 都会从您的应用程序剔除。让应用程序只做它该做的事,NGINX 还可作为负载均衡器,这是微服务实施过程中的一个关键角色。先进的 NGINX Plus 的功能包含了复杂的负载均衡算法、多种方式的会话持久和管理监控,这些对微服务尤其有用(NGINX 最近还增加了使用 DNS SRV 记录的服务发现支持,这是一个顶尖的功能)。而且,如本章所述,NGINX 可以自动化部署微服务。 +那么这与微服务有什么关系呢?实现一个反向代理服务器,并使用 NGINX 的其他功能来为您提供架构灵活性,反向代理服务器、静态和应用文件缓存、SSL/TLS 和 HTTP/2 都将从您的应用程序剔除。让应用程序只做它该做的事,NGINX 还可作为负载均衡器,这是微服务实施过程中的一个关键角色。先进的 NGINX Plus 的功能包含了复杂的负载均衡算法、多种方式的会话持久和管理监控,这些对微服务尤其有用(NGINX 最近还增加了使用 DNS SRV 记录的服务发现支持,这是一个顶尖的功能)。而且,如本章所述,NGINX 可以自动化部署微服务。 -此外,NGINX 还提供了必要的功能来支撑 [NGINX 微服务参考架构][27]中的三大模型。代理模型使用 NGINX 作为 API 网关;网格路由模型使用了一个额外的 NGINX 作为进程间通信中枢;Fabric 模型中的每个微服务使用一个 NGINX 来控制 HTTP 流量,在微服务之间实现 SSL/TLS,这非常具有突破性。 +此外,NGINX 还提供了必要的功能来支撑 [NGINX 微服务参考架构][27]中的三大模型。代理模型使用 NGINX 作为 API 网关;网格路由模型使用一个额外的 NGINX 作为进程间通信中枢;Fabric 模型中的每个微服务使用一个 NGINX 来控制 HTTP 流量,在微服务之间实现 SSL/TLS,这非常具有突破性。 [1]: http://www.gartner.com/technology/research/methodologies/hype-cycle.jsp [2]: http://microservices.io/patterns/monolithic.html diff --git a/7-refactoring-a-monolith-into-microservices.md b/7-refactoring-a-monolith-into-microservices.md index 51d3eb0..10320a1 100644 --- a/7-refactoring-a-monolith-into-microservices.md +++ b/7-refactoring-a-monolith-into-microservices.md @@ -1,22 +1,22 @@ # 7、重构单体为微服务 -本书是关于如何使用微服务构建应用程序,这是本书的第七章,也是最后一章。[第一章](1-introduction-to-microservices.md)介绍了微服务架构模式,讨论了使用微服务的优点与缺点。随后的章节讨论了微服务架构的方方面面:[使用 API ​​网关](2-using-an-api-gateway.md)、[进程间通信](3-inter-process-communication.md)、[服务发现](4-service-discovery.md)、[事件驱动数据管理](5-event-driven-data-management-for-microservices.md)和[部署微服务](6-choosing-deployment-strategy.md)。在本章中,我们将介绍单体应用迁移到微服务器的策略。 +本书主要介绍如何使用微服务构建应用程序,这是本书的第七章,也是最后一章。[第一章](1-introduction-to-microservices.md)介绍了微服务架构模式,讨论了使用微服务的优点与缺点。随后的章节讨论了微服务架构的方方面面:[使用 API ​​网关](2-using-an-api-gateway.md)、[进程间通信](3-inter-process-communication.md)、[服务发现](4-service-discovery.md)、[事件驱动数据管理](5-event-driven-data-management-for-microservices.md)和[部署微服务](6-choosing-deployment-strategy.md)。在本章中,我们将介绍单体应用迁移到微服务的策略。 我希望这本电子书能够让您对微服务架构、其优点和缺点以及何时使用它有很好的了解。微服务架构也许很适合您的组织。 -然而,您正工作于大型复杂的单体应用程序上,这是相当不错的机会。您开发和部署应用程序的日常经历是缓慢而痛苦的。微服务似乎是一个遥不可及的天堂。幸运的是,有一些战略可以用来逃离单体地狱。在本文中,我将描述如何将单体应用程序逐渐重构为一组微服务。 +您正工作于大型复杂的单体应用程序上,这是相当不错的机会。然而,您开发和部署应用程序的日常经历是缓慢而痛苦的。微服务似乎是一个遥不可及的天堂。幸运的是,有一些战略可以用来逃离单体地狱。在本文中,我将描述如何将单体应用程序逐渐重构为一组微服务。 ## 7.1、微服务重构概述 单体应用程序转换为微服务的过程是[应用程序现代化](https://en.wikipedia.org/wiki/Software_modernization)的一种形式。这是几十年来开发人员一直在做的事情。因此,在将应用程序重构为微服务时,有一些想法是可以重用的。 -一个不要使用的策略是“大爆炸”重写。就是您将所有的开发工作都集中在从头开始构建新的基于微服务器的应用程序。虽然这听起来很吸引人,但非常危险,有可能会失败。[据 AsMartin Fowler 讲到](http://www.randyshoup.com/evolutionary-architecture):“大爆炸重写的唯一保证就是大爆炸!”("the only thing a Big Bang rewrite guarantees is a Big Bang!")。 +一个不要使用的策略是“大爆炸”重写。就是您将所有的开发工作都集中在从头开始构建新的基于微服务的应用程序。虽然这听起来很吸引人,但非常危险,有可能会失败。[据 AsMartin Fowler 讲到](http://www.randyshoup.com/evolutionary-architecture):“大爆炸重写的唯一保证就是大爆炸!”("the only thing a Big Bang rewrite guarantees is a Big Bang!")。 -您应该逐步重构单体应用程序,而不是通过大爆炸重写。您逐渐添加新功能,并以微服务的形式创建现有功能的扩展 —— 以互补的形式修改单体应用,并且一同运行微服务和修改的单体。随着时间推移,单体应用程序实现的功能量会缩小,直到它完全消失或变成另一个微服务。这种策略类似于在 70公里/小时的高速公路上驾驶一辆汽车,这很具有挑战性,但比尝试大爆炸改写的风险要小得多。 +您应该逐步重构单体应用程序,而不是通过大爆炸重写。您可以逐渐添加新功能,并以微服务的形式创建现有功能的扩展 — 以互补的形式修改单体应用,并且一同运行微服务和修改后的单体。随着时间推移,单体应用程序实现的功能量会缩小,直到它完全消失或变成另一个微服务。这种策略类似于在 70公里/小时的高速公路上驾驶一辆汽车,很具挑战性,但比尝试大爆炸改写的风险要小得多。 -![](resources/7.png) +![葡萄树](resources/7.png) -Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.martinfowler.com/bliki/StranglerApplication.html)(Strangler Application)。这个名字来自于热带雨林中发现的葡萄树(也称为绞杀榕)。一棵葡萄树生长在一棵树上,以获取森林冠层之上的阳光。有时,树死了,留下一个树形的腾。应用现代化也遵循相同的模式。我们将构建一个新的应用程序,包括了围绕遗留应用的微服务(它将会慢慢缩小或者最终消亡)。 +Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.martinfowler.com/bliki/StranglerApplication.html)(Strangler Application)。这个名字来自发现于热带雨林中的葡萄树(也称为绞杀榕)。一棵葡萄树生长在一棵树上,以获取森林冠层之上的阳光。有时,树死了,留下一个树形的腾。应用现代化也遵循相同的模式。我们将构建一个新的应用程序,包括了围绕遗留应用的微服务(它将会慢慢缩小或者最终消亡)。 让我们来看看能做到这点的不同策略。 @@ -31,7 +31,7 @@ Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.mart 除了新服务和传统的单体,还有另外两个组件。第一个是请求路由,它处理传入的(HTTP)请求,类似于[第二章](2-using-an-api-gateway.md)中描述的 API 网关。路由向新服务发送与新功能相对应的请求。它将遗留的请求路由到单体。 -另一个组件是粘合代码,它将服务与单体集成。一个服务很少孤立存在,通常需要访问单体的数据。位于单体、服务或两者中的胶合代码负责数据集成。该服务使用粘合代码来读取和写入单体数据。 +另一个组件是粘合代码,它将服务与单体集成。一个服务很少孤立存在,通常需要访问单体的数据。位于单体、服务或两者中的粘合代码负责数据集成。该服务使用粘合代码来读取和写入单体数据。 服务可以使用三种策略来访问单体数据: @@ -39,7 +39,7 @@ Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.mart - 直接访问单体数据库 - 维护自己的数据副本,与单体数据库同步 -粘合代码有时被称为防护层(anti-corruption layer)。这是因为粘合代码阻止了服务被遗留的单体领域模型的概念所污染,这些服务具有自己的原始领域模型。粘合代码在两种不同的模型之间转换。防护层一词首先出现于埃里克·埃文斯(Eric Evans)的必读图书[《领域驱动设计》](http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?ie=UTF8&s=books&qid=1238687848&sr=8-1)(Domain Driven Design)中,并在[白皮书](http://docs.scala-lang.org/overviews/core/futures.html)中进行了改进。开发一个防护层并不是一件简单的事。但是,如果您想要从单体地狱中走出来,这是必不可少的步骤。 +粘合代码有时被称为防护层(anti-corruption layer)。这是因为粘合代码阻止了服务被遗留的单体领域模型的概念所污染,这些服务具有自己的原始领域模型。粘合代码在两种不同的模型之间转换。防护层一词首先出现于埃里克·埃文斯(Eric Evans)所著的必读图书[《领域驱动设计》](http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=sr_1_1?ie=UTF8&s=books&qid=1238687848&sr=8-1)(Domain Driven Design)中,并在[白皮书](http://docs.scala-lang.org/overviews/core/futures.html)中进行了改进。开发一个防护层并不是一件简单的事情。但是,如果您想要从单体地狱中走出来,这是必不可少的步骤。 使用轻量级服务来实现新功能有几个好处。它防止单体变得更加难以管理。该服务可以独立于单体开发、部署和扩展。可让您创建的每个新服务体验到微服务架构的优势。 @@ -60,13 +60,13 @@ Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.mart 访问基础架构组件的组件,如数据库和消息代理。 -一方面的表现逻辑和另一方的业务和数据访问逻辑之间通常有一个完全的隔离。业务层具有由一个或多个门面组成的粗粒度 API,其封装了业务逻辑组件。这个 API 是一个天然的边界,您可以沿着该边界将单体拆分成两个较小的应用程序。一个应用程序包含表现层。另一个应用程序包含业务和数据访问逻辑。分割后,表现逻辑应用程序对业务逻辑应用程序进行远程调用。 +一方的表现逻辑和另一方的业务和数据访问逻辑之间通常有一个完全的隔离。业务层具有由一个或多个门面组成的粗粒度 API,其封装了业务逻辑组件。这个 API 是一个天然的边界,您可以沿着该边界将单体拆分成两个较小的应用程序。一个应用程序包含表现层。另一个应用程序包含业务和数据访问逻辑。分割后,表现逻辑应用程序对业务逻辑应用程序进行远程调用。 重构之前和之后的架构如图 7-2 所示。 ![图 7-2、重构现有的应用程序](resources/7-2.png) -以这种方式拆分单体有两个主要优点。它使您能够独立于彼此开发、部署和扩展这两个应用。特别是,它允许表现层开发人员在用户界面上快速迭代,并且可以轻松执行 A/B 测试。这种方法的另一个优点是它暴露了可以被您开发的微服务调用的远程 API。 +以这种方式拆分单体有两个主要优点。它使您能够独立于彼此开发、部署和扩展这两个应用。特别是它允许表现层开发人员在用户界面上快速迭代,并且可以轻松执行 A/B 测试。这种方法的另一个优点是它暴露了可以被您开发的微服务调用的远程 API。 然而,这一策略只是一个局部解决方案。两个应用程序中的一个或两个很可能是一个无法管理的单体。您需要使用第三种策略来消除剩余的整体或单体。 @@ -82,7 +82,7 @@ Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.mart 将模块转换为服务通常是耗时的。您想按照您将获得的利益对模块进行排列。提取频繁更改的模块通常是有益的。一旦将模块转换为服务,您就可以独立于单体开发和部署,这将加快开发工作。 -提取这些资源需求与单体的其他模块有显著不同的模块也是有益的。例如,将有一个有内存数据库的模块转换为服务是很有用的,这样可以部署在具有大量内存的主机上,无论是裸机服务器、虚拟机还是云实例。同样,提取实现了计算昂贵算法的模块也是值得的,因为该服务可以部署在具有大量 CPU 的主机上。通过将具有特定资源需求的模块转换为服务,您可以使应用程序更加容易、廉价地扩展。 +提取这些与单体的其他模块有显著不同的模块也是有益的。例如,将有一个有内存数据库的模块转换为服务是很有用的,这样可以部署在具有大量内存的主机上,无论是裸机服务器、虚拟机还是云实例。同样,提取实现了计算昂贵算法的模块也是值得的,因为该服务可以部署在具有大量 CPU 的主机上。通过将具有特定资源需求的模块转换为服务,您可以使应用程序更加容易、廉价地扩展。 当找到要提取的模块时,寻找现有的粗粒度边界(又称为接缝)是有用的。它们使模块转成服务变得更容易和更连廉价。有关这种边界的一个例子是一个仅通过异步消息与应用程序的其他部分进行通信的模块。将该模块转变为微服务相对比较廉价和简单。 @@ -99,7 +99,7 @@ Martin Fowler 将这种应用现代化策略称为[杀手应用](http://www.mart 第二个重构步骤是将模块转换为一个独立服务。入站和出站接口使用 IPC 机制的代码来实现。您将很可能需要通过将 Module Z 与 [Microservice Chassis](http://microservices.io/patterns/microservice-chassis.html) 框架相结合来构建服务,该框架负责处理诸如服务发现之类的横切点。 -一旦您提取了一个模块,您就可以独立于单体和任何其他服务开发、部署和扩展其他服务。您甚至可以从头开始重写服务;在这种情况下,整合服务与单体的 API 代码成为在两个领域模型之间转换的防护层。每次提取服务时,您都会朝微服务方向迈近一步。随着时间的推移,单体将缩小,您将拥有越来越多的微服务。 +一旦您提取了一个模块,您就可以独立于单体和任何其他服务开发、部署和扩展其他服务。您甚至可以从头开始重写服务。在这种情况下,整合服务与单体的 API 代码成为在两个领域模型之间转换的防护层。每次提取服务时,您都会朝微服务方向迈近一步。随着时间的推移,单体将缩小,您将拥有越来越多的微服务。 @@ -118,12 +118,12 @@ by Floyd Smith - **更好地支持微服务** - 如第五章最后栏目所述,NGINX 和 [NGINX Plus](https://www.nginx.com/products/) 具有利于开发基于微服务的应用的功能。当您开始重新设计单体应用时,由于 NGINX 的功能,您的微服务将执行得更好、更易于管理。 + 如第五章尾栏所述,NGINX 和 [NGINX Plus](https://www.nginx.com/products/) 具有利于开发基于微服务的应用的功能。当您开始重新设计单体应用时,由于 NGINX 的功能,您的微服务将执行得更好、更易于管理。 - **跨环境的功能抽象** - 从您管理的服务器到各种公共云、私有云和混合云上将功能迁移到 NGINX 作为反向代理服务器可以减少部署在新的环境中的设施数量变化。这补充扩展了微服务所固有的灵活性。 + 从您管理的服务器甚至是各种公共云、私有云和混合云上将功能迁移到 NGINX 作为反向代理服务器可以减少部署在新环境中的设施数量变化。这补充扩展了微服务所固有的灵活性。 - **NGINX 微服务参考架构可用性** 当您迁移到 NGINX 时,您可以借鉴 [NGINX 微服务参考架构](https://www.nginx.com/blog/introducing-the-nginx-microservices-reference-architecture/)(MRA,Microservices Reference Architecture),以便在迁移到微服务之后定义应用程序的最终结构,并根据需要使用的 MRA 部分应用于您创建的每个新的微服务。 -总而言之,实现NGINX作为您的转型的第一步,将压倒您的单片应用程序,使其更容易获得微服务的所有优势,并为您提供用于进行转换的模型。您可以了解有关 MRA 的更多信息,并获得 NGINX Plus 的免费试用版。 \ No newline at end of file +总而言之,实现使用 NGINX 作为您转型的第一步,压倒您的单体应用程序,使其更容易获得微服务的所有优势,并为您提供用于进行转换的模型。您可以了解有关 MRA 的更多信息,并获得 NGINX Plus 的免费试用版。 \ No newline at end of file