消息队列(一)-- RabbitMQ入门(4)

RabbitMQ 其他知识点

幂等性

  • 消息重复消费
    消费者在消费MQ 中的消息时,MQ 已经把消息发送给消费者,消费者在给 MQ 返回 ack 时网络中断,故MQ 未收到确认消息,该消息会重新发给其他消费者,或网络重新连接后再次发给该消费者,但是实际上该消息已被消费过了,造成消费者重复消费同一条消息。

  • 解决思路
    MQ 消费者的幂等性的解决一般使用全局ID 或者写个唯一标识,如时间戳、UUID 或 MQ的ID等,每次消费消息时用ID 判断该消息是否已经消费过。
    业界主流的幂等性有两种操作:

    • 唯一ID + 指纹码机制
      指纹码:一些规则或时间戳加别的服务给的唯一信息码,它并不一定是我们系统生成的,基本都是由业务规则拼接而来,但是一定要保证唯一性,然后就利用查询语句进行判断这个 id 是否存在数据库中。优势就是实现简单就一个拼接,然后查询判断是否重复。劣势就是在高并发时,如果是单个数据库就会有写入性能瓶颈,当然也可以采用分库分表提升性能,但是不太推荐。
    • Redis 原子性
      利用 redis 执行 setnx 命令,天然具有幂等性。从而实现不重复消费。

优先级队列

曾经后端系统是使用 redis 来存储定时轮询,而 redis 只能用List 做一个简单的消息队列,并不能实现优先级的场景。所以订单量大了后采用 RabbitMQ 进行改造和优化,如果发现是VIP客户的订单,就给一个相对较高的优先级,否则默认优先级。

  • 控制台页面添加
    在这里插入图片描述
  • 队列声明代码中添加优先级
Map<String , Object> params = new HashMap<>();
params.put("x-max-priority", 10);//官方允许是0-255 之间 ,此处设置10 允许优先级范围为0-10 不要设置过大,浪费CPU与内存
channel.queueDeclare(QUEUE_NAME, true, false, false, params);
for (int i = 0; i < 10; i++) {
    String message = "info"+(i+1);
    if((i+1) == 5){
        AMQP.BasicProperties properties = new AMQP.BasicProperties()
                .builder().priority(5).build();
        channel.basicPublish("", QUEUE_NAME, properties, message.getBytes());
    }else{
        channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
    }
}

先运行生产者发消息,然后再运行消费者,消息info5 因为设置了优先级,优先被消费了。
在这里插入图片描述

  • 实现队列优先级注意如下:
    队列需要设置为优先级队列,消息需要设置消息的优先级,消费者需要等待消息已经发送到队列中才能消费,才有机会对消息进行排序。

惰性队列

RabbitMQ 从3.6.0 版本开始引入了惰性队列的概念。惰性队列会尽可能的将消息存入磁盘中,而在消费者消费到响应的消息时才会被加载到内存中,它的一个重要设计目标是能够支持更长的队列,即支持更多的消息存储。当消费者由于各种各样的原因(比如消费者下线、宕机或者由于维护而关闭等)而致使长时间内不能消费消息造成堆积是,惰性队列就很有必要了。
默认情况下,当消费者将消息发送到 RabbitMQ 的时候,队列中的消息会尽可能的存储在内存中,这样可以更加快速的将消息发送给消费者。即使是持久化的消息,在被写入磁盘的同时也会在内存中驻留一份备份。当 RabbbitMQ 需要释放内存的时候,会将内存中的消息换页至磁盘中,这个操作会消耗较长的时间,也会阻塞队列的操作,进而无法接受新的消息。

  • 两种模式
    队列具备两种模式:default 和 lazy 。默认的为 default。lazy模式为惰性队列的模式,可以通过调用 channel.queueDeclare 方法的时候,在参数中设置。也可以通过 Policy 的方式设置。如果一个队列同时使用两种方式设置的话,那么 Policy 方式具备更高的优先级。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-queue-mode","lazy");
channel.queueDeclare("myqueue",false,false,false,args);

在发送1百万条消息,每条消息大概占1KB的情况下,普通队列占用内存是1.2GB,而惰性队列仅仅占用1.5MB。

RabbitMQ 集群

集群搭建步骤

在这里插入图片描述

  • 把原有装过RabbitMQ 的虚拟机克隆两份,分别修改IP。
    在这里插入图片描述
  • 修改3台机器的主机名称,改完需要重启机器
    vim /etc/hostname
    在这里插入图片描述
  • 配置各个节点的 hosts 文件,让各个节点都能互相识别对方
    vim /etc/hosts
    192.168.1.130 node1
    192.168.1.131 node2
    192.168.1.132 node3
    在这里插入图片描述
  • 以确保各个节点的 cookie 文件使用的是同一个值
    在 node1 上执行远程操作命令
    scp /var/lib/rabbitmq/.erlang.cookie root@node2:/var/lib/rabbitmq/.erlang.cookie
    scp /var/lib/rabbitmq/.erlang.cookie root@node3:/var/lib/rabbitmq/.erlang.cookie
  • 启动 RabbitMQ 服务,顺带启动 Erlang 虚拟机和RabbitMQ 应用服务器
    rabbitmq-server -detached
  • 在节点2 执行
    rabbitmqctl stop_app
    (rabbitmqctl stop 会将 Erlang 虚拟机关闭,rabbitmqctl stop_app 只关闭 RabbitMQ 服务)
    rabbitmqctl reset
    rabbitmqctl join_cluster rabbit@node1
    (需要节点1服务器防火墙放开4369和25672端口)
    rabbitmqctl start_app(只启动应用服务)
    在这里插入图片描述
    在这里插入图片描述
  • 在节点3执行
    rabbitmqctl stop_app
    rabbitmqctl reset
    rabbitmqctl join_cluster rabbit@node2
    rabbitmqctl start_app
  • 集群状态
    rabbitmqctl cluster_status
    在这里插入图片描述
  • 需要重新设置用户
    创建账号
    rabbitmqctl add_user admin 123456
    设置用户角色
    rabbitmqctl set_user_tags admin administrator
    设置用户权限
    rabbitmqctl set_permissions -p “/” admin “.*” “.*” “.*”
    然后可以访问管理界面查看(可以任意访问其中一个IP)
    在这里插入图片描述
  • 解除集群节点(node2 和 node3 机器分别执行)
    rabbitmqctl stop_app
    rabbitmqctl reset
    rabbitmqctl start_app
    rabbitmqctl cluster_status
    rabbitmqctl forget_cluster_node rabbit@node2(node1 机器上执行)

镜像队列

引入镜像队列(Mirror Queue)的机制,可以将队列镜像到集群中的其他 Broker 节点之上,如果集群中的一个节点失效了,队列能自动地切换到镜像中的另一个节点上,保证服务的可用性。

  • 启动三台集群节点
  • 随便找一个节点添加policy
    在这里插入图片描述
    在这里插入图片描述
    其中
    Name:mirrior-two 为名称,可随意起名
    Pattern:^mirrior 规则,以mirrior 前缀的交换机和队列进行备份
    ha-mode:exactly 指定模式
    ha-params:2 备两份
    ha-sync-mode:automatic 同步模式为自动
    在这里插入图片描述

创建一个队列,并发送一个消息
在这里插入图片描述
在这里插入图片描述
然后通过命令把节点1停止,发现自动又备份到节点3上。
在这里插入图片描述

在这里插入图片描述
通过连接节点2,依然能消费消息。
在这里插入图片描述

  • 就算整个集群只剩一台机器,依然能消费队列里的消息。

HAProxy 高可用负载均衡

HAProxy 提供高可用性、负载均衡及基于 TCPHTTP 应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。
在这里插入图片描述

Federation Exchange

因为减少网络延迟,两个地方(比如北京和上海)都有MQ服务,但是需要数据同步,就需要Federation 插件解决这个问题。

  • 需要保证每台节点单独运行

  • 在每台机器上开启 Federation 相关插件
    rabbitmq-plugins enable rabbitmq_federation
    rabbitmq-plugins enable rabbitmq_federation_management

  • 原理图
    在这里插入图片描述
    先运行consumer 在 node2 创建 fed_exchange

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("192.168.1.131");
        factory.setUsername("admin");
        factory.setPassword("123456");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare("fed_exchange", BuiltinExchangeType.DIRECT);
        channel.queueDeclare("node2_queue", true, false, false, null);
        channel.queueBind("node2_queue", "fed_exchange", "routeKey");
        //声明 接收消息
        DeliverCallback deliverCallback = (consumerTag, message) -> {
            System.out.println(new String(message.getBody()));
        };
        //取消消息时的回调
        CancelCallback cancelCallback = consumerTag -> {
            System.out.println("消息消费被中断");
        };
        channel.basicConsume(QUEUE_NAME, true, deliverCallback, cancelCallback);
  • 在 downstream(node2)配置 upstream(node1)
    在这里插入图片描述
  • 添加policy
    在这里插入图片描述
  • 查看状态
    在这里插入图片描述

Federation Queue

联邦队列可以在多个 Broker 节点(或者集群)之间为单个队列提供负载的功能。一个联邦队列可以连接一个或多个上游队列(upstream queue),并从这些上游队列中获取消息以满足本地消费者消费消息的需求。

  • 原理图
    在这里插入图片描述
  • 添加 upstream(同上)
  • 添加policy
    在这里插入图片描述

Shovel

跟 Federation 具备的数据转发功能类似,Shovel 够可靠、持续地从一个 Broker 中的队列(作为源端,即 source)拉取数据并转发至另一个 Broker 中的交换器(作为目的端,即 destination)。作为源端的队列和作为目的端的交换器可以同时位于同一个 Broker,也可以位于不同的 Broker上。Shovel 可以翻译为“铲子”,是一种比较形象的比喻,这个“铲子”可以将消息从一方“铲到”另一方。Shovel 行为就像优秀的客户端应用程序能够负责连接源和目的地、负责消息的读写及负责连接失败问题的处理。
在这里插入图片描述

  • 开启插件(需要的机器都开启)
    rabbitmq-plugins enable rabbitmq_shovel
    rabbitmq-plugins enable rabbitmq_shovel_management
    在这里插入图片描述
    在这里插入图片描述
  • 添加 shovel 源和目的地
    在这里插入图片描述
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机科学cs/电子信息ei面试准备——数学基础/线性代数复习

1. 中值定理 中值定理是反映函数与导数之间联系的重要定理&#xff0c;也是微积分学的理论基础&#xff0c;在许多方面它都有重要的作用&#xff0c;在进行一些公式推导与定理证明中都有很多应用。中值定理是由众多定理共同构建的&#xff0c;其中拉格朗日中值定理是核心&…

登录和注册页面 - 验证码功能的实现

目录 1. 生成验证码 2. 将本地验证码发布成 URL 3. 后端返回验证码的 URL 给前端 4. 前端将用户输入的验证码传给后端 5. 后端验证验证码 1. 生成验证码 使用hutool 工具生成验证码. 1.1 添加 hutool 验证码依赖 <!-- 验证码 --> <dependency><groupId…

Android Studio Flamingo Logcat使用方式

旧版Android Studio突然打不开了&#xff0c;安装了新的Flamingo。习惯用Log.e看日志&#xff0c;突然发现logcat没有筛选下拉了。o(╥﹏╥)o 还是需要查看官方文档&#xff1a;https://developer.android.google.cn/studio/debug/logcat?hlzh-cn &#xff08;不知道为啥&…

jdk,jre和jvm三者的关系和区别

目录 一、三者的关系 二、JDK的概念 三、JRE的概念 四、JVM的概念 五、三者区别 一、三者的关系 从图中可以清楚地看到&#xff0c;他们之间的关系是JDK包含JRE, JRE又包含JVM。 因此&#xff0c;JDK包含JRE和JVM。 JDK JRE Java 开发工具包 [Java,Javac,Javadoc,Javap…

VS下c++解析pcap文件

一、pcap文件格式 https://www.cnblogs.com/Chary/articles/15716063.html 接口协议&#xff08;四&#xff09;&#xff1a;以太网&#xff08;Ethernet&#xff09;学习&#xff08;一&#xff09;&#xff1a;协议_以太网协议_QNee的博客-CSDN博客 二、代码 pcapParser.h #…

自然语言处理实战项目13-基于GRU模型与NER的关键词抽取模型训练全流程

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下自然语言处理实战项目13-基于GRU模型与NER的关键词抽取模型训练全流程。本文主要介绍关键词抽取样例数据、GRU模型模型构建与训练、命名实体识别(NER)、模型评估与应用&#xff0c;项目的目标是通过训练一个GRU模型…

npm i babel-plugin-import -D之后报错

替换modules/.bin/XX文件 1.vue-cli-service #!/bin/sh basedir$(dirname "$(echo "$0" | sed -e s,\\,/,g)")case uname in*CYGWIN*) basedircygpath -w "$basedir";; esacif [ -x "$basedir/node" ]; then"$basedir/node"…

Audio Clip

Unity支持的音频格式&#xff1a; aiff/wav&#xff1a;适用于较短声音片段 mp3/OGG:适用于较长的音乐片段 多声道强制转为单声道&#xff0c;减小所占内存。 勾选后会对声音有优化 在后台加载声音 Load Type&#xff1a; 第一个&#xff0c;以不压缩的形式存在内存&#…

深度学习(二)

目录 一、神经网络 整体架构: 架构细节: 神经元个数的影响: 神经网络过拟合解决: 卷积网络 整体架构: 卷积层 边缘填充 特征尺寸计算 池化层 特征图变化 递归神经网络 一、神经网络 整体架构: 图中分别为输入层、隐层1、隐层2、输出层 通过输入层输入某数值&#xf…

Java版本企业电子招投标采购系统源码——功能模块功能描述+数字化采购管理 采购招投标

功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外部…

FAQ文档的重点注意事项!别踩坑了

在很多优秀的大企业中&#xff0c;FAQ文档是企业运营管理中不可或缺的重要部分。但是也仅限大企业&#xff0c;很多企业目前还是没有这个意识的。一方面原因是因为缺乏这个客户服务的意识&#xff0c;另一方面也和技术水平不足有关。但是其实现在有不少的第三方搭建平台可以帮助…

【Element-ui】学习与使用

网站快速成型工具Element&#xff0c;一套为开发者、设计师和产品经理准备的基于vue2.0的桌面端组件库 安装 npm i element-ui -S 在项目中安装element-ui&#xff0c;安装了以后查看package.json中的依赖中有没有element-ui的版本&#xff0c;如果有&#xff0c;则说明安装成功…

react 在build读取env 数据

默认会读取.env 文件 npm install dotenv --save npm install dotenv-cli --save-dev例如读取.env.test "build:test": "dotenv -e .env.test react-app-rewired build",.env.test REACT_APP_CURRENTMODE devREACT_APP_Public_Path "https://baid…

如何利用JMeter测试带有Token参数的POST接口

JMeter有一个很强大的功能就是可以用来做接口测试。 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系…

TikTok广告数据不好?收下这份常见问题自查手册!

你是一位跨境卖家吗&#xff1f;你是否在TikTok上投放过广告&#xff1f; 如果你的答案是肯定的&#xff0c;那么你可能遇到过一些困扰。比如&#xff0c;你的广告为什么不起量&#xff1f;为什么突然掉量了&#xff1f;为什么成本上升了&#xff1f;到底是哪里出了问题&#…

基于linux下的高并发服务器开发(第二章)- 2.22 setitimer 定时器函数

#include <sys/time.h> int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value); - 功能&#xff1a;设置定时器&#xff08;闹钟&#xff09;。可以替代alarm函数。精度微妙us&#xff0c;可以实现周期性定时 - 参数&#xff1a; -…

网络安全(黑客)就业分析指导

一、针对网络安全市场分析 市场需求量高&#xff1b;则是发展相对成熟入门比较容易。所需要的技术水平国家政策环境 对于国家与企业的地位愈发重要&#xff0c;没有网络安全就没有国家安全 更有为国效力的正义黑客—红客联盟 可见其重视程度。 需要掌握的知识点偏多 外围打点…

RocketMQ教程-(5)-功能特性-事务消息

事务消息为 Apache RocketMQ 中的高级特性消息&#xff0c;本文为您介绍事务消息的应用场景、功能原理、使用限制、使用方法和使用建议。 事务消息为 Apache RocketMQ 中的高级特性消息&#xff0c;本文为您介绍事务消息的应用场景、功能原理、使用限制、使用方法和使用建议。…

探索NE555:一款经典的集成电路(超详细)

NE555是一款经典的集成电路&#xff0c;它在电子领域被广泛应用于定时器、脉冲发生器、电压控制振荡器等各种应用场景。它的设计简单、易于使用&#xff0c;并且具备稳定可靠的性能&#xff0c;因此深受电子爱好者和工程师的青睐。本篇博客将详细介绍NE555的原理、工作模式和常…

微服务——统一网关Getway

为什么需要网关&#xff1f; 网关的两种实现: 网关Getway——快速入门 步骤一 网关背身也是一个微服务&#xff0c;需要注册到nacos中去 步骤二 成功运行后 可以通过网关进行请求转发到对应服务。 流程如下&#xff1a; 路由断言工厂 网关路由可以配置的东西有如下。 spri…