读构建可扩展分布式系统:方法与实践06异步消息传递

news2024/12/23 16:32:23

1. 异步消息传递

1.1. 通信是分布式系统的基础,也是架构师需要纳入其系统设计的主要问题

1.2. 客户端发送请求并等待服务器响应

  • 1.2.1. 这就是大多数分布式通信的设计方式,因为客户端需要得到即时响应后才能继续

  • 1.2.2. 并非所有系统都有这个要求

1.3. 使用异步通信的方式,客户端(称为生产者)将其请求发送到中间消息传递服务

1.4. 生产者对他们发送的请求“发后即忘”(fire and forget)

  • 1.4.1. 一旦请求被传递到消息传递服务,生产者就会进入其逻辑中的下一步,并确信它发送的请求最终得到处理

  • 1.4.2. 消息机制提高了系统的响应能力,因为生产者不必等到请求处理完成

1.5. 异步消息传递是可扩展系统架构的一个组成部分

1.6. 消息传递机制在经历请求高峰和低谷的系统中特别有吸引力

  • 1.6.1. 在高峰时段,生产者可以将请求添加到队列中并快速响应客户端,而无须等待请求被处理

1.7. 消息队列可以分布在多个代理之间以扩展消息吞吐量,也可以复制队列来提高可用性

1.8. 消息机制并非不存在风险

  • 1.8.1. 将消息副本放在队列中,如果队列保留在内存中,则消息可能会丢失

1.9. 将消息副本放在队列中,如果队列保留在内存中,则消息可能会丢失

2. 消息传递简介

2.1. 异步消息传递平台是一个成熟的技术领域

  • 2.1.1. 久负盛名的IBM MQ系列出现于1993年,至今仍是企业系统的中流砥柱

  • 2.1.2. Java消息传递服务(JMS)是一种API级别的规范,由多个JEE供应商实现和支持

  • 2.1.3. RabbitMQ,可以说是部署最广泛的开源消息传递系统

2.2. 消息传递原语

  • 2.2.1. 消息队列

    • 2.2.1.1. 存储一系列消息的队列
  • 2.2.2. 生产者

    • 2.2.2.1. 将消息发送到队列

    • 2.2.2.2. 生产者将消息发送到代理上的命名队列

  • 2.2.3. 消费者

    • 2.2.3.1. 从队列中取出消息

    • 2.2.3.2. 多个消费者可以从同一个队列中获取消息

    • 2.2.3.3. 消费者获取消息有两种行为模式,即拉取或推送

      2.2.3.3.1. 在拉取(也称为轮询)模式中,消费者向代理发送请求,代理用下一条可供处理的消息进行响应

      2.2.3.3.2. 在推送模式下,消费者告知代理自己希望从队列中接收消息

      2.2.3.3.2.1. 消费者提供了一个回调函数,当消息可用时应调用该函数

      2.2.3.3.2.2. 然后消费者就会阻塞(或执行其他工作)​,消息代理会在有消息可用时将消息传递给回调函数进行处理

      2.2.3.3.2.3. 使用推送模式更加高效

2.2.3.3.2.3.1. 避免了代理可能被来自多个消费者的请求压垮,并使代理能更高效地实现消息传递

2.2.3.3.2.3.2. 消费者确认后,代理就可以将消息标记为已传递,并将其从队列中删除

2.2.3.3.2.3.3. 如果使用自动确认,消息传递给消费者之后,在消息处理之前代理就会收到确认

  • 2.2.4. 消息代理

    • 2.2.4.1. 消息代理是一个服务,管理着一个或多个队列

    • 2.2.4.2. 消息代理可以在同一硬件上管理多个队列

2.3. 通常会有消费者希望确保消息在确认之前得到完全处理

  • 2.3.1. 它将使用手动确认的方式

  • 2.3.2. 可以防止出现消息已经被传递给消费者,但由于消费者崩溃而导致消息未被处理的问题

  • 2.3.3. 确实会增加消息确认的延迟

2.4. 无论选择何种确认模式,未确认的消息都有效地保留在队列中,并将在稍后的某个时间传递给另一个消费者处理

2.5. 消息持久化

  • 2.5.1. 默认情况下,消息队列通常保存在内存中,以便为生产者和消费者提供尽可能快的服务

  • 2.5.2. 只要内存充足,在内存中管理队列的开销就是最小的

    • 2.5.2.1. 如果服务器崩溃,那么它确实有丢失消息的风险
  • 2.5.3. 为了防止消息丢失,队列可以设置成可持久化的

    • 2.5.3.1. 当生产者将消息放入队列时,只有消息写入磁盘后操作才会完成

    • 2.5.3.2. 如果消息代理发生故障,在重新启动时它可以将队列内容恢复到失败前的状态,并且不会丢失任何消息

  • 2.5.4. 持久队列会固有地增加发送操作的响应时间,但数据安全性却得到了提高

  • 2.5.5. 代理通常会在内存和磁盘上维护队列内容,这样就能在正常操作时以最小的开销将消息发送给消费者

2.6. 发布-订阅

  • 2.6.1. 在发布-订阅系统中,消息队列被称为主题

  • 2.6.2. 一个主题一般都是一个消息队列,它会将每个发布的消息传递给多个订阅者之一

  • 2.6.3. 发布者与订阅者分离,订阅者的数量可以动态变化

    • 2.6.3.1. 须对现有系统进行任何更改即可添加新的订阅者,架构具有高度的可扩展性
  • 2.6.4. 发布-订阅模式给消息代理带来了额外的性能负担

    • 2.6.4.1. 利用推送的消息消费模型为发布-订阅架构提供了最有效的解决方案
  • 2.6.5. 发布-订阅消息传递机制是构建分布式事件驱动架构的关键组件

    • 2.6.5.1. 在事件驱动的架构中,多个服务可以使用消息代理主题发布与某些状态变更相关的事件

    • 2.6.5.2. 服务可以通过订阅主题来注册感兴趣的各种事件类型

    • 2.6.5.3. 该主题发布的每个事件都会发送给所有感兴趣的消费者服务

2.7. 消息复制

  • 2.7.1. 在异步系统中,消息代理可能会是一个潜在的故障点

  • 2.7.2. 系统或网络故障可能导致代理不可用,从而使系统无法正常运行

  • 2.7.3. 大多数消息代理都允许在多个代理之间以物理方式复制逻辑队列和主题,每个代理都在自己的节点上运行

  • 2.7.4. 消息队列复制的最常见方法是领导者-追随者(leader-follower)架构

    • 2.7.4.1. 一个代理被指定为领导者,生产者和消费者分别通过该领导者发送和接收消息

    • 2.7.4.2. 追随者被称为热备用,是领导者的副本,如果领导者发生故障,则追随者顶上

  • 2.7.5. 在故障场景下,生产者和消费者可以通过切换访问追随者来继续操作,称之为故障转移

    • 2.7.5.1. 故障转移在消息代理的客户端库中实现,因此对生产者和消费者来说是透明的
  • 2.7.6. 实现一个可以执行队列复制的代理是一件复杂的事情

    • 2.7.6.1. 不要考虑使用自己的复制方案或任何其他复杂的分布式算法

    • 2.7.6.2. 你的解决方案将不如现有解决方案有效,开发成本将超出你的预期

3. RabbitMQ

3.1. 是分布式系统中使用最广泛的消息代理之一

3.2. RabbitMQ代理采用Erlang语言构建,主要为AMQP(Advanced Message Queuing Protocol,高级消息队列协议)开放标准提供支持

  • 3.2.1. AMQP诞生于金融行业,致力于定义合作协议

    • 3.2.1.1. 它是一种二进制协议,为执行该协议的不同产品提供互操作性
  • 3.2.2. RabbitMQ支持开箱即用,支持AMQP v0-9-1,并通过插件支持v1.0

3.3. 消息、交换机和队列

  • 3.3.1. 代理基于一个被称为交换机(exchange)的概念实现了一个消息传递模型,它为创建消息传递拓扑提供了一种灵活的机制

  • 3.3.2. 交换是对接收生产者消息并传递给代理队列的过程的一种抽象

  • 3.3.3. 直连交换机通常用于根据匹配路由键将每条消息传递到一个目标队列

3.4. 分发和并发

  • 3.4.1. 通道不是线程安全的,这意味着每个线程都需要对通道进行独占访问

  • 3.4.2. 线程的生命周期和调用由服务器平台控制,而不是由你的代码控制

  • 3.4.3. 轮询效率很低,因为它涉及繁忙的等待,即使没有消息可用,也要求消费者不断询问消息

    • 3.4.3.1. 高性能系统中不会使用这种方法
  • 3.4.4. 推送模型

3.5. 与大多数消息代理一样,RabbitMQ在消费速率跟生产速率相当时表现最佳

  • 3.5.1. 当队列增长到大约有数万条消息时,管理队列的线程将承受更多的开销

  • 3.5.2. 默认情况下,代理使用运行节点40%的可用内存

3.6. 数据安全与性能权衡

  • 3.6.1. 所有消息传递系统都面临着性能与可靠性权衡的两难境地

  • 3.6.2. 核心问题是消息传递的可靠性,通常称为数据安全

3.7. 可用性与性能权衡

  • 3.7.1. 单个代理发生故障属于单点故障,因此如果代理崩溃或经历短暂的网络故障,就会导致系统不可用

  • 3.7.2. 高可用性的典型解决方案是代理和队列复制

  • 3.7.3. RabbitMQ提供了两种支持高可用性的方法,分别是镜像队列和仲裁队列

    • 3.7.3.1. 需要部署两个或多个RabbitMQ代理并配置成一个集群

    • 3.7.3.2. 每个队列都有一个领导者版本,以及一个或多个追随者

    • 3.7.3.3. 发布者向领导者发送消息,领导者负责将每条消息复制给追随者

    • 3.7.3.4. 消费者也连接到领导者,当领导者收到消息成功处理的应答时,消息也会从追随者中删除

    • 3.7.3.5. 由于所有发布者和消费者的队列行为都由领导者执行,仲裁队列和镜像队列虽然都提升了可用性,但不支持负载均衡

      3.7.3.5.1. 消息吞吐量受到领导者副本的性能限制

    • 3.7.3.6. 关键的区别在于如何复制消息,以及在领导者发生故障的情况下如何选择新的领导者

      3.7.3.6.1. 仲裁本质上意味着超过半数

      3.7.3.6.2. 如果有五个队列副本,那么至少需要三个副本(领导者和两个追随者)来持久保存新发布的消息

      3.7.3.6.3. 仲裁队列实现了RAFT算法以便管理副本,并在领导者不可用时选择新的领导者

      3.7.3.6.4. 仲裁队列必须是持久性的,因此主要适用于数据安全性和可用性优先于性能的用例

      3.7.3.6.4.1. 在故障处理方面,它比镜像队列的实现更有优势

4. 消息传递模式

4.1. 竞争消费者

  • 4.1.1. 消息传递系统的一个常见需求是尽可能快地消费队列中的消息

4.2. 可用性

  • 4.2.1. 如果一个消费者发生故障,系统仍然可用,这个消费者的消息份额只是简单地分发给其他竞争消费者

4.3. 故障处理

  • 4.3.1. 如果一个消费者发生故障,它未确认的消息将传递给另一个队列消费者

4.4. 动态负载均衡

  • 4.4.1. 新的消费者可以在高负载期间启动并在负载减少时停止,而无须更改任何队列或消费者配置

4.5. 严格遵守一次处理原则

  • 4.5.1. 在异步消息传递系统中,重复处理消息来源于两个问题

    • 4.5.1.1. 第一个是来自发布者的重复发布

      4.5.1.1.1. 一些消息代理提供了对这种重复检测的支持,从而确保重复的消息不会被发布到队列中

      4.5.1.1.2. 利用每条消息在客户端生成的唯一幂等键值

      4.5.1.1.2.1. 发布者只需要将特定的消息属性设置为唯一值

      4.5.1.1.3. 代理利用缓存来存储幂等键值并检测重复项,有效地消除了队列中的重复消息,解决了第一个问题

      4.5.1.1.4. 在消费者端,代理将消息传递给消费者后,消费者对消息进行了处理,但之后无法发送应答(消费者崩溃或网络丢失应答)​,就会发生重复给消费者传递消息的情况

    • 4.5.1.2. 第二个是消费者多次消费

      4.5.1.2.1. 消费者有义务防止重复处理

      4.5.1.2.2. 为已处理的消息维护一个缓存或幂等键值数据库

      4.5.1.2.3. 大多数代理将设置一个消息头,指示消息是否为重新传递

      4.5.1.2.3.1. 消费者可以用它来实现幂等性

      4.5.1.2.3.2. 它不能保证消费者已经处理了该消息

      4.5.1.2.3.3. 它只是告诉你代理已传递过该消息并且消息仍未得到应答

    • 4.5.1.3. 两者都需要解决,以确保每条消息都只处理一次

4.6. 有害消息

  • 4.6.1. 最常见的可能是生产者发送了错误的消息,消费者无法处理

  • 4.6.2. 导致消费者崩溃

    • 4.6.2.1. 在研发和测试系统中最为常见

    • 4.6.2.2. 有时这些问题也会流入生产环境,而消费者发生故障肯定会导致一些严重的运营难题

  • 4.6.3. 导致消费者拒绝消息,因为它无法成功处理消息负载

  • 4.6.4. 有害消息将被传递给另一个消费者,会得到可预测的、不良结果

    • 4.6.4.1. 如果没办法检测到有害消息,则会无限期地传递它们

    • 4.6.4.2. 最好的结果是只占用处理能力,减少系统吞吐量

  • 4.6.5. 有害消息处理的方案是限制重新传递消息的次数

    • 4.6.5.1. 当达到重新传递的限制时,消息会自动转移到一个收集问题请求的队列

      4.6.5.1.1. 这个队列在传统上被称为死信队列

  • 4.6.6. 每个消息传递平台实现有害消息处理的确切机制都有所不同

  • 4.6.7. 有害消息处理的最后一部分是诊断出消息被重定向到死信队列的原因

  • 4.6.8. 最重要的是你需要设置某种形式的监视警报给工程师发送消息处理失败的通知

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2141524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据时代,职场离不开的远程控制工具

中秋了大概率是在正常放假了吧,如果突发遇到需要你处理的文件怎么办呢?其实有远程操作工具你就不用到办公室了。向日葵远程控制软件这些工具就可以帮我们远程实现控制电脑操作。如果你也有这方面需求就继续看吧,这次我将介绍几款我用过效果比…

Redis常见应用场景

目录 一、实现博客点赞功能 二、实现博客点赞用户列表功能 三、好友关注和取关以及求共同关注 四、实现关注推送 1、拉模式 2、推模式 3、推拉结合 四、三种模式对比 这里简单记录一下,没有实现方法,只是帮助记忆 一、实现博客点赞功能 可以通…

[NSSRound#4 SWPU]hide_and_seek-用gdb调试

看反汇编 ; __unwind { .text:0000000000001514 F3 0F 1E FA endbr64 .text:0000000000001518 55 push rbp .text:0000000000001519 48 89 E5 mov rbp, rsp .text:000000000000151C 53 …

python tkinter

基本使用 基于tkinter创建 GUI基本四步:窗口->组件->布局->事件 1.创建窗口对象 from tkinter import *root Tk() # 创建窗口root.mainloop() # 进入事件循环 2.创建组件 按钮文本等组件 btn Button(root) # 创建Button组件,使组件在…

re题(25)BUUFCTF-[GUET-CTF2019]re

BUUCTF在线评测 (buuoj.cn) 查下壳,是upx壳 脱一下 查看字符串,定位到主函数,也可以用ctrlE的方式找到主函数 明显,sub_4009AE是对flag加密的关键函数 进入sub_4009AE看一下 看到这儿有一堆大数和方程,我们知道要用z…

Transformer模型详细步骤

Transformer模型是nlp任务中不能绕开的学习任务,我将从数据开始,每一步骤都列举出来,然后对应重点的代码进行讲解 ------------------------------------------------------------------------------------------------------------- Trans…

Skytower

一、安装配置靶机 下载地址: SkyTower: 1 ~ VulnHub 下载之后解压发现是VirtualBox格式的 我们下载一个VirtualBox,这是官网 Downloads – Oracle VirtualBox 安装到默认路径就 打开后点击注册 选择解压后的vbox文件 然后点击左上角管理 点击导出虚拟电脑&…

PCIe进阶之TL:Request Handling Rules

1 Handling of Received TLPs 本节介绍接收到的 TLP 在数据链路层经过完整性验证之后,这些 TLP 在事务处理层时的处理方式。这些规则如下图所示: 接收侧会忽略保留字段。如果 Fmt 字段显示存在至少一个 TLP Prefix : (1)通过检查后续 DWORD 的第一个字节中的 Fmt 字段,…

两个人群填充参考(CHN100K和NARD)

分别是中国人群和东北亚人群的填充参考,测试了下,中国人群的参考注册还是相对友好的,没有像有些网站一样严格限制。东北亚的没有测试,两个数据库的特点都是包含了少数民族,研究朝鲜或蒙古族或其他民族的同学&#xff0…

Java 枚举 新特性

Java 枚举(enum)自JDK 1.5引入以来,随着版本的升级不断增强。本文将回顾枚举的演进,尤其是结合switch语句的应用,展示枚举如何在现代Java中变得更加灵活。 1. JDK 1.5:Java 枚举的诞生 在JDK 1.5之前&…

Dbt基本概念与快速入门

在过去的几年里,数据科学界已经慢慢地接受了以数据为中心的范式。我们不仅关注日益复杂的机器学习模型,还要更多地关注数据质量。这使得数据工程、分析工程领域技术和工具成为热点。dbt(数据构建工具)是一个显著改善数据工程师生活的工具。它的目的是向数…

【漏洞复现】金某云星空ERP GetImportOutData .net反序列化漏洞

免责声明: 本文内容旨在提供有关特定漏洞或安全漏洞的信息,以帮助用户更好地了解可能存在的风险。公布此类信息的目的在于促进网络安全意识和技术进步,并非出于任何恶意目的。阅读者应该明白,在利用本文提到的漏洞信息或进行相关测…

Chinese Spelling Correction as Rephrasing Language Model(AAAI2024)

Chinese Spelling Correction as Rephrasing Language Model(AAAI2024) 一.概述 目前最先进的方法将CSC(Chinese Spelling Correction)作为序列标注任务,并在句子对上微调基于bert的方法。然而,我们注意到在将一个字符标注为另一个字符的过…

springboot+mybatis+mysql仿百度网盘系统2.0

springbootmybatismysql仿百度网盘系统2.0 一、系统介绍二、功能展示1.用户登陆2.主页3.全部文件4.文件上传5.文件分享6.文件分类 三、其它1.其他系统实现 一、系统介绍 系统主要功能: 普通用户:用户登陆、主页、全部文件、上传文件、文件分类、文件分部…

初始爬虫6

数据提取 数据提取总结 响应分类 结构化 json数据(高频出现) json模块 jsonpath模块 xml数据(低频出现) re模块 …

AJAX 入门 day3

目录 1.XMLHttpRequest 1.1 XMLHttpRequest认识 1.2 用ajax发送请求 1.3 案例 1.4 XMLHttpRequest - 查询参数 1.5 XMLHttpRequest - 数据提交 2.Promise 2.1 Promise认识 2.2 Promise - 三种状态 2.3 案例 3.封装简易版 axios 3.1 封装_简易axios_获取省份列表 3…

TS - tsconfig.json 和 tsconfig.node.json 的关系,如何在TS 中使用 JS 不报错

目录 1,前言2,二者关系2.1,使用 3,遇到的问题3.1,TS 中使用 JS 1,前言 通过 Vite 创建的 Vue3 TS 项目,根目录下会有 tsconfig.json 和 tsconfig.node.json 文件,并且存在引用关系…

【云原生监控】Prometheus之PushGateway

Prometheus之PushGateway 文章目录 Prometheus之PushGateway介绍作用资源列表基础环境一、部署PushGateway1.1、下载软件包1.2、解压软件包1.3、编辑配置systemctl启动文件1.4、创建日志目录1.5、加载并启动1.6、监控端口1.7、访问PushGateway 二、 配置Prometheus抓取PushGate…

超声波测距

基本原理:超声波测距是通过发射超声波到物体表面再反射回来,通过测量声波传播的时间来计算距离的方法。 公式解释: ( L C \times T ) ( L ):距离(从发射头到接收头的总距离)( C ):声波的传播速…

汉王手写签批控件如何在谷歌、火狐、Edge等浏览器使用

背景 近日,有网友咨询汉王手写签批控件是否可以通过allWebPlugin中间件技术加载到谷歌、火狐、Edge等浏览器?为此,笔者详细了解了一下汉王手写签批控件,它是一个标准的ActiveX控件,曾经主要在IE浏览器使用,…