消息队列中间件 - RabbitMQ消息的持久化、确认机制、死信队列

2,108 阅读4分钟

持久化和应答机制Ack

消息队列中间件系列的最后一篇了,RabbitMQ消息的持久化、确认机制、死信队列、负载均衡等一系列进行说明。

消息持久化

  • 当RabbitMq重启以后,未消费的消息,可以在服务重启后继续消费,不会丢失。

应答机制Ack

两种方式:一种是自动确认,一种是手动确认

  • 自动确认就是消费者接收消息以后,立即ack,然后再慢慢处理业务逻辑,假如业务逻辑出现异常,消息也会被确认的。
  • 手动确认,消费者接收消息以后,消息状态被置为unack状态,然后由业务逻辑指定ack的位置,假如没有手动ack,则mq中的消息不回减少。

死信队列

死信队列 DLX(Dead-Letter-Exchange) 也可以成为死信交换机,就是当一个队列中的消息变成死信以后,会被重新发送到另一个交换机,这个交换机就是DLX,而绑定DLX的队列就是死信队列。

死信队列的成因:

**消息被拒绝,**消费者中使用 (basic.reject/basic.nack),并且 requeue = false , 消息被拒绝接收后就会进入到死信队列中。

# 消费者
$callback = function ($msg) {
   // 拒绝接收消息
   $msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
};

$channel->basic_qos(null, 1, null);
$channel->basic_consume($queueName,'', false,false,false,false,$callback);

**消息过期,**可以使用 x-message-ttl 参数设置当前队列中所有消息的过期时间(单位毫秒)。一旦消息过期,就会从队列中删除。

// 在正常队列中设置消息过期时间
$channel->exchange_declare('logs', 'direct',false, false, false);
$args = new AMQPTable([
   // 消息过期时间
   'x-message-ttl'             => 20000,
   // 死信交换机
   'x-dead-letter-exchange'    => 'dead-exc',
   // 死信路由键
   'x-dead-letter-routing-key' => 'dead-key'
]);
$channel->queue_declare($queue_name, false, true,false,false,false,$args);
$channel->queue_bind($queue_name, 'logs');

队列达到最大长度: x-max-length 设置最大消息数,x-max-length-bytes 设置最大长度(以字节为单位)。如果设置了两个参数,则两者都将适用,将强制执行首先达到的限制。

$args = new AMQPTable([
// 设置最大消息数
   'x-max-length' => 2,
   'x-dead-letter-exchange'    => 'dead-exc',
   'x-dead-letter-routing-key' => 'dead-key'
]);

设置死信队列,只需要定义队列的时候设置x-dead-letter-exchange指定交换机就可以了

延时队列

延时队列就是当消息发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后消费者才能拿到消息来消费。

集群模式

  • 允许生产者和消费者在RabbitMQ节点崩溃的情况下继续运行。
  • 允许通过添加更多的节点来扩展消息通信的吞吐量。

RabbitMQ会始终记录以下四种类型的内部元数据:

  • 队列元数据,队列名称和它们的属性(是否持久化,是否自动删除)
  • 交换机元数据,交换器类型、名称和属性
  • 绑定元数据,一张简单的表格展示了如何将消息路由到队列
  • vhost元数据,为vhost内的队列、交换机和绑定提供命名空间和安全属性

RabbitMQ集群分为3个模式,主备模式,镜像模式,异地多活模式。

cluster1.png

  • 主备模式,从节点相当于主节点的链接,所有从节点收到的请求,真实转向的都是主节点,一般在并发和数据不是特别多的情况下使用,当主节点挂掉会从备份的节点中选择一个节点出来作为主节点对外提供服务。

cluster2.png

  • 镜像模式,将需要消费的队列变成镜像队列,存在于多个节点,这样就可以实现RabbitMQ的HA高可用,作用就是消息实体会主动在镜像节点之间实现同步,任何一个节点宕机都都关系,保证100%数据不丢失,在实际工作中用的最多的。

cluster3.png

  • 异地多活模式,用来实现异地的数据复制,使用多活模式需要借助federation插件来实现集群间或节点间的消费复制,广泛用于多互联网公司。

负载均衡

HAproxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性、负载均衡、以及Tcp和Http的应用程序代理。

特别适用于那些负载特大的Web站点,完全可以支持数以万计的并发连接,同时可以保护Web服务器不被暴漏到网络上。