什么是MQ?为什么使用MQ?

RabbitMQ Use cases: Explaining message queues and when to use them

MQ Message Queue, 消息队列,用于消息传递和缓存

  • 为了系统模块间解耦,不同子系统可以使用不同的编程语言
  • 实现异步通信
  • 应对流量并发,限流(如何实现限流?

哪些场景中会使用MQ?

  • 日志处理: 解决大量日志传输
  • 分布式任务处理

SmartCMP产品中有哪些场景下使用到了MQ?

  • Cloudify task日志处理
  • Cloudify celery异步任务处理的broker
  • Java异步任务处理的broker
  • Java与Cloudify rpc调用(主机名,IP地址分配)
  • cloudify同步任务状态给Java端

MQ的缺点?

  • 系统可用性降低
  • 复杂度升高

有哪些MQ产品?各自优缺点比较

RabbitMQ:erlang语言开发,社区活跃度高,文档完善,技术支持较好

RocketMQ:阿里开源的,基于Java语言开发,经过阿里的生产环境的超高并发、高吞吐的考验,性能卓越,同时还支持分布式事务等特殊场景。

Kafka:提供的消息中间件的功能明显较少一些,Kafka的优势在于专为超高吞吐量的实时日志采集、实时数据同步、实时数据计算等场景来设计,因此Kafka在大数据领域中配合实时计算技术(比如Spark Streaming、Storm、Flink)使用的较多。但是在传统的MQ中间件使用场景中较少采用。

ActiveMQ:较为传统的消息中间件,互联网企业使用较少。

RabbitMQ基本概念

RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而聚类和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端

  • Broker: 简单来说就是消息队列服务器实体
  • Exchange: 消息交换机,它指定消息按什么规则,路由到哪个队列
  • Queue: 消息队列载体,每个消息都会被投入到一个或多个队列
  • Binding: 绑定,它的作用就是把exchange和queue按照路由规则绑定起来
  • Routing Key: 路由关键字,exchange根据这个关键字进行消息投递
  • VHost: vhost 可以理解为虚拟 broker ,即 mini-RabbitMQ server。其内部均含有独立的 queue、exchange 和 binding 等,但最最重要的是,其拥有独立的权限系统,可以做到 vhost 范围的用户控制。当然,从 RabbitMQ 的全局角度,vhost 可以作为不同权限隔离的手段(一个典型的例子就是不同的应用可以跑在不同的 vhost 中)。
  • Producer: 消息生产者,就是投递消息的程序
  • Consumer: 消息消费者,就是接受消息的程序
  • Channel: 消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路。
  • Exchange Type
    • direct
    • fanout
    • topic
    • headers

RabbitMQ工作原理

五种工作模式

  1. simple 模式
  2. work 模式
  3. publish/subscribe 发布订阅模式
  4. routing 路由模式
  5. topic 主题模式

RabbitMQ常见问题

  • 消息持久化
  • 队列持久化
  • 消息时序如何保证
  • 消息重复消费

造成消息重复的根本原因是:网络不可达。

所以解决这个问题的办法就是绕过这个问题。那么问题就变成了:如果消费端收到两条一样的消息,应该怎样处理?

消费端处理消息的业务逻辑保持幂等性。只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样。保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现。利用一张日志表来记录已经处理成功的消息的 ID,如果新到的消息 ID 已经在日志表中,那么就不再处理这条消息。

  • 消息可靠传输
  • 大流量高并发,消费端来不及处理(消息积压)

  • 网络分区(脑裂)如何应对

  • 如何保证高可用

    • 普通集群模式
    • 镜像集群模式(有什么缺点)
    • Quorum queues
  • 如何解决消息长时间无人消费

    • 设置消息的TTL
  • 如何避免大流量导致RabbitMQ内存超限,甚至系统OOM

  • 如何规划Exchange、Queue以及绑定关系

RabbitMQ常用命令

  1. # 当前节点运行状态查询
  2. rabbitmqctl status
  3. # 集群状态查询
  4. rabbitmqctl cluster_status
  5. # 用户列表查询
  6. rabbitmqctl list_users
  7. # vhost 查询
  8. rabbitmqctl list_vhosts
  9. # 队列列表查询
  10. rabbitmqctl list_queues
  11. # 消费者列表查询
  12. rabbitmqctl list_consumers
  13. # 策略列表查询
  14. rabbitmqctl list_policies
  15. # 集群配置
  16. rabbitmqctl stop_app
  17. rabbitmqctl join_cluster <nodename>
  18. rabbitmqctl start_app
  19. # 开启管理页面功能
  20. rabbitmq-plugins enable rabbitmq_management

RabbitMQ 实践

创建Exchange

  • vhost
  • name
  • type: direct, fanout, topic, headers
  • durability: durable, transient
  • Auto delete: no, yes
  • internal: no, yes

创建Queue

  • vhost
  • type
  • name
  • durability
  • auto delete
  • Arguments
    • Message TTL: 消息最大存活时间(ms)
    • Auto expire: 队列被销毁前最长unused时间
    • max length:队列中最多多少条ready状态的消息,超出部分会从队列头部开始被drop掉
    • max length bytes
    • overflow behaviour:队列长度超限后,如果操作,默认drop head,其他:reject-publish
    • dead letter exchange
    • dead letter routing key
    • single active consumer
    • maxium priority
    • lazy mode
    • master locator

创建Policy

查看Connections、channels、exchanges、queues、policies

如何设计一个消息中间件系统

CAP理论

  • 一致性:raft一致性协议
  • 可用性:集群、配置与数据持久化
  • 分区容错
  • 伸缩性