rabbitMQ学习(二)高级特性与集群

rabbitMQ学习(二)高级特性与集群

我们学习中间件的时候,入门往往是简单的(会用API就行了),但要做到对MQ的高可用与高性能,我们还得了解一下他的一些高级特性。

rabbitMQ的高级特性

保证MQ的可靠性

学习过了TCP协议的同学都知道,TCP协议通过了确认机制、重传机制等等保证了数据传输的可靠性。

招式是一样的,rabbitMQ也提供了差不多的机制来保证我们生产者的消息被消费者接收并正常使用。

我们先来回顾一下rabbitMQ消息的发送流程(先考虑最简单的版本):

可以看到我们的发送主要有三个部分组成,也有三个对应的机制来保证这三个部分的可靠性。

confirm机制

生产者发送的消息能达到交换机的可靠性由confirm机制来保证。

对于每一条发送的消息,MQ都会返回一个到达交换机成功与否的标志,我们可以在此之后选择不同的处理方式。

该机制由回调方式来实现:

channel.confirmSelect(); // 此条代码表示选择确认模式
channel.addConfirmListener(new ConfirmListener() {
    public void handleAck(long l, boolean b) throws IOException { // 成功
        System.out.println(b);
        System.out.println(l);
        System.out.println("chenggong");
    }

    public void handleNack(long l, boolean b) throws IOException { // 失败
        System.out.println(b);
        System.out.println(l);
        System.out.println("shibai");
    }
});
return机制

对于交换机能否找到对应的路由队列进行消息的存储,我们采用return机制来保证。

对于每一条没有找到路由的消息,我们都能通过回调的方式获取到该消息的信息,从而做出不同的选择。

channel.addReturnListener(new ReturnCallback() {
    public void handle(Return aReturn) {
        System.out.println(new String(aReturn.getBody()));  // 获取该消息类容
        System.out.println(aReturn.getExchange());	// 获取消息的交换机
        System.out.println(aReturn.getRoutingKey()); // 获取消息的路由信息
    }
});
Consumer-ACK机制

对于我们的消息是否正常的被处理,MQ提供了ConsumerACK机制来将消息重新放入队列中:

channel.basicConsume("test", false, new DefaultConsumer(channel){ // 注意:需要将第二个参数(自动回复)设为false,否则不会生效
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println(new String(body));
        channel.basicNack(envelope.getDeliveryTag(), false, true); // basicNack表示消息处理失败,将消息重新放入队列中
        //channel.basicAck(envelope.getDeliveryTag(), false); // 表示消息处理成功
    }
});
对消息的管理
限流

rabbitMQ为我们提供了限流机制来防止消息堆叠过多导致消费端崩溃的情况。

只需一行代码就能搞定:

channel.basicQos(0, 3, false); // 第一个参数表示消息的大小限制(0为不做限制) 第二个参数表示一次性消费的消息数量 第三个表示我们是否将此设置应用于channel
TTL

同时,为了解决消息堆叠过多的情况,MQ也支持消息的过期时间设置。

MQ支持两种方式来设置过期时间,第一种是每条消息都能设置单独的过期时间,通过发送时的参数设置:

AMQP.BasicProperties properties = new AMQP.BasicProperties().builder()
                .deliveryMode(2)
                .contentEncoding("UTF-8")
                .expiration("100000") // 100s的过期时间
                .headers(headers)
                .build();
        String msg = "test message";
        channel.basicPublish("", queueName, properties, msg.getBytes());

第二种是对队列设置过期时间,该队列中所有的消息都会在过期时间后被删除。

死信队列

上一节我们说到,消息会在过期时间后被删除,这样真的安全吗,我们的做法应该是将该消息放入别的队列中被消费。这就是死信队列。

死信队列:没有被及时消费的消息存放的队列。

那些消息是没有被即使消费的呢?

  1. 上面说到的过期的消息
  2. 达到最大队列长度后的消息
  3. 消息被拒绝了,且没有设置重新投递
延迟队列

延迟队列可以实现消息的延迟发送,即等时间过了N久后消费方才会读取。

比如订单支付场景,我们要在订单创建后的15分钟后判断是否支付,就可以用延迟队列来实现。

rabbitMQ没有直接实现延迟队列的功能,但结合我们上面的知识,我们发现可以通过死信队列和TTL共同来实现延迟队列。

即为一个队列设置过期时间,等过期时间到了之后便被发送到了一个死信队列进行处理。

集群

为了保证MQ的高可用,rabbitMQ也支持集群模式。

如图,rabbitMQ通过一种镜像队列的方式来保证一个节点崩溃后导致整个MQ不可用。

每个MQ节点都会主动的进行同步,但是这种方式也会极大地消耗系统内部的带宽。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值