「第二部:容器和微服务架构](11) 微服务架构中的通信

简介: 「第二部:容器和微服务架构](11) 微服务架构中的通信

在单个进程上运行的单片应用程序中,组件使用语言级方法或函数调用彼此调用。如果使用代码创建对象(例如,new ClassName()),则可以强耦合这些对象;如果使用依赖注入,则可以通过引用抽象而不是具体的对象实例,以分离的方式调用这些对象。不管怎样,对象都在同一进程中运行。当从单一应用程序转变为基于微服务的应用程序时,最大的挑战在于改变通信机制。从进程内方法调用到服务的RPC调用的直接转换将导致在分布式环境中性能不佳的聊天和不高效的通信。正确设计分布式系统的挑战是众所周知的,甚至还有一个被称为分布式计算谬误的经典,它列出了开发人员在从单一设计转向分布式设计时经常做出的假设。


没有一个解决方案,只有几个。一种解决方案是尽可能地隔离业务微服务。然后在内部微服务之间使用异步通信,并用粗粒度通信替换对象之间的进程内通信中的典型细粒度通信。您可以通过对调用进行分组并将聚合多个内部调用结果的数据返回给客户端来完成此操作。


基于微服务的应用程序是在多个进程或服务上运行的分布式系统,通常甚至跨多个服务器或主机运行。每个服务实例通常是一个流程。因此,服务必须使用进程间通信协议(如HTTP、AMQP)或二进制协议(如TCP)进行交互,具体取决于每个服务的性质。


微服务社区提倡“智能端点和哑管道”的理念这一口号鼓励设计尽可能在微服务之间分离,并在单个微服务中尽可能具有凝聚力。如前所述,每个微服务都拥有自己的数据和域逻辑。但是,组成端到端应用程序的微服务通常只是通过使用REST通信而不是复杂的协议(如WS-*和灵活的事件驱动通信)进行编排,而不是使用集中的业务流程编排器。


这两种常用的协议是HTTP请求/响应和资源api(在大多数情况下查询时),以及在跨多个微服务通信更新时的轻量级异步消息传递。以下各节将更详细地解释这些问题。


通信类型


客户机和服务可以通过多种不同类型的通信进行通信,每种通信都针对不同的场景和目标。最初,这些类型的通信可以分为两个轴。


第一个轴定义协议是同步的还是异步的:

  • 同步协议。HTTP是一种同步协议。客户端发送请求并等待服务的响应。这与客户端代码执行无关,客户端代码执行可以是同步的(线程被阻塞)或异步的(线程不被阻塞,响应最终将到达回调)。这里重要的一点是,协议(HTTP/HTTPS)是同步的,客户端代码只有在接收到HTTP服务器响应时才能继续其任务。
  • 异步协议。其他协议如AMQP(许多操作系统和云环境支持的协议)使用异步消息。客户端代码或消息发送者通常不会等待响应。它只是在向RabbitMQ队列或任何其他消息代理发送消息时发送消息。

第二轴定义通信是否有一个或多个接收器:

  • 单接收器。每个请求必须由一个接收者或服务处理。这种通信的一个例子是命令模式。
  • 多个接收器。每个请求都可以由零到多个接收器处理。这种类型的通信必须是异步的。例如,在事件驱动架构等模式中使用的发布/订阅机制。当通过事件在多个微服务之间传播数据更新时,这基于事件总线接口或消息代理;通常通过服务总线或类似的工件(如Azure服务总线)通过使用主题和订阅来实现。

基于微服务的应用程序通常会使用这些通信样式的组合。最常见的类型是在调用常规Web API HTTP服务时使用HTTP/HTTPS之类的同步协议进行单接收器通信。微服务通常也使用消息传递协议在微服务之间进行异步通信。

这些轴是很好知道,所以你有可能的沟通机制,但他们不是重要的关注时,建设微服务。在集成微服务时,客户端线程执行的异步性和所选协议的异步性都不是重点。重要的是能够异步集成您的微服务,同时保持微服务的独立性,如下一节所述。


异步微服务集成增强了微服务的自主性


如前所述,构建基于微服务的应用程序时,重要的一点是集成微服务的方式。理想情况下,您应该尽量减少内部微服务之间的通信。微服务之间的通信越少越好。但在很多情况下,您必须以某种方式集成微服务。当您需要这样做时,这里的关键规则是微服务之间的通信应该是异步的。这并不意味着您必须使用特定的协议(例如,异步消息传递与同步HTTP)。这只是意味着微服务之间的通信应该只通过异步传播数据来完成,但不要依赖于其他内部微服务作为初始服务HTTP请求/响应操作的一部分。


如果可能,永远不要依赖多个微服务之间的同步通信(请求/响应),即使是查询。每个微服务的目标都是自治的,并可供客户机消费者使用,即使作为端到端应用程序一部分的其他服务已关闭或不正常。如果您认为需要从一个微服务调用其他微服务(如执行数据查询的HTTP请求)才能向客户端应用程序提供响应,那么您的体系结构在某些微服务失败时将无法恢复。

此外,如图4-15的第一部分所示,在微服务之间具有HTTP依赖关系(如使用HTTP请求链创建长请求/响应周期时),不仅使微服务不具有自治性,而且一旦该链中的某个服务性能不好,它们的性能就会受到影响。

在微服务(如查询请求)之间添加的同步依赖项越多,客户端应用程序的总体响应时间就越差。


图15 微服务间通信中的反模式和模式


如上图所示,在同步通信中,在为客户机请求提供服务的同时,在微服务之间创建请求的“链”。这是一种反模式。在异步通信中,微服务使用异步消息或http轮询来与其他微服务通信,但客户机请求会立即得到服务。


如果您的微服务需要在另一个微服务中引发附加操作,请尽可能不要同步执行该操作,并将其作为原始微服务请求和回复操作的一部分。相反,要异步进行(使用异步消息传递或集成事件、队列等)。但是,尽可能不要作为原始同步请求和应答操作的一部分同步调用操作。


最后(这是构建微服务时出现的大多数问题),如果初始微服务需要最初由其他微服务拥有的数据,不要依赖于对该数据进行同步请求。相反,通过使用最终一致性(通常是通过使用集成事件,如后面几节所述)将数据(仅需要属性)复制或传播到初始服务的数据库中。


正如前面在识别每个微服务部分的域模型边界中所指出的,在多个微服务之间复制某些数据并不是一个错误的设计相反,这样做时,您可以将数据转换为该附加域或有界上下文的特定语言或术语。例如,在eShopOnContainers应用程序中,有一个名为identity api的微服务,它负责用户的大部分数据,实体名为user。但是,当需要在Ordering microservice中存储有关用户的数据时,可以将其存储为名为Buyer的不同实体。买方实体与原始用户实体共享相同的标识,但它可能只有订购域所需的少数属性,而不是整个用户配置文件。

您可以使用任何协议在微服务之间异步通信和传播数据,以便最终保持一致性。如前所述,可以使用事件总线或消息代理来使用集成事件,甚至可以通过轮询其他服务来使用HTTP。没关系。重要的规则是不要在微服务之间创建同步依赖关系。


以下各节介绍了在基于微服务的应用程序中可以考虑使用的多种通信样式。

通信风格


根据要使用的通信类型,可以使用许多协议和选项进行通信。如果使用的是基于同步请求/响应的通信机制,那么HTTP和REST方法等协议是最常见的,尤其是在Docker主机或微服务集群之外发布服务时。如果您在服务之间进行内部通信(在Docker主机或微服务集群内),您可能还需要使用二进制格式的通信机制(如使用TCP和二进制格式的WCF)。或者,可以使用异步的、基于消息的通信机制,如AMQP。


还有多种消息格式,如JSON或XML,甚至是二进制格式,这样可以更高效。如果您选择的二进制格式不是标准格式,那么使用该格式公开发布您的服务可能不是一个好主意。您可以使用非标准格式在微服务之间进行内部通信。在Docker主机或微服务群集(例如Docker orchestrators)内的微服务之间通信时,或者在与微服务对话的专用客户端应用程序之间通信时,可以这样做。


基于HTTP和REST的请求/响应通信


当客户机使用请求/响应通信时,它向服务发送一个请求,然后服务处理该请求并发回一个响应。请求/响应通信特别适合于从客户端应用程序查询实时UI(实时用户界面)的数据。因此,在微服务架构中,您可能会对大多数查询使用这种通信机制,如图4-16所示。


图16 使用HTTP请求/响应通信(同步或异步)


当客户机使用请求/响应通信时,它假设响应将在短时间内到达,通常不到一秒,或最多几秒。对于延迟响应,您需要实现基于消息模式和消息技术的异步通信,这是我们在下一节中解释的另一种方法。


请求/响应通信的流行体系结构样式是REST。这种方法基于HTTP协议,并与之紧密耦合,包括GET、POST和PUT等HTTP动词。REST是创建服务时最常用的架构通信方法。在开发ASP.NET核心Web API服务时,可以实现REST服务。


当使用HTTP REST服务作为接口定义语言时,还有额外的价值。例如,如果使用夸张的元数据来描述服务API,则可以使用生成客户端存根的工具来直接发现和使用服务。


额外资源


  • Martin Fowler. Richardson Maturity Model A description of the REST model.
    https://martinfowler.com/articles/richardsonMaturityModel.html
  • Swagger The official site.
    https://swagger.io/
  • 基于HTTP的推送与实时通信
  • 另一种可能性(通常用于与REST不同的目的)是与更高级别的框架(如ASP.NET signaler)和协议(如WebSockets)进行实时的一对多通信。
  • 如图4-17所示,实时HTTP通信意味着您可以让服务器代码在数据可用时将内容推送到连接的客户端,而不是让服务器等待客户端请求新数据。

  • 图17 一对一实时异步消息通信
  • signaler是实现从后端服务器将内容推送到客户端的实时通信的好方法。由于通信是实时的,客户端应用程序几乎可以立即显示变化。这通常由WebSockets等协议处理,使用许多WebSockets连接(每个客户端一个)。一个典型的例子是,当一个服务同时向许多客户端web应用程序传递一个体育游戏的分数变化时。
相关文章
|
11天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
13天前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
12天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
29 1
服务架构的演进:从单体到微服务的探索之旅
|
10天前
|
消息中间件 监控 安全
后端架构演进:从单体到微服务####
在数字化转型的浪潮中,企业应用的后端架构经历了从传统单体架构到现代微服务架构的深刻变革。本文探讨了这一演进过程的背景、驱动力、关键技术及面临的挑战,揭示了如何通过微服务化实现系统的高可用性、扩展性和敏捷开发,同时指出了转型过程中需克服的服务拆分、数据管理、通信机制等难题,为读者提供了一个全面理解后端架构演变路径的视角。 ####
27 8
|
11天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
37 5
|
12天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
31 5
|
12天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
12天前
|
Cloud Native API 持续交付
云原生之旅:从容器到微服务的演进之路
【10月更文挑战第39天】在这篇文章中,我们将一起探索云原生技术的奥秘。通过浅显易懂的语言和生动的比喻,我们将了解云原生技术如何改变软件开发的世界。文章将带领读者从容器的基本概念出发,逐步深入到微服务架构的实践,揭示这些技术如何助力现代应用的快速迭代与可靠部署。准备好,让我们启程进入云原生的精彩世界吧!
|
16天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
64 6
|
16天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
30 1
下一篇
无影云桌面