RabbitMQ安装(windows)
windows下安装很简单,跟着安装程序走就可以了。
管理后台
rabbitmq自带管理后台,安装后需要配置开启
进入rabbitmq安装目录中的sbin目录执行
rabbitmq-plugins enable rabbitmq_management
重启rabbitmq服务生效
打开http://localhost:15672/即可看到管理后台
用户名密码均为guest
配置说明
http://www.rabbitmq.com/configure.html#config-items
使用命令行查看队列列表
sbin>rabbitmqctl list_queues
sbin>rabbitmqctl list_queues name messages_ready messages_unacknowledged
使用命令行查看exchange列表
sbin>rabbitmqctl list_exchanges
定义队列
RabbitMQ 不允许你用不同的参数重新定义一个已经存在的队列。
RabbitMQ doesn’t allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that
可靠性
要确保消息不丢失,需要设置消息持久化,同时队列也必须为耐久的。
但是这样做仍然不是100%可靠,因为如果RabbitMQ 在接收消息后、完成持久化之前崩溃,那么就会导致消息丢失。
重复处理
考虑如下场景(前提:队列、消息都是持久的):
- 消费者接收了一个消息msgA,处理了一半,没有完成、没有发起ack确认;
- 此时RabbitMQ 崩溃了;
- 消费者完成了消息msgA的处理;
- 当RabbitMQ 重启后,发现msgA未被处理,于是msgA再次被发送给消费者。
这种场景下,消息msgA就会被处理两次,所以消费者端应该要有防止重复处理的机制。
ACK
ACK确认,只是告诉RabbitMQ 消费者已经完成了对消息的处理,而不是说逻辑上处理成功,即使是由于业务处理失败了,也要进行ACK确认。因为一般而言业务上的原因导致失败的话,重试是不解决问题的。只有网络中断、机器断电等故障引起的失败才有重试的必要。
防止业务负载集中到某个消费者
channel.basicQos(prefetchCount);
设置
prefetchCount=1
,告诉RabbitMQ 每次只给一个消费者分配一个消息,直到上一个分配给该消费者的消息被确认处理完成。这样一来,消息就会根据实际处理情况,每次都分配给空闲的消费者。
关于默认Exchange
默认Exchange隐式地绑定到每一个队列,路由key为队列名。不能对其进行显式绑定或解绑。并且它是不可删除的。
The default exchange is implicitly bound to every queue, with a routing key equal to the queue name. It is not possible to explicitly bind to, or unbind from the default exchange. It also cannot be deleted.
消息传递的基本过程
发布者发布一个消息
–>exchange接收消息(如果发布者没有指定特定的Exchange则使用默认Exchange),并根据exchange的类型,按照一定的路由规则,把消息路由给每一个符合路由规则的队列(如果没有匹配的队列,则消息被丢弃)
–>队列将消息发送给订阅该队列的某一个消费者(如果没有消费者则消息保留在队列中,知道有消费者消费该消息)
Topic Exchange的通配符
星号匹配一个单词(注意,不是一个字母)
*
(star) can substitute for exactly one word.
井号匹配任意个单词
#
(hash) can substitute for zero or more words.
AMQP协议mandatory和immediate标志位的作用
mandatory和immediate是AMQP协议中basic.pulish方法中的两个标志位,它们都有当消息传递过程中不可达目的地时将消息返回给生产者的功能。具体区别在于:
1. mandatory标志位
当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者;当mandatory设为false时,出现上述情形broker会直接将消息扔掉。
2. immediate标志位
当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。