一、MQ常见问题

  • ① 消息可靠性

确保发送的消息至少被消费一次;

  • ② 延迟消息

实现消息的延迟投递;

  • ③ 消息堆积

处理消息无法及时消费的问题;

  • ④ 高可用

避免单点MQ故障导致整体不可用;

二、消息堆积-惰性队列

1、消息堆积问题

当生产者发送消息的速度超过了消费者处理消息的速度,就会导致队列中的消息堆积,直到队列存储消息达到上限。最早接收到的消息,可能就会成为死信,会被丢弃,这就是消息堆积问题。

2、解决消息堆积方法

  • ① 增加更多消费者,提高消费速度;
  • ② 在消费者内开启线程池加快消息处理速度;
  • ③ 扩大队列容积,提高堆积上限。

3、惰性队列

从RabbitMQ的3.6.0版本开始,就增加了Lazy Queues的概念,也就是惰性队列。

  • ① 惰性队列特征

Ⅰ 接收到消息后直接存入磁盘而非内存;
Ⅱ 消费者要消费消息时才会从磁盘中读取并加载到内存;
Ⅲ 支持数百万条的消息存储。

  • ② 设置惰性队列

要设置一个队列为惰性队列,只需要在声明队列时,指定x-queue-mode属性为lazy即可。

Ⅰ 可以通过命令行将一个运行中的队列修改为惰性队列,如下:
rabbitmqctl set_policy Lazy "^lazy-queue$" '{"queue-mode":"lazy"}' --apply-to queues

Ⅱ 用SpringAMQP声明惰性队列,如下:

@Bean注解的形式,如下:

@Bean
public Queue lazyQueue(){
    return QueueBuilder
            .durable("lazy.queue")
            .lazy() // 开启x-queue-mode为lazy
            .build();
}

@RabbitListener注解的形式,如下:

@RabbitListener(queuesToDeclare = @Queue(
        name = "lazy.queue",
        durable = "true",
        arguments = @Argument(name = "x-queue-mode", value = "lazy")
))
public void listenLazyQueue(String msg){
    log.info("接收到lazy.queue的延迟消息:{}", msg);
}
  • ④ 惰性队列优缺点

Ⅰ 优点
基于磁盘存储,消息上限高;
没有间歇性的page-out,性能比较稳定;

Ⅱ 缺点
基于磁盘存储,消息时效性会降低;
性能受限于磁盘的IO。

三、高可用-MQ集群

官方文档:Clustering Guide — RabbitMQ

1、集群分类

  • ① 普通集群

是一种分布式集群,将队列分散到集群的各个节点,从而提高整个集群的并发能力。

  • ② 镜像集群

是一种主从集群,普通集群的基础上,添加了主从备份功能,提高集群的数据可用性。

注意:镜像集群虽然支持主从,但主从同步并不是强一致的,某些情况下可能有数据丢失的风险。

  • ③ 仲裁队列

在RabbitMQ的3.8版本以后推出的,底层采用Raft协议确保主从的数据一致性。

2、普通集群

  • ① 普通集群特点

Ⅰ 会在集群的各个节点间共享部分数据,包括:交换机、队列元信息。不包含队列中的消息;
Ⅱ 当访问集群某节点时,如果队列不在该节点,会从数据所在节点传递到当前节点并返回;
Ⅲ 队列所在节点宕机,队列中的消息就会丢失。

  • ② 模拟普通集群搭建

Ⅰ 获取Cookie

RabbitMQ底层依赖于Erlang,而Erlang虚拟机就是一个面向分布式的语言,默认就支持集群模式。集群模式中的每个RabbitMQ 节点使用 cookie 来确定它们是否被允许相互通信。

要使两个节点能够通信,它们必须具有相同的共享秘密,称为Erlang cookie。cookie 只是一串最多 255 个字符的字母数字字符。

每个集群节点必须具有相同的 cookie。实例之间也需要它来相互通信。

首先获取Cookie,指令如下:

docker exec -it mq cat /var/lib/rabbitmq/.erlang.cookie

其中YYNCLCJEKVNUFYQFPNZH这一串就是生成的Cookie,如下:

[root@localhost ~]# docker exec -it mq cat /var/lib/rabbitmq/.erlang.cookie
YYNCLCJEKVNUFYQFPNZH[root@localhost ~]#