ActiveMQ生产环境调优

ActiveMQ简介

   MQ是消息中间件,是一种在分布式系统中应用程序借以传递消息的媒介,常用的有ActiveMQ,RabbitMQ,kafka。ActiveMQ是Apache下的开源项目,完全支持JMS1.1和J2EE1.4规范的JMS Provider实现。消息类型包括点对点(queue),一对多(topic),本次生产环境用的是queue。


1、部署环境 

  三个ActiveMQ实例+MySQL数据数据库持久化,三台ActiveMQ采用failover方式,MQ数据持久化在MySQL数据库中,MySQL采用主备方式,该架构保证数据高可用性。目前线上压测TPS为1200,满足实际生产需求。

 实际TPS到2、3千没问题。

2、Producer优化

  采用spring+activemq实现,采用PooledConnectionFactory连接池,用于缓存session和producter,在高并发情况下不要采用CachingConnectionFactory,CachingConnectionFactory共享一个connection,TPS上不去。

   对发送TPS有直接影响的参数如下

      1.ActiveMQConnectionFactory调优
     connectionFactory.setUseAsyncSend(activeMqProperties.isAsyncSend());   // 同步\异步发送消息,如果是异步需要设置 connectionFactory.setProducerWindowSize(10240);
     connectionFactory.setMaxThreadPoolSize(activeMqProperties.getMaxThreadPoolSize());   // session线程池

        2.PooledConnectionFactory调优
     pooledConnectionFactory.setMaxConnections(10);  // 最大connection数量,和生产者TPS直接相关
        pooledConnectionFactory.setMaximumActiveSessionPerConnection(5); // 每个connection的最大session数

 

3、consumer优化

  对消费TPS有直接影响的参数如下

  ActiveMQ生产环境调优

          asyncSend=true  //设置为true,异步方式,如果是false和生产者有关系,严重影响消费TPS
         queuePrefetch=1 // 实际测试为1效率高,设置比较大时,严重影响消费TPS

        concurrentConsumers=100 // 消费者线程总量,和消费TPS直接相关

 

4、MQ数据持久化数据库配置 

      <bean id="mysql-ds" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
            <property name="driverClassName" value="com.mysql.jdbc.Driver" />
            <property name="url" value="jdbc:mysql://localhost:3306/activemq?characterEncoding=utf-8&amp;relaxAutoCommit=true" />
            <property name="username" value="root" />
            <property name="password" value="123" />
            <property name="initialSize" value="100" />
            <property name="maxTotal" value="500" />
            <property name="maxIdle" value="30" />
            <property name="maxWaitMillis" value="10000" />
            <property name="minIdle" value="1" />
            <property name="poolPreparedStatements" value="true"/>
            <property name="connectionProperties" value="connectTimeout=60000;socketTimeout=60000"/>    // 特别注意,当数据库发生主从切换时,需要断开数据库链接,不然会卡死当前主MQ实例
        </bean>

 特别注意:

对于mq在mysql发生主从切换时卡死20分钟问题的解决方案如下
1.运维写了个脚本监控,当数据库主服务宕机后,监控3306端口连接情况,当3306端口没有连接后在漂移到从数据库
  经过验证,大概20s mq恢复正常工作,不丢弃数据;
2.mq配置文件配置jdbc连接时加上connectTimeout=60000;socketTimeout=60000,当数据库主宕机后,1分钟左右mq恢复正常工作,不丢弃数据;
PS:当mysql主服务实例挂了,方案1起作用;如果mysql主服务器重启这种机器故障,方案2起作用。