RabbitMQ订阅者超时

时间:2012-06-28 13:22:30

标签: java messaging rabbitmq firewall cisco

在遍历CISCO ASA 5505防火墙时订阅RabbitMQ消息时遇到问题。似乎防火墙中存在某种超时,它会关闭空闲连接并导致我的RabbitMQ订阅被静默删除。结果是我的订阅者不会抛出/显示任何异常,但不会收到已发布的消息。

public class RabbitMqSubscriber<T extends Serializable> implements Subscriber<T> {

    private QueueingConsumer consumer;
    private MessageListener<T> listener;
    private String exchange;
    private String topic;
    public RabbitMqSubscriber(String host,String exchange,String topic) throws IOException {
        this.exchange=exchange;
        this.topic=topic;
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(host);
            factory.setRequestedHeartbeat(10);
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(exchange, "topic");
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, exchange, topic);
        consumer = new QueueingConsumer(channel);
        channel.basicConsume(queueName, true, consumer);
    }

    public void run() {

        while (true) {
            QueueingConsumer.Delivery delivery;
            try {
                delivery = consumer.nextDelivery();
                Object o=SerializationUtils.deserialize(delivery.getBody());
                listener.receive((T)o);
            } catch (ShutdownSignalException | ConsumerCancelledException | InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void setListener(MessageListener<T> listener) {
        this.listener=listener;
    }

}

我也尝试将keepalive添加到服务器配置中,但这也没有帮助:

[        {rabbit, [{tcp_listen_options, [binary, 
                     {packet, raw}, 
                     {reuseaddr, true}, 
                     {backlog, 128}, 
                     {nodelay, true}, 
                     {exit_on_close, false}, 
                     {keepalive, true}]}]}]. 

3 个答案:

答案 0 :(得分:0)

尝试使用连接工厂设置连接超时:

factory.setConnectionTimeout(timeout);

答案 1 :(得分:0)

一个疯狂的猜测:防火墙具有用于具有有限存储容量的网络地址转换(NAT)条目的缓存,因此会丢弃空闲连接。如果内存资源仍然足够,则可以增加超时。 This CISCO documentation表示正常超时为24小时。

答案 2 :(得分:0)

  

防火墙中出现了某种超时,它会关闭空闲连接并导致我的RabbitMQ订阅被静默删除。

正确。在以下情况下,Cisco ASA将超时非活动TCP套接字:

  1. tcp套接字超出了ASA的idle-timeout值
  2. tcp套接字超过NAT xlate空闲超时
  3. 我比使用RabbitMQ更熟悉Cisco ASA。从我所看到的情况来看,即使你尝试配置它,看起来你在某种程度上也没有在这个会话上获得TCP keepalive。

    请尝试启用tcp keepalive的不同方法。在创建新连接之前调用setRequestedHeartbeat上的ConnectionFactory,或者ConnectionFactory子类,覆盖configureSocket方法,然后调用socket.setKeepAlive(true)