转:RabbitMQ 消息队列特性知多少

转自: https://www.jianshu.com/p/94d6d5d98c3d

 

序言

现在我们每天都要与信息打交道,主动或被动的在创造或接收消息。你会收到话费通知短信,使用微信 QQ跟远在万里的朋友交流,也可能使用钉钉跟同事讨论工作,使用抖音娱乐等等。信息要准确及时的发送和接收 这背后使用了 消息队列的相关技术。本文以RabbitMQ为例 讲解消息队列涉及的相关技术及使用场景,结合自身开发经验帮助读者更好理解这个隐藏在背后的这项“黑科技”

概括

常见的消息通讯方式有同步和异步两种,消息队列实现了异步通讯方式,即消息先存储到消息队列容器里 ,满足某种条件后 发送给消息的接收方,当然消息队列也可以实现同步通讯。队列(Queue)是一种数据结构 满足了先进先出的规则。这个消息的传输有生产者 交换机 消息队列 消费者4部分组成。

RabbitMQ是一种易扩展,高可用 实现了AMQP协议并被广泛应用的开源消息队列。

 

image

RabbitMQ队列属性简介

AMQP的属性在RabbitMQ体现:

1 持久化 即队列持久化保存到硬盘,如果服务重启 可以再次恢复队列

如在代码里配置两个 Queue

/*** queue 持久化* @return*/
@Bean
public Queue DurableTrueQueue(){return new Queue("durableQueue",true);
}/*** queue 非持久化* @return*/
@Bean
public Queue DurableFalseQueue(){return new Queue("noDurableQueue",false);
}

如注释那样 队列durableQueue 是持久化队列 而 noDurableQueue是非持久化队列

在RabbmitMQ的管理后台可以看到这两个队列信息

 

image

重启RabbitMQ服务器 可以看到noDurableQueue 已经没了

 

image

2 独有性 排他性 即队列只为当前链接服务 链接断开 队列被删除

我对独有性理解就是 队列只服务于一个链接 链接消失 则队列也被删除

代码里配置排他性的 队列

 

@Bean
public Queue exclusiveTrueQueue(){return new Queue("exclusiveTrueQueue",true,true,false);
}

在RabbitMQ后台管理页面可以看到 该队列

 

image

点击队列名称 exclusiveTrueQueue 进入队列详情页面

点击get Messages 里的 get Message 按钮 会报错 说该队列具有排他性 不能获取消息内容

 

image

3 自动删除 即消费者断开 队列被删除

自动删除 是指如果该队列对应的链接全部断开 则删除该队列 读者可参考自行实验

需要说明的是 如果队列的 exclusive 为true或auto delete为true 那durable属性是不起作用的 因为服务器重启 链接都会断掉 队列信息会被删除

4 其他可选队列参数参数属性(如队列长度 过期时间等)

仲裁队列

在集群环境下,仲裁队列可以提供一种高效的 保证数据安全的 数据传输能力,能保证在某一台服务器不可用情况下 主从服务的快速切换 和数据完整性复制 从而达到RabbitMQ的高可用和高性能,仲裁队列遵循Raft分布式协议。仲裁队列是RabbitMQ3.8.*版本以后加入的队列类型 用以替换之前版本的队列镜像

在RabbitMQ集群架构中 ,会有一个主实例和多个从实例,主实例负责跟发送端 接收端的交互,把接收到的数据 往从实例复制一份,即从实例是主实例的拷贝和备份,当主实例节点宕机或不可用时候 从实例中会选出一个新的主实例 进行消息的接收和发送 从而保证队列的可用性。

为保证主从节点数据一致性 ,只有当主节点的数据全部写入从节点时候,主节点才会跟发送方确认消息已接收。数据完整保存或最接近完整数据的从节点才有可能被选举为主节点 ,数据残缺不全或者数据要比其他节点少的从节点是不会被选为主节点的,即从节点的选择要最大可能保证数据的完整性。

仲裁队列创建:

 

@Bean
Queue quorumQueue(){Map<String,Object> map = new HashMap<>();map.put("x-queue-type","quorum");return new Queue("quorumQueue",true,false,false,map);
}

在RabbitMQ管理后台可以看到已经创建成功:

 

image

消息过期时间(Time-To-Live)

RabbitMQ 队列里的消息如果超过了过期时间没有消费者接收就变成了死信。处于消息队列中的死信不能发送给客户端,消息服务器会在过期后将消息删除。

RabbitMQ 的过期时间(以下简称TTL)有两种类型设置:

1 设置单条消息的过期时间

2 以队列为单位设置消息的过期时间(代码,命令行两种方式)

两种设置时间的单位都是毫秒

以队列为单位设置消息的过期时间 需要在声明队列时候 设置消息过期参数

 

@Bean
public Queue ttlQueue(){Map<String,Object> map = new HashMap<>();map.put("x-message-ttl",60000);return new Queue("ttlQueue",true,false,false,map);
}

如果x-message-ttl 设置为0,则该队列的消息需要同步接收 不能在队列里保存 否则会过期

设置成功后 在服务器管理页面可以看到TTL标识

 

image

设置单条消息过期时间

 

image

需要注意的是 MessageProperties 的Expiration类型为String格式

队列过期时间

队列过期时间指超过一定时间 队列没有被消费者消费 也没有被重新声明续租 消息队列节点会自动删除该队列

队列过期可以使用在 不断创建新队列 老的队列在没有一定时间没有使用后会自动删除释放资源,如 聊天场景消息的发送接收 RPC 通过不断创建队列传输消息 当聊天结束后 自动删除队列

如果对持久化队列设置了过期时间 当服务器重启后 过期时间会重新开始计算

设置方式是 在创建声明队列时候 传入参数x-expires

 

@Bean
public Queue ttlForQueue(){Map<String,Object> map = new HashMap<>();map.put("x-expires",60000);return new Queue("ttlForQueue",true,false,false,map);
}

 

image

队列长度限制

队列的最大长度既可以限制队列里处理消息的数量 也可以限制处理消息总的字节大小。

这里的长度限制是指被消费者处理过的消息累积,不包括没有被消费者端接收的在途消息

当消息达到队列长度限制的时候,系统默认会将队列头部(最老的消息)删除或设置为死信。

可以设置消息超限的应对策略 参数为x-overflow 值对应为

1 drop-head(默认方式 删除队列最早消息)

2 reject-publish(拒绝新的消息加入)

@RequestMapping(value = "/limitQueue",method = RequestMethod.GET)
public void sendMessageForLimitQueue(){Map<String,Object> args = new HashMap<>();args.put("x-overflow","drop-head");args.put("x-max-length",5);//声明数量受限的队列Queue queue = new  Queue("limitQueue",true,false,false,args);rabbitAdmin.declareQueue(queue);//绑定到交换机Binding binding = new Binding("limitQueue",Binding.DestinationType.QUEUE,"testExchange","limitQueueRoutkey",null);rabbitAdmin.declareBinding(binding);String content = "hello this is a test message ";Map<String,Object> map = makeMessage();map.put("content",content);System.out.println("开始发送。。"+map.toString());rabbitTemplate.convertAndSend("testExchange","limitQueueRoutkey",map);
}



 

 

 

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

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

相关文章

easyui根据select下拉框内容更新表单内容_Ant Design 4.0 的一些杂事儿 - Select 篇

前几篇&#xff1a;Ant Design 4.0 的一些杂事儿 - Table 篇Ant Design 4.0 的一些杂事儿 - Form 篇聊完了 Table 和 Form 两个重型组件&#xff0c;我们来继续聊聊看起来不那么重的 Select 组件。它在 Ant Design 4.0 中有哪些变化。如果你读过 《Ant Design 4.0 进行时》&…

避免代码冗余,使用接口和泛型重构Java代码

转载自 避免代码冗余&#xff0c;使用接口和泛型重构Java代码在使用动态语言和.NET工作了若干年后&#xff0c;我又回到老本行–Java开发。在Ruby中&#xff0c;清除代码冗余是非常方便的&#xff0c;而在Java中则需要结合接口和泛型实现类似的功能。 原始代码 以下是这个类中的…

一文理类加载相关知识:类加载器、双亲委派、SPI

思维导图 类加载的时机 类加载的流程 类从被加载到内存中开始&#xff0c;直到被从内存中卸载为止&#xff0c;它的整个生命周期包括&#xff1a;验证、准备、解析、初始化、使用和卸载7 个阶段。 其中验证、准备、解析 3 个部分统称为连接&#xff08;Linking&#xff09; …

可以搜python编程答案的软件_python实现百万答题自动百度搜索答案

用python搭建百万答题、自动百度搜索答案。 使用平台 windows7 python3.6 MIX2手机 代码原理 手机屏幕内容同步到pc端 对问题截图 对截图文字分析 用浏览器自动搜索文本 使用教程 1、使用Airdroid 将手机屏幕显示在电脑屏幕上。也可使用360手机助手实现。不涉及任何代码。实现效…

intellij idea设置主题、字体样式和背景色

转自&#xff1a; https://blog.csdn.net/fanrenxiang/article/details/80598895 点击这里查看 <intellij idea使用教程汇总篇> 引言&#xff1a;所谓工欲善其事必先利其器&#xff0c;idea就是这样的利器&#xff0c;刚装好的intellij idea主题样式是白的&#xff0c;…

MySQL优化(四):count()

count()不同写法的区别 COUNT(字段名)&#xff1a;返回SELECT语句检索的行中值不为NULL的行数 COUNT(1)&#xff1a;表示的是直接查询符合条件的数据库表的行数&#xff08;会包含值为NULL的行数&#xff09;。其中1指的是表中的第一个字段&#xff0c;如有表 table(id, colu…

图像sobel梯度详细计算过程_数字图像处理(第十章)

点、线、边缘检测背景知识。书中主要介绍了图像的一阶导数与二阶导数&#xff0c;这个之前的文章中有过介绍这里在复习一遍。对于函数 ,对于点 在x方向的一阶偏导为&#xff1a;,二阶偏导为&#xff1a;之后书中总结了一阶导与二阶导对于图像求取边缘的结论&#xff1a;孤立点检…

idea部署maven+javaweb项目到jboss

小编习惯使用eclipse对jboss跑的项目部署,第一次使用idea进行jboss部署项目,遇到很多问题,做此文章以帮助更多人. 图中涂鸦的是项目名,对应上自己的项目名即可 1.导入项目,这一步不多说 2.配置项目: a>点击file-->Project-Stucture-->Project 3.配置Modules 配置…

Java8-本地缓存

转载自 Java8-本地缓存这里我将会给大家演示用ConcurrentHashMap类和lambda表达式实现一个本地缓存。因为Map有一个新的方法可以在key为Null的时候自动计算一个新的value值。非常完美的实现cache。来看下代码&#xff1a;12345678910111213141516publicstatic void main(String…

Integer和Int的比较,谈谈拆卸和装箱

示例代码 public static void main(String[] args) {Integer a new Integer(10111);int b 10111;boolean equal1 a b;//自动拆箱&#xff0c;xxxValue()boolean equal2 a.equals(b);//自动装箱, valueOf()System.out.println(equal1);System.out.println(equal2); }反编译…

python调用webservice接口实例_python调用webservice接口的实现

使用suds这个第三方模块 from suds.client import Client url http://ip:port/?wsdl cilentClient(url) print cilent 查看webservice接口的具体信息&#xff1a; 调用接口方法&#xff0c;通常 client.service.methodname 实际测试过程中遇到的坑&#xff1a; 1、tns 值为Lo…

idea2021部署maven+javaweb项目到jboss(diy)

【README】 我为什么要写这个文章&#xff0c;看了这位老哥的博文 https://blog.csdn.net/PacosonSWJTU/article/details/118074604 部署成功了&#xff0c;很感谢&#xff0c;所以也想照做一下&#xff1b; 【1】创建web项目module &#xff08;Project02 是一个空项目&…

Java对象内存结构

转载自 Java对象内存结构学C/C出身的我&#xff0c;对Java有一点非常困惑&#xff0c;那就是缺乏计算对象占用内存大小的机制。而在C中就可以通过sizeof运算符来获得基本类型以及类实例的大小。C和C中的这个操作符对于指针运算、内存拷贝和IO操作都非常有用。 Java中并没有一个…

Java版大顶堆的实现

堆的概念 堆是一棵完全二叉树&#xff0c;一般使用数组来存储。通俗来讲堆其实就是利用数组来维护一个完全二叉树。 按照堆的特点可以把堆分为大顶堆和小顶堆 大顶堆&#xff1a;堆的每个结点的值都大于或等于其左右孩子结点的值 小顶堆&#xff1a;堆的每个结点的值都小于或…

Java 8新特性探究(二)深入解析默认方法

转载自 Java 8新特性探究&#xff08;二&#xff09;深入解析默认方法 什么是默认方法&#xff0c;为什么要有默认方法 简单说&#xff0c;就是接口可以有实现方法&#xff0c;而且不需要实现类去实现其方法。只需在方法名前面加个default关键字即可。 为什么要有这个特性&am…

把本地库推送到github远程库

【1】 github上创建远程库 注意 &#xff0c;远程库的名字要与本地库相同 【2】新建github远程库别名origin 【3】 代码提交 git add ./* &#xff1a; 把修改内容添加到暂存区 &#xff1b; git commit -m msg &#xff1a; 提交暂存区的修改内容到本地库&#xff1b; g…

react antd confirm content list_React造轮系列:对话框组件 - Dialog 思路

React造轮系列&#xff1a;对话框组件 - Dialog 思路对话框一般是我们点击按钮弹出的这么一个东西&#xff0c;主要类型有 Alter, Confirm 及 Modal, Modal 一般带有半透明的黑色背景。当然外观可参考 AntD 或者 Framework 等。确定 APIAPI 方面主要还是要参考同行&#xff0c;…

Spring IOC 和 AOP 概览

IOC&#xff08;控制反转&#xff09; IoC&#xff08;Inversion of Control&#xff0c;控制倒转&#xff09;。所谓IoC&#xff0c;对于spring框架来说&#xff0c;就是由spring来负责控制对象的生命周期和对象间的关系。 在没有IOC时&#xff0c;我们通过new 等关键字等方…

Java 并发实践 — ConcurrentHashMap 与 CAS

转载自 Java 并发实践 — ConcurrentHashMap 与 CAS最近在做接口限流时涉及到了一个有意思问题&#xff0c;牵扯出了关于concurrentHashMap的一些用法&#xff0c;以及CAS的一些概念。限流算法很多&#xff0c;我主要就以最简单的计数器法来做引。先抽象化一下需求&#xff1a;…

git rebase命令(转)

转自&#xff1a; https://www.yiibai.com/git/git_rebase.html git rebase命令在另一个分支基础之上重新应用&#xff0c;用于把一个分支的修改合并到当前分支。 使用语法 git rebase [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>][<u…