1.微服务简介@微服务的设计和开发

本文探讨了微服务架构如何解决大型单体应用程序的复杂性问题,允许独立开发、部署和扩展服务。微服务通过拆分应用程序为小型、相互协作的服务,提高了敏捷性和可扩展性。然而,它也带来了分布式系统的挑战,如服务通信和数据库分区。微服务模式鼓励使用轻量级协议,如REST,和自动化部署策略,如使用NGINX作为反向代理服务器和API网关。
摘要由CSDN通过智能技术生成

微服务目前受到很多关注:文章,博客,讨论,社交媒体和会议演示。他们正迅速走向加特纳·海普周期中过高期望的顶峰。与此同时,软件界有些怀疑论者认为微服务并不新鲜。反对者声称,这个想法只是服务型架构(SOA)的重塑。然而,尽管炒作和怀疑,微服务架构模式(Microservices Architecture pattern)有显著的好处。特别是在实现复杂企业应用程序的敏捷开发和交付方面。

这个章节是本书七个章节中的第一个章节,是关于设计,构建和部署微服务的。您将学习有关微服务的方法,以及它如何与更传统的单体结构模式(Monolithic Architecture pattern)进行比较。这本书将描述微服务架构模式下的各种元素。你将学习到关于微服务架构模式的优点和缺点,它是否对你的项目有意义, 以及如何应用它。

让我们先看看为什么你应该考虑使用微服务。

构建巨大的单体应用程序(Building Monolithic Applications)

让我们想象一下,你开始建立一个全新的出租车租赁应用程序,旨在与优步和Hailo竞争。在一些初步会议和要求收集后,您将手动创建一个新项目,或者使用特定的技术,比如 Rails, Spring Boot, Play, 或者 maven。
这个新的应用程序将有一个模块化六边形架构,如图1-1:

在这里插入图片描述

这个应用的核心是业务逻辑,它由定义服务(services)、域对象(domain objects)和事件(events)的模块实现。核心周围是与外部世界接口的适配器。适配器示例包括数据库访问组件(database access components)、生成和消费消息的消息组件(messaging components)以及暴露 API 或实现 UI 的 Web 组件。

尽管具有逻辑模块化架构,但应用程序还是被打包并作为整体部署。实际格式取决于应用程序的语言和框架。例如,许多 Java 应用程序被打包为 WAR 文件,并部署在应用程序服务器(如 Tomcat 或 Jetty)上。其他 Java 应用程序被打包为自成一体的可执行 JAR。同样,Rails 和 Node.js 应用程序被打包为目录层次结构

以这种风格编写的应用程序非常常见,它们很容易开发,因为我们的 ID 和其他工具专注于构建单个应用程序。这些类型的应用程序也很容易测试。只需启动应用程序,并使用 Selenium 等测试包测试 UI,即可实现端到端测试。

单体应用程序也易于部署 您只需将包装的应用程序复制到服务器,您也可以通过在负载平衡器后面运行多个副本来缩放应用程序。在项目的早期阶段,它工作得很好。

向单体应用的地狱前进

不幸的是,这种简单的方法有一个巨大的局限性。成功的应用程序有一个习惯,随着时间的推移增长,并最终成为巨大的。在每次冲刺期间,您的开发团队都会实施更多的用户故事,这当然意味着添加许多代码行。几年后,你的小,简单的应用程序将成长为一个可怕的巨石。为了举一个极端的例子,我最近采访了一位开发人员,他正在编写一个工具来分析数千个JAR之间的依赖关系。数百万行代码 (LOC) 应用程序。

我相信,经过众多开发人员多年来的共同努力,才打造出这样的野兽。

一旦您的应用程序成为一个大的,复杂的整体,您的开发组织可能处于痛苦的世界中。任何敏捷开发和交付的尝试都将举步维艰。一个主要问题是,应用程序是压倒性的复杂。它太大,任何单个开发人员都无法完全理解。因此,正确修复错误和实现新功能变得困难且耗时。更重要的是,这往往是一个螺旋式下降。如果代码库难以理解,那么更改将无法正确进行,您最终会遇到一个可怕的问题,难以理解的大球泥(big ball of mud)。

应用程序的绝对规模也会减慢开发速度。应用程序越大,启动时间越长,我调查了开发人员关于其单一应用程序的大小和性能,有些报告的启动时间长达 12 分钟。我还听到过应用程序需要长达 40 分钟才能启动的趣闻。如果开发人员必须定期重新启动应用程序服务器,那么他们一天的大部分时间将花费在等待中,他们的生产力将受到影响。

大型复杂单体应用程序的另一个问题是,它是持续部署的障碍。如今,SaaS 应用的最先进的技术是每天多次推动生产变更。这是极其困难的处理复杂的巨石,因为您必须重新部署整个应用程序,以更新它的任何一个部分。我前面提到的冗长的启动时间也无济于事。

此外,由于更改的影响通常不太了解,因此您可能需要进行广泛的手动测试 因此,连续部署几乎是不可能的。

当不同的模块具有相互矛盾的资源需求时,单片应用也很难缩放 例如,一个模块可能实现 CPU 密集的图像处理逻辑,最好部署在 Amazon EC2 计算优化实例中。另一个模块可能是内存数据库,最适合 EC2 内存优化实例 但是,由于这些模块是一起部署的,因此您不得不在硬件选择上做出妥协。

单体应用的另一个问题是可靠性,因为所有模块都在运行在同一过程中,任何模块中的 bug(如内存泄漏)都可能带来整个过程。此外,由于应用程序的所有实例都是相同的,该 bug 将影响整个应用程序的可用性。

最后但并非最不重要的一点是,单一应用使得采用新的框架和语言变得极其困难。例如,让我们想象一下,您有 200 万行代码使用 XYZ 框架编写。重写整个应用程序以使用较新的 ABC 框架(即使该框架要好得多)将非常昂贵(无论在时间和成本上)。因此,采用新技术存在巨大障碍,无论您在项目开始时做出何种技术选择,您都会陷入困境。

总结一下:你有一个成功的业务关键应用程序,已经成长为一个可怕的巨石,很少,如果有的话,开发人员理解。它是使用过时的、非生产性的技术编写的,这使得雇佣有才华的开发人员变得困难。应用程序难以缩放,不可靠。因此,无法灵活开发和交付应用程序。

所以你能够做些什么呢?

微服务 - 处理复杂性

许多组织,如亚马逊,易趣和Netflix,已经解决了这个问题。采用现在所谓的微服务架构模式(Microservices Architecture pattern)。这个想法不是构建单一的、单一的应用程序,而是将应用程序拆分为一组更小、相互关联的服务。

服务通常实现一组不同的特性或功能,如订单管理、客户管理等。每个微服务都是一个小型应用程序,它有自己的六边形架构,包括业务逻辑和各种适配器。某些微服务会暴露其他微服务或应用程序客户端消耗的 API。其他微服务可能会在运行时实现 Web UI,每个实例通常是云虚拟机 (VM) 或 Docker 容器。

例如,图 1-2 中显示了前面描述的系统的可能分解:
在这里插入图片描述

应用程序的每个功能区域现在由其自己的微服务实现。此外,Web 应用程序被拆分为一组更简单的 Web 应用程序 - 例如,在我们的出租车出租示例中,一个适用于乘客,一个用于司机。这使得为特定用户、设备或专用案例部署不同的体验更加容易。

每个后端服务都会暴露 REST API,并且大多数服务都会消费其他服务提供的 API。例如,驱动程序管理使用通知服务器告诉可用的驱动程序有关潜在行程 UI 服务调用其他服务以渲染网页服务,也可能使用异步的基于消息的通信,服务间通信将在本电子书的稍后详细内容中涵盖。

一些 REST API 还暴露在驾驶员和乘客使用的移动应用程序中 但是,应用程序无法直接访问后端服务. 相反,通信由称为 API 网关(API Gateway)的中间人进行调解.API 啊网关扶着的任务例如:负载均衡(load balancing), 缓存(caching), 访问控制(load balancing), API 统计(API metering), 监控(monitoring), 并可以有效地实现使用 NGINX。章节2 将详细的讨论 API 网关。

在这里插入图片描述

微服务架构模式对应于规模立方体的 Y 轴缩放,这是一个 3D 模型的可扩展性来源于优秀的书的可扩展性的艺术(The Art of Scalability)。
其他两个扩展轴是 X-轴扩展,其中包括在负载平衡器后面运行应用程序的相同副本,以及 Z 轴缩放(或数据分区),其中请求属性(例如,行的主要密钥或客户身份)用于将请求路由到特定服务器。

应用程序通常同时使用三种类型的缩放。Y 轴缩放分解图1-2中所示,应用于微服务。在运行时间,X 轴缩放在负载平衡器后面运行每个服务的多个实例,以获得吞吐量和可用性。某些应用程序也可能使用 Z 轴缩放来分区服务。图 1-4 显示了如何部署与 Docker 在亚马逊 EC2 上运行的行程管理服务。

在这里插入图片描述

在运行的时候,行程管理服务包含多个服务实例。每个服务实例是一个Docker容器。为了能够高可用,这个容器运行在多个云虚拟主机上。在服务实例前面是负载平衡器(如 NGINX),它在整个实例中分发请求。负载均衡器可能也会处理其他冲突,比如缓存,访问控制,API计量和监控。

微服务架构模式显著影响应用程序和数据库,而不是与其他共享一个数据库图服务,每个服务都有自己的数据库模式。另一方面,这种方法与全企业数据模型的想法相悖。此外,它经常导致某些数据的重复。但是,如果您想从微服务中受益,则每个服务必须有一个数据库模式,因为它可以确保松散的耦合。图1-5显示了同样的应用程序的数据架构

每个服务都有自己的数据库。此外,服务可以使用最适合其需求的数据库类型,即所谓的多语种持久性架构,例如,发现司机靠近潜在乘客的驱动程序管理必须使用支持高效地理查询的数据库。

在这里插入图片描述

表面上,微服务架构模式类似于SOA,通过这两种方法,架构由一组服务组成。然而,思考微服务架构模式的一种方法是,它是 SOA,没有网络服务规范 (ws-*) 和企业服务 BUS (ESB) 的商用化和感知包。基于微服务的应用程序喜欢更简单、更轻量级的协议,例如restful,而不是WS-*他们也非常避免使用ESB,而是实施微服务本身的 ESB 功能。微服务架构模式也拒绝 SOA 的其他部分,例如规范模式的概念数据访问.

微服务的优点

微服务架构模式有一系列重要的好处。首先,它解决了复杂性问题。它将本来是一个可怕的单一应用分解成一组服务。虽然功能总

量保持不变,但应用程序已分解为可管理的区块或服务 每个服务都以远程程序呼叫(RPC)驱动或消息驱动的 API 的形式具有明确定义的边界。微服务架构模式执行一种模块化水平,而这种模块化在实践中是极其难以实现的代码基数。因此,个人服务的发展速度要快得多,理解和维护起来也容易得多。

第二,这个架构运行每个服务有一个团队独立的开发,这个团队只聚焦于这个业务。开发者能够自由地选择使用什么杨的技术,只要该服务遵守 API 约定。当然,大多数组织都希望通过限制技术选项来避免完全的无政府状态。然而,这种自由意味着开发人员不再有义务使用新项目开始时可能过时的技术。在编写新服务时,他们可以选择使用当前技术。此外,由于服务相对较少,因此使用当前技术重写旧服务变得更加可行。

第三,微服务架构模式使每个微服务能够独立部署。开发人员永远不需要协调更改的部署本地到他们的服务。这些更改一经测试即可部署。例如,UI 团队可以执行 A|B 测试并快速迭在 UI 更改上。微服务架构模式使连续部署成为可能。

最后,微服务架构模式使每个服务能够独立缩放。此外,您可以仅部署满足其容量和可用性限制的每个服务的实例数,此外,您可以使用最符合服务资源要求的硬件,例如,您可以在 EC2 计算优化实例上部署 CPU 密集型图像处理服务,并在 EC2 内存优化实例上部署内存数据库服务。

微服务的缺点

正如弗雷德·布鲁克斯在近30年前的《神话人月》(The Mythical Man-Month)中所写的那样,像其他技术一样,没有一种高招只有优点没有缺点,微服务架构模式也有缺点。一个缺点是名称本身。"微服务"一词过分强调服务规模。事实上,有些开发商主张建立极其精细的10-100LOC服务。虽然小型服务更可取,但重要的是要记住,微服务是达到目的的手段,而不是首要目标。微服务的目标是充分分解应用程序,以促进敏捷的应用程序开发和部署。

微服务的另一个主要缺点是微服务应用程序是分布式系统,开发人员需要选择并实施基于消息传递或基于RPC的通信机制。此外,他的来处理部分故障,因为请求的目的地可能较慢或不可用。虽然这些都不是火箭科学,但它比单体应用要复杂得多,模块通过语言级的方法/程序调用相互调用。

微服务的另一个挑战是数据库结构的分区。更新多个业务实体的业务交易相当常见。由于存在单个数据库,因此在单一应用程序中实现此类交易微不足道。但是,在基于微服务的应用程序中,您需要更新不同服务拥有的多个数据库。使用分布式事务通常不是一种选择,这不仅仅是因为CAP定理。目前许多高度可伸缩的NoSQL数据库和消息传递代理都不支持它们。您最终不得不使用基于一致性的最终方法,这对开发人员来说更具挑战性。

测试微服务应用程序也要复杂得多。例如,对于像Spring Boot这样的现代框架,编写一个测试类来启动一个单片web应用程序并测试它的REST API是很简单的。相反,服务的类似测试类需要启动该服务及其依赖的任何服务,或者至少为这些服务配置存根。再说一次,这不是火箭科学,但重要的是不要低估了做这件事的复杂性。

微服务体系结构模式的另一个主要挑战是实现跨多个服务的更改。例如,假设您正在实现一个需要更改服务A、B和C的故事,A取决于B,B取决于C, 在单一的应用程序可以简单地改变相应的模块,集成的变化,和将它们部署在一个相比之下,微服务架构模式中你需要仔细计划和协调更改每个服务的依赖。例如,您需要更新服务C,然后是服务B,最后是服务A。幸运的是,大多数更改通常只影响一个服务;需要协调的多服务更改相对较少。

部署一个基于微服务的应用程序也要复杂得多,单体应用程序简单地部署在传统负载平衡器后面的一组相同的服务器上。每个应用程序实例都与数据库和消息代理等基础设施服务的位置(主机和端口)进行配置。相比之下,微服务应用程序通常由大量服务组成。例如,据阿德里安•科克罗夫特(Adrian Cockcroft)说,Hailo有160种不同的服务,netflix有600多种。

每一个服务将由多个运行实例。还有更多的移动部件需要配置、部署、扩展和监控。此外,您还需要实现一种服务发现机制,使服务能够发现它需要与之通信的任何其他服务的位置(主机和端口)。传统的基于故障单和手动操作方法无法扩展到这种复杂性水平。因此,成功地部署微服务应用程序需要开发人员对部署方法进行更大的控制和高度的自动化。

实现自动化的一种方法是使用现成的平台即服务(PaaS),比如Cloud Foundry。PaaS为开发人员提供了一种简单的方式来部署和管理他们的微服务。
它将他们与诸如采购和配置It资源之类的问题隔离开来。同时,配置PaaS的系统和网络专业人员可以确保遵循最佳实践和公司政策。

另一种自动化微服务部署的方法是开发实质上是您自己的PaaS。一个典型的起点是使用集群解决方案(如Kubernetes),并结合容器技术(如Docker)。在这本电子书的后面,我们将看到基于软件的应用程序交付方法,如NGINX,它可以轻松地处理缓存、访问控制、API计量和微服务级别的监控,如何帮助解决这个问题。

总结

构建复杂的应用程序本质上是困难的。单片架构模式只适用于简单的轻量级应用程序。如果您将它用于复杂的应用程序,您将最终陷入痛苦的世界。微服务体系结构模式是复杂的、不断发展的应用程序的更好选择,尽管存在缺陷和实现挑战.

在后面的章节,我将深入探讨微服务体系结构模式的各个方面的细节,并讨论服务发现、服务部署选项以及将单个应用程序重构为服务的策略等主题。

微服务实践:NGINX Plus 作为一个反向代理服务器

NGINX支持超过50%的排名前一万的网站,这主要是因为它的作为反向代理服务器的功能。你可以“把NGINX放在”当前应用程序甚至数据库服务器的前面来获得各种功能.更高的性能、更高的安全性、可扩展性、灵活性等。所有这些都只需要对现有的应用程序和配置代码进行少量或不进行任何更改。对于遭受性能压力的网站——或预计未来会有高负荷的网站——这种效果看起来简直是奇迹。

那么,这与微服务有什么关系呢?实现一个反向代理服务器,并使用NGINX的其他功能,给你提供了架构上的灵活性。反向代理服务器、静态和应用程序文件缓存、SSL/TLS和HTTP/2终止都可以减轻应用程序的负载,让它去做“只有它”——应用程序——“能做的事情”。

NGINX Plus 的高级特性,包括复杂的负载均衡算法、会话持久化的多种方法、管理和监控,在微服务中特别有用。(NGINX最近增加了对使用DNS SRV记录发现服务的支持,这是一个前沿特性。)而且,正如本章所提到的,NGINX可以帮助实现微服务的自动化部署。

此外,NGINX还提供了必要的功能来支持 NGINX 微服务参考体系结构中的三个模型。代理模型(Proxy Model)使用NGINX作为API网关;Router Mesh模型使用一个额外的NGINX服务器作为进程间通信的中心;Fabric模型每个微服务使用一个NGINX服务器,控制HTTP流量,并可选地在微服务之间实现SSL/TLS,这是一个突破能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值