RabbitMQ采坑笔记

本文介绍了RabbitMQ中QueueingConsumer在4.x版本被弃用的情况,推荐使用DefaultConsumer,并详细解释了基本的消费模式、Consumer的工作原理以及如何避免内存溢出。此外,还讨论了在传送对象时遇到的问题,强调不能同时发送自定义对象和CorrelationData,否则会导致MessageConversionException。
摘要由CSDN通过智能技术生成

QueueingConsumer过时

QueueingConsumer在Rabbitmq客户端3.x版本中用的如火如荼,但是在4.x版本开初就被标记为@Deprecated。
Consumer的消费模式有Pull 和 Push两种,而经常用到的就是Push模式,Push模式在3.x的用法demo如下:

QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicQos(1);
channel.basicConsume(QUEUE_NAME, false, "consumer_zzh",consumer);
 
while (true) {
    QueueingConsumer.Delivery delivery = consumer.nextDelivery();
    String message = new String(delivery.getBody());
    System.out.println(" [X] Received '" + message + "'");
    channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
    break;
}

在官方文档中推荐使用继承DefaultConsumer的方式:

boolean autoAck = false;
channel.basicConsume(queueName, autoAck, "myConsumerTag",
     new DefaultConsumer(channel) {
         @Override
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body)
             throws IOException
         {
             String routingKey = envelope.getRoutingKey();
             String contentType = properties.getContentType();
             long deliveryTag = envelope.getDeliveryTag();
             // (process the message components here ...)
             channel.basicAck(deliveryTag, false);
         }
});

QueueingConsumer内部其实是一个LinkBlockingQueue,它将从broker端接受到的信息先暂存到这个LinkBlockingQueue中,然后消费端程序在从这个LinkBlockingQueue中take出消息。试下一下,如果我们不take消息或者说take的非常慢,那么LinkBlockingQueue中的消息就会越来越多,最终造成内存溢出。
这个问题可以通过设置Basic.Qos来很好的解决。
DefaultConsumer还有一下方法:

  • handleShutdownSignal方法 当Channel与Conenction关闭的时候会调用,
  • handleCancelOk方法会在其它方法之前调用,返回消费者标签
    handleCancelOk与handleCancel消费者可以显式或者隐式的取水订单的时候调用,也可以通过channel.basicCancel方法来显式的取消一个消费者订阅
    首先触发handleConsumeOk方法,之后触发handleDelivery方法,最后才触发handleCancelOk方法
	@Override
    public void handleConsumeOk(String consumerTag) {
        this._consumerTag = consumerTag;
    }

 	@Override
    public void handleCancelOk(String consumerTag) {
        // no work to do
    }

  	@Override
    public void handleCancel(String consumerTag) throws IOException {
        // no work to do
    }

   @Override
    public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig) {
        // no work to do
    }

  	@Override
    public void handleRecoverOk(String consumerTag) {
        // no work to do
    }

进入basicConsume方法内部看一看,他有三个实现但最终都是ChannerlN.class下的 public String basicConsume(String queue, final boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, final Consumer callback) throws IOException {}方法(下面代码块中的源码1)在最终执行,我们可以看到其只调用了Consumer的HandleConsumeOk方法,其方法实现如源码2;

//自己的consumer
 DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值