RabbitMQ 简介
Exchange
生产者直接将消息发送到exchange里面。
vhost
虚拟主机。一个RabbitMQ物理服务器上可以支持有多个vhost。不同的vhost可以认为都是一个RabbitMQ Server,可以简单的理解为,每一个vhost都是运行在物理机上的一个虚拟机。它会拥有自己的queue、exchange、bindings等,并且不同的vhost单独配置自己的权限。注意,不同的vhost,其queue和exchange不允许绑定。
消费模式
- 拉模式,就是消费者根据自己的意愿,主动从MQ中获取消息。MQ将不会主动将消息告知到消费者
- 造成消息堆积
- 推模式情况下, MQ主导什么情况下向消费者发送消息,以及每次发送多少消息
- 超过消费者消费能力限制
路由方式
direct
fanout
广播模式
假设有N个queue绑定到同一个fanout的exchange上,这个exchange每接收到一条消息,就会向这N个queue分别发送一条消息。
topic
topic与direct模式有些相似,都是exchange拿到消息,之后会根据routing key,将消息发送到routing key相匹配并且绑定到了这个exchange上的queue里面去(如果有多个queue的routing key都匹配,那么这些queue都会收到消息)
不过topic与direct的一个区别在于:topic模式下,queue向exchange绑定所用的routing key是支持模糊匹配的
此模式经常用做消息的多播模型。
header
上面所说的三种是最经常使用的模式,此外,还有一种header模式。
header模式的exchange在路由消息时,是不会使用routing key作为路由依据的,它的路由依据为消息的headers属性(并且只有在完全匹配的时候才会进行路由,否则是不会向这些queue投递消息的,消息会进入Alternate Exchanges,后面会详述)。
问题
1. 如何保证消息的可靠性投递
可能由于网络问题导致交付失败
生产侧的消息确认
事务模式
只有成功地将消息交付给RabbitMQ,事务才算完成。显而易见,使用事务会对性能造成影响。
confirm模式
消息都会被指派一个唯一的ID,一旦消息被投递到所有匹配的队列后,broker就会发送一个确认给生产者。如果消息和队列是持久化的,那么确认消息会在消息写入磁盘后再发出
confirm模式最大的好处在于它可以是异步的:单条confirm、批量confirm、异步confirm
消费侧的消息确认
消费者可以指定参数使得,RabbitMQ会等待消费者显式发回ack信号才会从内存(和磁盘,如果是持久化消息的话)中移除消息。否则,RabbitMQ会在队列中消息被消费后立即进行删除
注意
- 对于消费者这一侧的消息确认,RabbitMQ是没有设置超时时间的,理由是并不能确认消息的消费时长。但是一旦消费者的链接断开,这些没有ack的消息是会被重新投递的。换句话说,如果一个消费者挂掉(与MQ的连接断开),没有ack的消息会进行重新投递,但是假如这个消费者没有挂掉,那么会一直等待ack,没有超时时间的限制
2. 集群负载均衡
-
轮询法
-
随机法
-
源地址哈希法
-
加权轮询法
-
最小连接数法
3. 如何处理消息积压
一般来说是消息生产超过了消费者的消费能力
MQ的流控主要是指发生在消费者消费能力不足的情况下,对生产者进行阻塞。
- 基于内存:如果MQ内存使用量超过40%,会抛出异常警告并阻塞所有生产链接(这个值可以调整)
- 基于磁盘:如果磁盘剩余容量少于1G,同样会阻塞所有的生产者(这个值同样可以调整)
4. 消息消费是有序的吗?
rabbitmq本身是没有绝对的消息顺序机制的,单个queue在多消费者下不能保证其先后顺序
5. 如何确保不消费重复消息?
kafka有offset机制保证
rabbitmq可以在每次消费数据时,将消息ID写入到集合中,这样每次新消息消费之前都在集合中找有没有这个数据,如果有就丢弃掉
附录
apt-get install erlang-nox
apt-get update
apt-get install rabbitmq-server
rabbitmqctl add_user <username> <password>
rabbitmqctl set_user_tags <username> administrator
rabbitmqctl set_permissions -p / <username> ".*" ".*" ".*"
启动:sudo rabbitmq-server start
关闭: sudo rabbitmq-server stop
重启: sudo rabbitmq-server restart
rabbitmqctl status
配置rabbitMQ远程连接
https://www.rabbitmq.com/access-control.html
in the classic config file format (rabbitmq.config):
/etc/rabbitmq.config
[{rabbit, [{loopback_users, []}]}].
rabbitmqctl stop
rabbitmq-server