首先抛出几个问题:
1.消息中间件的优势?
2.rabbitmq作为一个消息中间件相比其他产品有什么优势?
3.组成部分以及每个部分担当的职责.
4.使用rabbitmq时应该注意什么
5.如何保证消息一定被消费/投递?
消息中间件的优势
- 最重要的优势就是解耦,消息中间件并不要求publisher和consumer要同时在线,有publisher就能够发布消息,有consumer在线就能够消费消息
- 其次是削峰,这其实是将消息中间件作为一个过渡,使用其内部的queue暂存没有被消费的消息,用来扛瞬时流量高峰是不错的选择
rabbitmq作为一个消息中间件的优势
- 开源
- 高可用
- 可伸缩
- 最重要的一点,自带好用的web控制台
组成部分
RabbitMQ是基于AMQP(https://en.wikipedia.org/wiki/Advanced_Message_Queuing_Protocol)模型实现的消息中间件,他包含以下组成部分
- publisher
publisher:发布消息
- exchange
exchange:用来决定消息应该投递到哪些queue
- queue
queue:用来存储并分发消息
- consumer
consumer:消费消息
除此之外还有另外几个概念
- routing_key
搭配binding_key用来过滤消息,这个属性会在消息发送时被决定
- binding_key
用来绑定exchange和queue,和routing_key搭配在exchange决策哪些消息应该投递到哪些queue
- exchange的类型:FANOUT,TOPIC,DIRECT
FANOUT:广播,此时binding_key和routing_key其实是无效的,消息将会投递到目标exchange绑定的所有queue上
DIRECT:消息将只会被投递到和routing_key一致的binding_key所绑定的queue上
TOPIC:和DIRECT相似,只是此时exchange的决策会考虑binding_key的通配符配置
举个例子,下图中一共两个Exchange,一个采用的时fanout模式,另一个是direct模式,红线代表routingkey=sun的消息的轨迹,绿线代表routingkey=moon的消息的轨迹,可以看到采用fanout模式的Exchange不关心bindingkey到底是啥,消息将会投递给所有绑定在该Exchange的Queue里。
在看绿线消息的轨迹,因为DIRECT模式所以消息只被投递到了bindingkey=moon的queue。
综上,queue可以通过bindingkey来选择自己感兴趣的消息,而publisher可以通过设置消息的routingkey来对消息进行打标归类,而最终决定这个消息会投递到哪个queue,还需要看exchange的类型。
使用rabbitmq时该注意什么?
http://mqmastery.com/2017/02/28/4-things-avoid-rabbitmq/
- rabbitmq有默认的guest用户,他的权限和admin是一样的,安装时要注意T掉
- rabbitmq的集群尽量部署在LAN的环境下而不是WAN,原因在于rabbitmq的集群机器间通过heartbeat消息确认彼此的存活状态,如果部署在WAN的网络环境下,不可预期的网络抖动很容易造成heartbeat消息超时,某台机器被T出集群的情况,当这种情况发生的时候会产生的情况我们后面再讲。
- 避免使用rabbitmq处理数据量大的消息,比如将文件图片或者视频等内容通过mq来传输。这种大消息会占用大量的带宽,并且对于非持久化的queue配置来说,这将会占用broker大量的内存,这些都会导致broker的吞吐下降,从而导致消息被积压,再者因为发送heartbeat消息的channel和发送业务消息的channel其实是同一个,发送超大的消息将会占用channel资源这会导致集群健康检查失败,集群将会变的不稳定
- 避免在实时处理场景使用rabbitmq,比如IM即时通讯。http://mqmastery.com/2016/10/14/not-use-rabbitmq-real-time-messaging/
这篇文章简单总结下- 在即时通讯系统中,好友的online/offline等状态是对时间十分敏感的,但是rabbitmq并没有native的接口来让服务端感知有哪些客户端连接,以及有哪些客户端断开连接,那我们只有在客户端状态变更时发送类似heartbeat的消息广播给其他感兴趣的客户端,这会导致真正的聊天消息被这种消息淹没(毕竟rabbitmq更偏向于可用性,即保证消息会被投递到消费者,但是并不保证消息什么时候被投递)
- 在IM通讯的场景下,client会非常的多并且散布在WAN的网络环境下,这样就导致了消息消费的速度受到网络环境的制约,这导致的结果将和传输大消息差不多。
- 最后总结:rabbitmq并不保证时间敏感性,所以对于时间敏感的应用场景,不推荐使用rabbitmq
rabbitmq如何保证消息一定被消费/投递
rabbitmq的ack机制以轻量级的解决方案替代事务性消息保障消息的可靠性,具体可参考:http://www.rabbitmq.com/confirms.html
通俗理解如下,具体怎么表现要看client和broker的设置
- publisher发送消息给broker时,如果发送成功,broker会回复一个ack消息,如果publisher没收到ack消息,需要手动重试 Publisher Confirms and Guaranteed Delivery
- consumer消费消息成功时需要回复broker一个ack消息,接收到ack消息之后broker才会把消息从queue中删除,否则,消息会requeue并且重新投递,这也是为什么消息中间件都保证消息至少被消费1次,而且这也是为什么consumer要对处理做幂等
网友评论