ActiveMQ 故障转移传输 - 为啥有这么多连接?

Posted

技术标签:

【中文标题】ActiveMQ 故障转移传输 - 为啥有这么多连接?【英文标题】:ActiveMQ failover transport - Why so many connections?ActiveMQ 故障转移传输 - 为什么有这么多连接? 【发布时间】:2015-02-27 06:09:09 【问题描述】:

我们在代理网络中设置了 4 个 ActiveMQ 代理(每个都在单独的服务器上运行)。大约有60个生产者。生产者使用 JDNI 从 Glassfish 中查找 ActiveMQ 连接工厂。

Glassfish中配置的ActiveMQ URI如下:

failover:(tcp://phxgapm01:61616,tcp://phxgapm02:61616,tcp://phxgapm03:61616,tcp://phxgapm04:61616)?randomize=true&backup=false&maxReconnectAttempts=8

每个生产者进程都会对 javax.jms.ConnectionFactory 进行 JNDI 查找,然后创建 1 个 javax.jms.Connection。当生产者运行时,它会定期创建 javax.jms.Session 和 javax.jms.MessageProducer,将一些消息发送到队列,然后关闭 Session 和 MessageProducer。

这就是所有背景 - 现在是我的问题。从一些(但不是所有)生产者那里,我们会看到如下日志输出流:

2014-12-30 21:07:06,534 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm03:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,538 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm04:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,544 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm02:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,548 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm04:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,552 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm01:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,556 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm02:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,561 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm02:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,565 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm01:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,568 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm02:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,572 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm04:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,577 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm03:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,581 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm04:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,586 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm01:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,590 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm03:61616 - [ActiveMQ Task-1]
2014-12-30 21:07:06,594 INFO  FailoverTransport    - Successfully connected to tcp://phxgapm04:61616 - [ActiveMQ Task-1]

对于某些生产者,我们会每 10 分钟看到一次此输出 - 对于其他生产者来说,频率较低。更令人困惑的是,所有这些生产者都对 JMS 消息传递使用相同的代码 - 因此,虽然生产者创建会话和消息生产者的频率可能不同,但它们都使用相同的代码并且都只创建 1 个连接对象。

通过阅读文档,我的理解是故障转移传输将打开与 1 个代理的连接(在我们的例子中是随机选择的)。为什么我们会看到这种连接流(60 毫秒内到每个代理的多个连接)?使用 netstat 我们可以看到这些连接。这是正常的吗?如果没有,关于可能导致此问题的任何建议?

【问题讨论】:

代码是直接使用 JMS 还是 JMSTemplate 等。示例很有帮助。是否正在使用 PooledConnectionFactory。 它是直接的 JMS - 没有使用 PooledConnectionFactory(至少不是直接使用) 如果有XA Connection Factory那么你需要使用PooledConnectionFactory,否则它会一直断开/重新连接。您可以在其中一个管理主题中看到连接数增长(不记得是哪一个) 如果不是idleTimeout,防火墙呢? 你应该在 amq 中打开调试日志 【参考方案1】:

在没有提高 activeMQ 日志级别的情况下,还有一些猜测的余地,但是:

“对于其他人来说,它不那么频繁” - 在这种情况下观察不同实例的不同行为是完全自然的。如果负载没有在实例之间完美分布,那么它们在消息传递方面的行为会有所不同。想象一下,您的一个节点接收 90% 的触发输入并独自完成大部分工作。该节点将承受更高的负载,并且使用其 JMS 资源的方式与其他节点完全不同。 “我的理解是故障转移传输会打开与 1 个代理的连接” - 这是完全正确的。仅当包装 connectionFactory 请求打开新的物理连接时,故障转移才会起作用。在这种情况下,只会为该请求创建一个连接。 “为什么我们会看到这种连接流” - 我很确定这是由于您的项目中有一个池实现。您可以看到所有代理都建立了这些连接(随机分布),表明同时有多个新连接请求。

通过增加应用程序中的日志级别,您将能够准确地看到哪个层启动了此操作以及出于什么原因。可能的原因是:“所有连接都已过期,池将 minIdleConnection 计数恢复到最小值”; “您的应用程序中的某些传入请求需要一次发送大量消息,因此您的池会创建它们”。

【讨论】:

以上是关于ActiveMQ 故障转移传输 - 为啥有这么多连接?的主要内容,如果未能解决你的问题,请参考以下文章

Mule JMS ActiveMQ 传输失败到故障转移

ActiveMQ 经典到 ActiveMQ Artemis 故障转移不起作用

Activemq 宕机解决方案

ActiveMQ 主从故障转移丢失消息

ActiveMQ NMS:当代理关闭时,connection.start() 使用故障转移协议挂起

ActiveMQ-cpp:尽管发生故障转移,但连接丢失