一旦自动删除,生产者程序将不会在 Artemis 中重新创建地址
Producer program will not recreate an address in Artemis once automatically deleted
现在我设法获得了要自动删除的地址(基于 ),我无法弄清楚是什么阻止了我的制作人重新创建地址。
当没有生产者将数据推送到特定地址时,我需要它自动删除。现在,当最后一个消费者断开连接时,地址将被删除,生产者将不会重新创建地址。
以下是生产者代码。它只是一个简单的 Java 函数,它从 XML 消息中读取一个值并将其用作地址名称。它基本上是根据 XML 消息本身中的名称将消息分类为不同的主题:
/////////////////////////////////////
//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) ic.lookup("ConnectionFactory");
this.connection = (ActiveMQConnection) connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/////////////////////////////////////
//Switch address to publish to
/////////////////////////////////////
public void useAddress(String addressName) throws JMSException, NamingException{
if (producer != null) producer.close();
this.address= (Destination) ic.lookup("dynamicTopics/"+addressName);
this.producer = session.createProducer(address);
}
只有重启producer程序或者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>
编辑:
因此,仅通过 Artemis 中的设置确实没有一种简单的方法可以做到这一点。根据贾斯汀在下面的回答,我认为满足我需要的最佳解决方案是关闭自动删除设置并通过 java 编程来实现,使用类似于我阅读的其他 的东西可用地址,并删除不再相关的地址。
目前暂时用<auto-delete-address-delay>
设置一个长延时可以满足我目前的需要。
我认为这是目前未涉及的边缘情况。
当您创建命名生产者(例如使用 javax.jms.Session.createProducer(Destination)
) or send a message to a destination with an anonymous producer (e.g. using javax.jms.MessageProducer.send(Destination, Message)
)时,客户端会检查目标是否存在。如果目的地不存在,如果正确的 auto-create 设置为 true
,则客户端将创建它。然后客户端缓存此信息,这样它就不必在每次向相关目的地发送消息时都进行检查,因为每次检查都非常耗时。当然,不检查意味着目的地可能会消失,而客户端不会知道。
当您重新启动应用程序并再次创建生产者时,地址将变为 re-created。
不清楚为什么您需要在没有生产者主动向其推送消息时删除该地址。一般来说,我会说你的 use-case 不适合 auto-delete。 Auto-delete 实际上是为涉及 single-use 或临时目的地的 use-case 设计的。内存中的地址定义占用的资源很少,所以一般来说留着就好了。我建议您暂时禁用 auto-delete(默认情况下)以缓解此问题。
现在我设法获得了要自动删除的地址(基于
当没有生产者将数据推送到特定地址时,我需要它自动删除。现在,当最后一个消费者断开连接时,地址将被删除,生产者将不会重新创建地址。
以下是生产者代码。它只是一个简单的 Java 函数,它从 XML 消息中读取一个值并将其用作地址名称。它基本上是根据 XML 消息本身中的名称将消息分类为不同的主题:
/////////////////////////////////////
//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) ic.lookup("ConnectionFactory");
this.connection = (ActiveMQConnection) connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
/////////////////////////////////////
//Switch address to publish to
/////////////////////////////////////
public void useAddress(String addressName) throws JMSException, NamingException{
if (producer != null) producer.close();
this.address= (Destination) ic.lookup("dynamicTopics/"+addressName);
this.producer = session.createProducer(address);
}
只有重启producer程序或者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>
编辑:
因此,仅通过 Artemis 中的设置确实没有一种简单的方法可以做到这一点。根据贾斯汀在下面的回答,我认为满足我需要的最佳解决方案是关闭自动删除设置并通过 java 编程来实现,使用类似于我阅读的其他
目前暂时用<auto-delete-address-delay>
设置一个长延时可以满足我目前的需要。
我认为这是目前未涉及的边缘情况。
当您创建命名生产者(例如使用 javax.jms.Session.createProducer(Destination)
) or send a message to a destination with an anonymous producer (e.g. using javax.jms.MessageProducer.send(Destination, Message)
)时,客户端会检查目标是否存在。如果目的地不存在,如果正确的 auto-create 设置为 true
,则客户端将创建它。然后客户端缓存此信息,这样它就不必在每次向相关目的地发送消息时都进行检查,因为每次检查都非常耗时。当然,不检查意味着目的地可能会消失,而客户端不会知道。
当您重新启动应用程序并再次创建生产者时,地址将变为 re-created。
不清楚为什么您需要在没有生产者主动向其推送消息时删除该地址。一般来说,我会说你的 use-case 不适合 auto-delete。 Auto-delete 实际上是为涉及 single-use 或临时目的地的 use-case 设计的。内存中的地址定义占用的资源很少,所以一般来说留着就好了。我建议您暂时禁用 auto-delete(默认情况下)以缓解此问题。