如何在Spring Rabbit中干净地关闭RabbitTemplate?

时间:2016-08-19 19:52:47

标签: java spring rabbitmq spring-rabbit spring-rabbitmq

我编写了一个脚本,该脚本使用Spring Rabbit使用RabbitTemplate.convertAndSend将大量消息放入Rabbit队列,然后退出。但是,即使邮件已加入队列,Rabbit连接似乎也会使应用程序保持活动状态。在消息排队后,我还没有找到一种干净地告诉Rabbit服务器停止的方法。

我能够提出的最佳解决方案是将我的convertAndSend调用更改为convertSendAndReceive,以便我知道消息已成功入队,然后使用System.exit(0)退出。我切换到convertSendAndReceive,因为看起来convertAndSend发生在后台线程或某些事情中,因为如果我在执行了一些调用之后执行了System.exit(0),那么只有第一个调用才能成功。

请注意,仅创建RabbitTemplate不会导致此行为;通过"发送"之一使用它方法呢。

以下代码说明了这个问题。

import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import static issues.RabbitSettings.*; //Static fields containing my test Rabbit connection info

public class RabbitTemplateShutdownIssue {
    public static void main(String[] args) {
        RabbitTemplate rabbitTemplate = createRabbitTemplate();
        rabbitTemplate.convertAndSend(ROUTING_KEY, "Test"); // Or convertSendAndReceive
        // The app never exits
    }

    private static RabbitTemplate createRabbitTemplate() {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(getConnectionFactory());
        rabbitTemplate.setExchange(EXCHANGE);
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    private static ConnectionFactory getConnectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(HOSTNAME);
        connectionFactory.setPublisherConfirms(true);
        connectionFactory.setVirtualHost(VIRTUAL_HOST);
        connectionFactory.setUsername(USERNAME);
        connectionFactory.setPassword(PASSWORD);
        return connectionFactory;
    }
}

有没有办法告诉Rabbit客户端关闭,理想情况是所有邮件都被排队后?

1 个答案:

答案 0 :(得分:3)

如果你让Spring管理bean,你可以在完成后close()应用程序上下文。

现在配置它的方式(没有Spring上下文),您可以在连接工厂上调用destroy(),一切都将关闭。

对这样的东西使用静态方法是一种反模式;您需要将工厂存储在静态字段中,以便销毁模板正在使用的工厂。

您需要确认回叫以确认兔子收到了发送。