RabbitMQ

首先抛出几个问题:
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的类型。

屏幕快照 2018-10-24 下午7.46.24.png

使用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要对处理做幂等

你可能感兴趣的:(RabbitMQ)