RabbitMQ介绍
JMS组件:activemq(慢)
AMQP组件(advance message queue protocol):rabbitmq和kafka
一.、消息队列可以解决什么问题?
异步处理
应用解耦
流量削锋
日志处理
二、rabbitmq安装与配置
安装RabbitMQ需要先安装Erlang语言开发包,
官方地址:http://erlang.org/download/
点击 otp_win64_22.2.exe 就可以下载了。
RabbitMQ官方地址:https://www.rabbitmq.com/download.html
点击 Install: Windows 进入下载页面,然后点击rabbitmq-server-3.8.1.exe就直接下载了。安装好之后不要忘了配置环境变量哦!哦弥陀佛!一切就绪后在浏览器输入地址:http://localhost:15672,输入默认账号:guest 密码:guest,就能进入RabbitMQ界面了。哦弥陀佛!
三、消费者端参数详解
// 声明一个队列
// 第一个参数表示队列名称、第二个参数为是否持久化、第三个参数为是否是独占队列、第四个参数为当所有消费者客户端连接断开时是否自动删除队列、第五个参数为队列的其他参数
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments);
queue: 队列名称
durable:是否持久化(true表示是,队列将在服务器重启时生存), 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,如果想重启之后还存在就要使队列持久化,保存到Erlang自带的Mnesia数据库中,当rabbitmq重启之后会读取该数据库
exclusive:是否排外的/是否是独占队列,有两个作用(创建者可以使连接断开后自动删除,可使其变为某一消费者的私有队列)一:当连接关闭时connection.close()该队列是否会自动删除;二:该队列是否是私有的private,如果不是排外的,可以使用两个消费者都访问同一个队列,没有任何问题,如果是排外的,会对当前队列加锁,其他通道channel是不能访问的,如果强制访问会报异常:com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=405, reply-text=RESOURCE_LOCKED - cannot obtain exclusive access to locked queue ‘queue_name’ in vhost ‘/’, class-id=50, method-id=20)一般等于true的话用于一个队列只能有一个消费者来消费的场景*/
autoDelete:是当所有消费者客户端连接断开时是否自动删除队列,当最后一个消费者断开连接之后队列是否自动被删除,可以通过RabbitMQ Management,查看某个队列的消费者数量,当consumers = 0时队列就会自动删除
arguments:其他属性(消息什么时候会自动被删除、自动过期、最长长度、最大长度字节、死信交换、死信路由键、最高优先级、懒惰模式)
注意:关于队列的声明,如果使用同一套参数进行声明了,就不能再使用其他参数来声明,要么删除该队列重新删除,可以使用命令行删除也可以在RabbitMQ Management上删除,要么给队列重新起一个名字。
arguments具体说明
Message TTL:队列中的消息什么时候会自动被删除,(x-message-ttl)
Auto expire:自动过期,(x-expires):
Max length:最长长度,(x-max-length)
Max length bytes:最大长度字节,(x-max-length-bytes)
Dead letter exchange:死信交换,(x-dead-letter-exchange)
Dead letter routing key:死信路由键,(x-dead-letter-routing-key)
Maximum priority:最高优先级,(x-max-priority)
Lazy mode:懒惰模式,(x-queue-mode=lazy)
Master locator(x-queue-master-locator)
官方解释:
发布到队列的消息在丢弃之前可以存活多长时间(毫秒)。(设置“ x-message-ttl ”参数。)
在自动删除队列(毫秒)之前,队列可以使用多长时间。(设置“ x-expires ”参数。)
在队列开始从队列中删除之前,队列可以包含多少(就绪)消息。(设置“ x-max-length ”参数。)
队列在开始从头部删除之前可以包含的就绪消息的总体大小。(设置“ x-max-length-bytes ”参数。)
如果邮件被拒绝或过期,将重新发布邮件的交换的可选名称。(设置“ x-dead-letter-exchange ”参数。)
邮件是无效的时候使用的可选替换路由密钥。如果未设置,将使用消息的原始路由密钥。(设置“ x-dead-letter-routing-key ”参数。)
要支持的队列的最大优先级数; 如果未设置,则队列将不支持消息优先级。(设置“ x-max-priority ”参数。)
将队列设置为延迟模式,在磁盘上保留尽可能多的消息以减少RAM使用; 如果未设置,队列将保留内存缓存以尽快传递消息。(设置“ x-queue-mode ”参数。)
增加解释:
设置队列中的所有消息的生存周期(统一为整个队列的所有消息设置生命周期),单位毫秒, 类似于redis中的ttl,生存时间到了,消息会被从队里中删除,注意是消息被删除,而不是队列被删除, 特性Features=TTL,也可以在发布消息的时候单独为某个消息指定剩余生存时间(但在消息发送的设置里)
当队列在指定的时间没有被访问(consume, basicGet, queueDeclare…)就会被删除,Features=Exp
限定队列的消息的最大值长度,超过指定长度将会把最早的几条删除掉, 类似于mongodb中的固定集合,例如保存最新的100条消息, Feature=Lim
限定队列最大占用的空间大小, 一般受限于内存、磁盘的大小, Features=Lim B
当队列消息长度大于最大长度、或者过期的等,将从队列中删除的消息推送到指定的交换机中去而不是丢弃掉,Features=DLX
将删除的消息推送到指定交换机的指定路由键的队列中去, Feature=DLK
优先级队列,声明队列时先定义最大优先级值(定义最大值一般不要太大),在发布消息的时候指定该消息的优先级, 优先级更高(数值更大的)的消息先被消费,
先将消息保存到磁盘上,不放在内存中,当消费者开始消费的时候才加载到内存中
四、生产者端参数详解
// 发送消息到队列
// 第一个参数为交换机名称、第二个参数为队列映射的路由key、第三个参数为消息的其他属性、第四个参数为发送信息的主体
channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
void basicPublish(String neme, String routingKey, boolean mandatory, boolean immediate, BasicProperties properties, byte[] message) throws IOException;
neme:为交换机名称
routingKey:路由键(队列映射的路由key),#匹配0个或多个单词,*匹配一个单词,在topic exchange做消息转发用
mandatory:true:如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者。false:出现上述情形broker会直接将消息扔掉
immediate:true:如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。(简单来说:mandatory标志告诉服务器至少将该消息route到一个队列中,否则将消息返还给生产者;immediate标志告诉服务器如果该消息关联的queue上有消费者,则马上将消息投递给它,如果所有queue都没有消费者,直接把消息返还给生产者,不用将消息入队列等待消费者了。)
properties :需要注意的是BasicProperties.deliveryMode,0:不持久化 1:持久化 这里指的是消息的持久化,配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留
message:消息主体
请注意持久化概念:
队列持久化:重启RabbitMQ服务器队列还在
消息持久化:重启RabbitMQ服务器消息还在(设置消息持久化必须先设置队列持久化,要不然队列不持久化,队列都不存在了,消息存在还有什么意义。消息持久化需要将交换机持久化、队列持久化、消息持久化,才能最终达到持久化的目的)
RabbitMQ中的消息确认机制:
//自动应答回复队列(RabbitMQ中的消息确认机制)
channel.basicConsume(QUEUE_NAME, true, consumer);
原理:
true:自动应答,即消费者获取到消息,该消息就会从队列中删除掉,
false:手动应答,当从队列中取出消息后,需要程序员手动调用方法应答,如果没有应答,该消息还会再放进队列中,就会出现该消息一直没有被消费掉的现象
工作队列:
轮询分发 :这种方式叫做轮询分发(round-robin),结果就是不管谁忙活着谁清闲,都不会多给一个消息,任意消息总是你一个,我一个。
公平分发(fair dipatch):消费者2处理的消息比消费者1多,能者多劳。
各种情景:
1、最简单的hello生产和消费(单生产者和单消费者)。
2、单生产者-多消费者。
3、多生产者-多消费者。
4、实体类传输,springboot完美的支持对象的发送和接收,不需要格外的配置。实体类(必须实现序列化接口)。
5、topic ExChange 模式,topic 是RabbitMQ中最灵活的一种方式,可以根据binding_key自由的绑定不同的队列。
6、fanout ExChange 模式,Fanout 就是我们熟悉的广播模式或者订阅模式,给Fanout转发器发送消息,绑定了这个转发器的所有队列都收到这个消息。
4万+

被折叠的 条评论
为什么被折叠?



