自动删除地址在 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-addresses
为 true
时,代理将通过创建根据消息发送位置命名的地址进行响应。但是,由于 JMS 主题没有消费者,消息将被简单地丢弃。这符合基本的 publish/subscribe 语义。
此时不会删除该地址,因为代理知道从未在其上创建过任何消费者,因此实际上并未实际使用过该地址。如果经纪人在这种情况下要删除该地址,那么当另一条消息发送给它时,它必须立即 re-create 它。随着消息被发送到它浪费宝贵的资源,它最终会一遍又一遍地创建和删除地址。经纪人通过等到在地址上至少创建了一个消费者后再删除它(即一旦消费者断开连接)来避免这种病态情况。
您的地址看起来与 Web 控制台中的“ExpiryQueue”和“DLQ”地址不同的原因是这两个地址上有队列。您的地址和“activemq.notifications”地址都没有队列。
如果您不清楚地址和队列之间的关系,可以在 the documentation 中阅读更多内容。
我在让 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-addresses
为 true
时,代理将通过创建根据消息发送位置命名的地址进行响应。但是,由于 JMS 主题没有消费者,消息将被简单地丢弃。这符合基本的 publish/subscribe 语义。
此时不会删除该地址,因为代理知道从未在其上创建过任何消费者,因此实际上并未实际使用过该地址。如果经纪人在这种情况下要删除该地址,那么当另一条消息发送给它时,它必须立即 re-create 它。随着消息被发送到它浪费宝贵的资源,它最终会一遍又一遍地创建和删除地址。经纪人通过等到在地址上至少创建了一个消费者后再删除它(即一旦消费者断开连接)来避免这种病态情况。
您的地址看起来与 Web 控制台中的“ExpiryQueue”和“DLQ”地址不同的原因是这两个地址上有队列。您的地址和“activemq.notifications”地址都没有队列。
如果您不清楚地址和队列之间的关系,可以在 the documentation 中阅读更多内容。