「第二部:容器和微服务架构](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应用程序传递一个体育游戏的分数变化时。
相关文章
|
5月前
|
Cloud Native Serverless 流计算
云原生时代的应用架构演进:从微服务到 Serverless 的阿里云实践
云原生技术正重塑企业数字化转型路径。阿里云作为亚太领先云服务商,提供完整云原生产品矩阵:容器服务ACK优化启动速度与镜像分发效率;MSE微服务引擎保障高可用性;ASM服务网格降低资源消耗;函数计算FC突破冷启动瓶颈;SAE重新定义PaaS边界;PolarDB数据库实现存储计算分离;DataWorks简化数据湖构建;Flink实时计算助力风控系统。这些技术已在多行业落地,推动效率提升与商业模式创新,助力企业在数字化浪潮中占据先机。
319 12
|
7月前
|
监控 Kubernetes Cloud Native
基于阿里云容器服务Kubernetes版(ACK)的微服务架构设计与实践
本文介绍了如何基于阿里云容器服务Kubernetes版(ACK)设计和实现微服务架构。首先概述了微服务架构的优势与挑战,如模块化、可扩展性及技术多样性。接着详细描述了ACK的核心功能,包括集群管理、应用管理、网络与安全、监控与日志等。在设计基于ACK的微服务架构时,需考虑服务拆分、通信、发现与负载均衡、配置管理、监控与日志以及CI/CD等方面。通过一个电商应用案例,展示了用户服务、商品服务、订单服务和支付服务的具体部署步骤。最后总结了ACK为微服务架构提供的强大支持,帮助应对各种挑战,构建高效可靠的云原生应用。
|
7月前
|
监控 Cloud Native Java
基于阿里云容器服务(ACK)的微服务架构设计与实践
本文介绍如何利用阿里云容器服务Kubernetes版(ACK)构建高可用、可扩展的微服务架构。通过电商平台案例,展示基于Java(Spring Boot)、Docker、Nacos等技术的开发、容器化、部署流程,涵盖服务注册、API网关、监控日志及性能优化实践,帮助企业实现云原生转型。
|
8月前
|
人工智能 安全 Java
微服务引擎 MSE:打造通用的企业级微服务架构
微服务引擎MSE致力于打造通用的企业级微服务架构,涵盖四大核心内容:微服务技术趋势与挑战、MSE应对方案、拥抱开源及最佳实践。MSE通过流量入口、内部流量管理、服务治理等模块,提供高可用、跨语言支持和性能优化。此外,MSE坚持开放,推动云原生与AI融合,助力企业实现无缝迁移和高效运维。
291 1
|
9月前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
472 24
|
7月前
|
传感器 监控 安全
智慧工地云平台的技术架构解析:微服务+Spring Cloud如何支撑海量数据?
慧工地解决方案依托AI、物联网和BIM技术,实现对施工现场的全方位、立体化管理。通过规范施工、减少安全隐患、节省人力、降低运营成本,提升工地管理的安全性、效率和精益度。该方案适用于大型建筑、基础设施、房地产开发等场景,具备微服务架构、大数据与AI分析、物联网设备联网、多端协同等创新点,推动建筑行业向数字化、智能化转型。未来将融合5G、区块链等技术,助力智慧城市建设。
316 0
|
9月前
|
Kubernetes 安全 数据安全/隐私保护
云卓越架构:容器安全最佳实践
本次分享由阿里云智能集团解决方案架构师张玉峰主讲,主题为“云卓越架构:容器安全最佳实践”。内容涵盖容器安全的挑战、云原生容器安全架构及典型场景。首先分析了容器安全面临的问题,如镜像漏洞和权限管理。接着介绍了容器安全架构的五个维度:身份权限管理、配置安全检查、运行时防护、镜像安全检测及发布的安全管控。最后通过具体场景展示了容器身份与权限管理、密钥管理、运行时防入侵等最佳实践,强调了安全左移的重要性,确保从开发到运行的全生命周期安全覆盖。
|
9月前
|
关系型数据库 MySQL Docker
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
《docker高级篇(大厂进阶):5.Docker-compose容器编排》包括是什么能干嘛去哪下、Compose核心概念、Compose使用三个步骤、Compose常用命令、Compose编排微服务
507 6
|
9月前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。
|
10月前
|
Cloud Native Devops 云计算
云计算的未来:云原生架构与微服务的革命####
【10月更文挑战第21天】 随着企业数字化转型的加速,云原生技术正迅速成为IT行业的新宠。本文深入探讨了云原生架构的核心理念、关键技术如容器化和微服务的优势,以及如何通过这些技术实现高效、灵活且可扩展的现代应用开发。我们将揭示云原生如何重塑软件开发流程,提升业务敏捷性,并探索其对企业IT架构的深远影响。 ####
233 3

热门文章

最新文章