ActiveMQ问题与调优

使用ActiveMq的问题。

javax.jms.InvalidClientIDException: Broker: localhost - Client: client-id

2020-05-13 08:58:53,108 | WARN | Failed to add Connection id=ID:host04-36868-1589330662649-3:7467, clientId=1589290606450 due to {} 
| org.apache.activemq.broker.TransportConnection | qtp1879414521-27691
javax.jms.InvalidClientIDException: Broker: localhost - Client: 1589290606450 already connected from ws://127.0.0.1:48030
at org.apache.activemq.broker.region.RegionBroker.addConnection(RegionBroker.java:247)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.broker.jmx.ManagedRegionBroker.addConnection(ManagedRegionBroker.java:227)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.advisory.AdvisoryBroker.addConnection(AdvisoryBroker.java:119)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)[activemq-broker-5.15.9.jar:5.15.9]
at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)[activemq-broker-5.15.9.jar:5.15.9]

分析源码(org.apache.activemq.broker.region.RegionBroker.addConnection)可知这个原因是由于客户端的client-id重复,也就是盗链,但是我们没有允许。

    synchronized (this.clientIdSet) {
      oldContext = this.clientIdSet.get(clientId);
      if (oldContext != null) {
        if (context.isAllowLinkStealing()) {
          this.clientIdSet.put(clientId, context);
        } else {
          throw new InvalidClientIDException("Broker: " + getBrokerName() + " - Client: " + clientId + " already connected from " + oldContext
              .getConnection().getRemoteAddress());
        } 
      } else {
        this.clientIdSet.put(clientId, context);
      } 
    }

解决方式:

  1. 保证客户端的id不重复
    目前前端使用stomp连接时,采用了时间戳作为client-id:如果同时有2个用户连接,会出现冲突的问题
CONNECT
login:xxx
passcode:xxx
client-id:1589422159863
accept-version:1.1,1.0
heart-beat:10000,10000
  1. 允许盗链,修改mq配置:
<transportConnector  name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;allowLinkStealing=true"/>

java.lang.OutOfMemoryError: GC overhead limit exceeded

内存溢出是个很常见的问题,下面的问题是由于回收频繁却效果甚微。

2020-05-13 21:11:38,495 | WARN  | Transport Connection to: tcp://59.151.65.101:40204 failed: java.io.IOException: Unexpected error occurred: java.lang.OutOfMemoryError: GC overhead limit exceeded 
| org.apache.activemq.broker.TransportConnection.Transport | ActiveMQ Transport: tcp:///59.151.65.101:40204@61616

默认,activemq的jvm配置是最大1G内存, 根据/bin/activemq启动脚本可以知道:

# System variables for this script, like ACTIVEMQ_OPTS and ACTIVEMQ_OPTS_MEMORY,
# can be configured in 'env' script located in this directory.

/bin/env里可以看到配置:所以修改这里就行

# Set jvm memory configuration (minimal/maximum amount of memory)
ACTIVEMQ_OPTS_MEMORY="-Xms64M -Xmx1G"

if [ -z "$ACTIVEMQ_OPTS" ] ; then
    ACTIVEMQ_OPTS="$ACTIVEMQ_OPTS_MEMORY -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=$ACTIVEMQ_CONF/login.config"
fi

优化配置

定时移除过期的队列

修改conf/activemq.xml:

    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" useJmx="true" dataDirectory="${activemq.data}"  schedulePeriodForDestinationPurge="60000">

        <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry topic=">" >
                  <pendingMessageLimitStrategy>
                    <constantPendingMessageLimitStrategy limit="1000"/>
                  </pendingMessageLimitStrategy>
                </policyEntry>
				<policyEntry queue=">" gcInactiveDestinations="true" inactiveTimeoutBeforeGC="30000"/>
              </policyEntries>
            </policyMap>
        </destinationPolicy>
...

上面配置的是:每60秒清理一次,清理过期30秒的的队列。

这个修改:可以让管理界面流畅;也能缓解内存溢出问题

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值