自动删除地址在 ActiveMQ Artemis 中不起作用

Auto Delete Address not working in ActiveMQ Artemis

我在让 ActiveMQ Artemis 自动删除不再使用的动态地址时遇到问题。

以下摘自 broker.xml:

         <address-setting match="#">
            <dead-letter-address>DLQ</dead-letter-address>
            <expiry-address></expiry-address>
            <redelivery-delay>0</redelivery-delay>
            <expiry-delay>10</expiry-delay>
            <max-size-bytes>-1</max-size-bytes>
            <max-size-messages>-1</max-size-messages>
            <message-counter-history-day-limit>10</message-counter-history-day-limit>
            <address-full-policy>PAGE</address-full-policy>
            <auto-create-queues>true</auto-create-queues>
            <auto-create-addresses>true</auto-create-addresses>
            <auto-delete-queues>true</auto-delete-queues>
            <auto-delete-addresses>true</auto-delete-addresses>
            <auto-delete-created-queues>true</auto-delete-created-queues>
            <auto-delete-queues-message-count>-1</auto-delete-queues-message-count>
         </address-setting>

下面是创建话题的生产者代码:

    /////////////////////////////////////
    //Constructor to establish connection
    /////////////////////////////////////
    
    public ActiveMQ(String amq_url) throws JMSException, NamingException{
        jndi_env = new Hashtable<String, Object>();
        jndi_env.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
        jndi_env.put(InitialContext.PROVIDER_URL, amq_url);
        ic = new InitialContext(jndi_env);
        ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup("ConnectionFactory");
        this.connection = (ActiveMQConnection) connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
    }
    
    ///////////useTopic()///////////
    //create/select topic
    ////////////////////////////////    
    public void useTopic(String topicName) throws JMSException, NamingException{
        if (producer != null) producer.close();
        this.topic = (Destination) ic.lookup("dynamicTopics/"+topicName);
        this.producer = session.createProducer(topic);
    }

    public void closeConnection() throws JMSException{
        if (producer != null) producer.close();
        if (connection != null) connection.stop();
        if (session != null) session.close();
        if (connection != null) connection.close();
    } 

}

在 ActiveMQ Artemis 中创建地址时,它看起来与下拉列表中的其他地址不同(例如 TEST_SDCData 与 ExpiryQueue)。

我和我的同事无法弄清楚为什么在不重新启动ActiveMQ Artemis 服务器的情况下,根据上述内容无法删除该特定地址。停止创建主题的程序后,控制台显示没有消费者或生产者连接。根据 ActiveMQ Artemis Web 控制台,该主题的消息计数为 0。有什么想法吗?我觉得我没有设置需要设置的特定值。

据我所知,一切都按设计进行。让我解释一下...

当 JMS 客户端向主题发送消息并且 auto-create-addressestrue 时,代理将通过创建根据消息发送位置命名的地址进行响应。但是,由于 JMS 主题没有消费者,消息将被简单地丢弃。这符合基本的 publish/subscribe 语义。

此时不会删除该地址,因为代理知道从未在其上创建过任何消费者,因此实际上并未实际使用过该地址。如果经纪人在这种情况下要删除该地址,那么当另一条消息发送给它时,它必须立即 re-create 它。随着消息被发送到它浪费宝贵的资源,它最终会一遍又一遍地创建和删除地址。经纪人通过等到在地址上至少创建了一个消费者后再删除它(即一旦消费者断开连接)来避免这种病态情况。

您的地址看起来与 Web 控制台中的“ExpiryQueue”和“DLQ”地址不同的原因是这两个地址上有队列。您的地址和“activemq.notifications”地址都没有队列。

如果您不清楚地址和队列之间的关系,可以在 the documentation 中阅读更多内容。