如何在RabbitMQ中将消息从一个队列移动到另一个队列

如何在RabbitMQ中将消息从一个队列移动到另一个队列,rabbitmq,message-queue,spring-amqp,messagebroker,rabbitmq-exchange,Rabbitmq,Message Queue,Spring Amqp,Messagebroker,Rabbitmq Exchange,在RabbitMQ中,我有一个失败队列,其中有来自不同队列的所有失败消息。现在我想提供“重试”功能,以便管理员可以再次将失败消息移动到各自的队列中。这个想法是这样的: 上图是我的失败队列的结构。单击“重试”链接后,消息应移动到原始队列中,即队列1、队列2等。如果您正在寻找Java代码来执行此操作,那么您只需使用要移动的消息并将这些消息发布到所需队列。如果您不熟悉基本的消费和发布操作,只需查看rabbitmq的教程页面。这不是直接的消费和发布。RabbitMQ不是这样设计的。它考虑到交换和队列都

在RabbitMQ中,我有一个失败队列,其中有来自不同队列的所有失败消息。现在我想提供“重试”功能,以便管理员可以再次将失败消息移动到各自的队列中。这个想法是这样的:


上图是我的失败队列的结构。单击“重试”链接后,消息应移动到原始队列中,即队列1、队列2等。

如果您正在寻找Java代码来执行此操作,那么您只需使用要移动的消息并将这些消息发布到所需队列。如果您不熟悉基本的消费和发布操作,只需查看rabbitmq的教程页面。

这不是直接的消费和发布。RabbitMQ不是这样设计的。它考虑到交换和队列都可以是临时的,并且可以删除。这是嵌入在通道中的,用于在单次发布后关闭连接

假设: -您有一个持久队列,可交换目标(发送到) -您有一个用于目标(从中获取)的持久队列

以下是执行此操作的代码:

        import com.rabbitmq.client.Channel;
        import com.rabbitmq.client.QueueingConsumer;
        import org.apache.commons.lang.StringUtils;
        import org.slf4j.Logger;
        import org.slf4j.LoggerFactory;
        import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;    

        public object shovelMessage(
                     String exchange,
                     String targetQueue,
                     String destinationQueue,
                     String host,
                     Integer port,
                     String user,
                     String pass,
                     int count) throws IOException, TimeoutException, InterruptedException {

                if(StringUtils.isEmpty(exchange) || StringUtils.isEmpty(targetQueue) || StringUtils.isEmpty(destinationQueue)) {
                    return null;
                }

                CachingConnectionFactory factory = new CachingConnectionFactory();
                factory.setHost(StringUtils.isEmpty(host)?internalHost.split(":")[0]:host);
                factory.setPort(port>0 ? port: Integer.parseInt(internalPort.split(":")[1]));
                factory.setUsername(StringUtils.isEmpty(user)? this.user: user);
                factory.setPassword(StringUtils.isEmpty(pass)? this.pass: pass);
                Channel tgtChannel = null;
                try {
                    org.springframework.amqp.rabbit.connection.Connection connection = factory.createConnection();

                    tgtChannel = connection.createChannel(false);
                    tgtChannel.queueDeclarePassive(targetQueue);

                    QueueingConsumer consumer = new QueueingConsumer(tgtChannel);
                    tgtChannel.basicQos(1);
                    tgtChannel.basicConsume(targetQueue, false, consumer);

                    for (int i = 0; i < count; i++) {
                        QueueingConsumer.Delivery msg = consumer.nextDelivery(500);
                        if(msg == null) {
        // if no message found, break from the loop.
                            break;
                        }
                        //Send it to destination Queue
                        // This repetition is required as channel looses the connection with 
                        //queue after single publish and start throwing queue or exchange not 
                        //found connection.
                        Channel destChannel = connection.createChannel(false);
                        try {
                            destChannel.queueDeclarePassive(destinationQueue);
    SerializerMessageConverter serializerMessageConverter = new SerializerMessageConverter();
     Message message = new Message(msg.getBody(), new MessageProperties());
                          Object o = serializerMessageConverter.fromMessage(message);
// for some reason msg.getBody() writes byte array which is read as a byte array // on the consumer end due to which this double conversion.
                            destChannel.basicPublish(exchange, destinationQueue, null, serializerMessageConverter.toMessage(o, new MessageProperties()).getBody());
                            tgtChannel.basicAck(msg.getEnvelope().getDeliveryTag(), false);
                        } catch (Exception ex) {
                            // Send Nack if not able to publish so that retry is attempted
                            tgtChannel.basicNack(msg.getEnvelope().getDeliveryTag(), true, true);
                            log.error("Exception while producing message ", ex);
                        } finally {
                            try {
                                destChannel.close();
                            } catch (Exception e) {
                                log.error("Exception while closing destination channel ", e);
                            }

                        }
                    }

                } catch (Exception ex) {
                    log.error("Exception while creating consumer ", ex);
                } finally {
                    try {
                        tgtChannel.close();
                    } catch (Exception e) {
                        log.error("Exception while closing destination channel ", e);
                    }
                }

                return null;

            }
导入com.rabbitmq.client.Channel;
导入com.rabbitmq.client.QueueingConsumer;
导入org.apache.commons.lang.StringUtils;
导入org.slf4j.Logger;
导入org.slf4j.LoggerFactory;
导入org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
公共对象消息(
字符串交换,
字符串targetQueue,
字符串destinationQueue,
字符串主机,
整数端口,
字符串用户,
字符串传递,
int count)引发IOException、TimeoutException、InterruptedException{
if(StringUtils.isEmpty(交换)| | StringUtils.isEmpty(目标队列)| | StringUtils.isEmpty(目的队列)){
返回null;
}
CachingConnectionFactory=新的CachingConnectionFactory();
factory.setHost(StringUtils.isEmpty(主机)?internalHost.split(“:”[0]:主机);
setPort(端口>0?端口:Integer.parseInt(internalPort.split(“:”[1]));
factory.setUsername(StringUtils.isEmpty(用户)?this.user:user);
factory.setPassword(StringUtils.isEmpty(pass)?this.pass:pass);
通道tgtChannel=null;
试一试{
org.springframework.amqp.rabbit.connection.connection=factory.createConnection();
tgtChannel=connection.createChannel(false);
tgtChannel.queueDeclarePassive(目标队列);
QueueingConsumer=新的QueueingConsumer(tgtChannel);
tgtcchannel.basicQos(1);
tgtChannel.basicConsume(targetQueue,false,consumer);
for(int i=0;i
我还实现了类似的功能,因此我可以将消息从dlq移回处理。链接:

我不知道你在这里找什么。你必须编写代码来实现这一点,然后在某个地方你必须发布消息。我不知道你真的想尝试多少次除以零,但你永远不会得到不同的答案嗨,我只想将消息从一个队列移动到另一个队列