我使用ActiveMQ Artemis 2.17.0,我希望避免在故障转移期间生成器中丢失消息。
通过捕获ActiveMQunblockedException
并再次发送消息来处理Artemis主动到被动切换期间的消息发布丢失。代理被配置为主动/被动HA共享存储。主动节点配置在host1
和被动节点配置在host2
中。Url为:
(tcp://host1:61616,tcp://host2:61616)?ha=true&reconnectAttempts=-1&blockOnDurableSend=false
我们使用Spring 4.2.5和CachingConnectionFactory
作为连接工厂。
我使用以下代码发送消息:
private void sendMessageInternal(final ConnectionFactory connectionFactory, final Destination queue, final String message)
throws JMSException {
try (final Connection connection = connectionFactory.createConnection();) {
connection.start();
try (final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
final MessageProducer producer = session.createProducer(queue);) {
final TextMessage textMessage = session.createTextMessage(message);
producer.send(textMessage);
}
} catch (JMSException thr) {
if (thr.getCause() instanceof ActiveMQUnBlockedException) {
// consider as fail-over disconnection, send message again.
} else {
throw thr;
}
}
}
在host1机器中,Artemis部署为master-node1。在host2机器中,Artemis作为slave-node2部署。下面是模拟故障转移的步骤
ActiveMQunblockedException
并处理以再次发送消息ActiveMQunblockedException
和消息丢失。在第3步中获得以下错误堆栈。(被杀死的node1和node2成为实时服务器)。
javax.jms.JMSException: AMQ219016: Connection failure detected. Unblocking a blocking call that will never get a response
at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:540)
at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:434)
at org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext.sessionStop(ActiveMQSessionContext.java:470)
at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.stop(ClientSessionImpl.java:1121)
at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.stop(ClientSessionImpl.java:1110)
at org.apache.activemq.artemis.jms.client.ActiveMQSession.stop(ActiveMQSession.java:1244)
at org.apache.activemq.artemis.jms.client.ActiveMQConnection.stop(ActiveMQConnection.java:339)
at org.springframework.jms.connection.SingleConnectionFactory$SharedConnectionInvocationHandler.localStop(SingleConnectionFactory.java:644)
at org.springframework.jms.connection.SingleConnectionFactory$SharedConnectionInvocationHandler.invoke(SingleConnectionFactory.java:577)
at com.sun.proxy.$Proxy5.close(Unknown Source)
at com.eu.amq.failover.test.ProducerNodeTest.sendMessageInternal(ProducerNodeTest.java:133)
at com.eu.amq.failover.test.ProducerNodeTest.sendMessage(ProducerNodeTest.java:110)
at com.eu.amq.failover.test.ProducerNodeTest.main(ProducerNodeTest.java:90)
您得到的ActiveMQunblockedException
来自Spring对javax.jms.Connection#Stop
的调用。和发送信息无关。当收到此特定异常时,重新发送消息可能会导致重复的消息。
最终,您的问题与设置BlockonDurableSend=false
直接相关。这告诉客户“开火并忘记”。换句话说,客户机不会等待代理的响应来确保消息真正成功。这种缺乏等待的情况增加了吞吐量,但降低了可靠性。
如果您真的想减少潜在的消息丢失,您有两个主要的选择。
使用CompletionListener
。这将允许您保留BlockonDurableSend=false
,但是如果发送消息时出现问题,应用程序仍然会得到通知,尽管信息将异步提供。这个特性是在JMS2中专门为这类场景添加的。有关更多细节,请参见JavaDoc。
我试图创建一个简单的redis高可用性设置与1主,1从和2哨兵。 当从故障转移到时,该设置工作正常。当恢复时,它将自己正确地注册为新的主服务器的从服务器。 但是,当作为主服务器关闭时, 不能作为主服务器返回。的日志进入循环,显示: 每个复制文档都声明: 自Redis4.0以来,当一个实例在故障转移后被提升为master时,它仍然能够与旧master的从机执行部分重新同步。 但日志似乎显示了另一种情
null 当我使用Ctrl-C停止活动服务器时,从服务器报告的而断开连接,这是正确的,但是备份服务器没有更改其状态,也没有侦听端口61617。那么我在配置中做错了什么呢? 实时服务器配置: 备份服务器配置:
我们使用MQ作为传递消息的主要路径。这是我们的制度运作不可或缺的一部分。消息代理有时会失败,所有相关的队列也会随之失败。在camel中,有没有一种方法可以启动故障切换,并在其启动时恢复到主故障切换?
我们正在设计一个解决方案,它将使用JMS使用来自IBMMQ的消息。计划是使用WASLiberty,所以JMS是首选技术。我们将创建Message-Drive bean来侦听MQ队列中的消息。 我们也在考虑WAS自由和开放自由。 这里的诀窍是,我们必须使用故障转移来实现它,这样,如果一台服务器出现故障,另一台服务器将继续自动使用MQ中的消息。比如在主动/被动机制中。 我知道需要安装MQ适配器,因为它
我正在尝试用6台机器实现一个Redis集群。我有一个由六台机器组成的流浪集群: 运行redis服务器 我编辑了上述所有服务器的/etc/redis/redis.conf文件,添加了这个 然后我在六台机器中的一台上运行了这个程序; Redis集群已启动并运行。我通过在一台机器上设置值手动检查它显示在其他机器上。 我的问题是,当我关闭或停止任何一台主机上的redis server时,整个集群都会停止运
我使用的是Apache Artemis V2.12.0,在两个VM中启动了两个broker实例 broker.xml(myhost1)[myhost2的broker.xml与此类似,只是我使用的端口是61616] 步骤2:java客户机开始向代理发送消息 步骤3:从myhost1的控制台,我看到推送到队列中的消息 步骤4:停止myhost1中的代理实例 客户端代码执行日志消息:当客户端启动时,my