Performance 非常大的ActiveMQ部署性能问题

Performance 非常大的ActiveMQ部署性能问题,performance,activemq,message-queue,spring-jms,Performance,Activemq,Message Queue,Spring Jms,我们计划部署一个ActiveMQ服务器场,该服务器场能够跨多台服务器支持400多万个并发连接。我们没有基于我们的设计使用集群。客户机使用MQTT进行连接,订阅/使用他们自己的主题,并发布到共享虚拟主题。我们正在考虑每台服务器100k连接和20k msg/s。我还远没有达到这个数字。我已经成功地连接了这个数量,但是它的吞吐量正在伤害我 为了进行测试,我使用了一个基于FuseSource MQTT客户机异步(回调而非未来)版本的多线程客户机。使用该客户机,我能够在系统上施加足够大的负载,从而可以看到

我们计划部署一个ActiveMQ服务器场,该服务器场能够跨多台服务器支持400多万个并发连接。我们没有基于我们的设计使用集群。客户机使用MQTT进行连接,订阅/使用他们自己的主题,并发布到共享虚拟主题。我们正在考虑每台服务器100k连接和20k msg/s。我还远没有达到这个数字。我已经成功地连接了这个数量,但是它的吞吐量正在伤害我

为了进行测试,我使用了一个基于FuseSource MQTT客户机异步(回调而非未来)版本的多线程客户机。使用该客户机,我能够在系统上施加足够大的负载,从而可以看到队列积压。我使用“java-jar-activemq-all-5.13.0.jar-dstat”获取队列积压

我在很多方面对服务器进行了调整,但未能充分利用所有资源。Iostat显示低%util,顶部显示可用cpu资源

我的服务器运行在AWS m3.2xlarge(8vCPU,30G ram)上

我用“java–Xms12G–Xmx20G–jar…”启动activemq

以下是我如何开始我的经纪人。请注意,我已经改变了许多设置,但它们似乎并不重要

@Bean
public BrokerService getBrokerService() throws Exception {
    String hostname= InetAddress.getLocalHost().getHostName();

    // Create broker
    BrokerService broker = new BrokerService();
    broker.setBrokerName("ActiveMQ"+hostname);
    broker.setUseShutdownHook(true);
    broker.setAdvisorySupport( false );
    broker.setUseJmx(true);
    broker.setDeleteAllMessagesOnStartup( true );
    broker.setPopulateJMSXUserID( true );
    broker.setPopulateUserNameInMBeans( true );
    broker.setUseAuthenticatedPrincipalForJMSXUserID( true );
    broker.setUseVirtualTopics( true );

    // I have altered these but they don't seem to change anything.
    broker.setDedicatedTaskRunner( true );
    broker.setEnableStatistics( true );
    broker.setStartAsync( true );

    // Enable JMX bean
    final ManagementContext managementContext = new ManagementContext();
    managementContext.setCreateConnector(true);
    broker.setManagementContext( managementContext );        

    // Enable LevelDB
    broker.setPersistent( true );
    File dataFileDir = new File("/activemq/data/leveldb);
    LevelDBStore adapter = new LevelDBStore();
    adapter.setDirectory(dataFileDir);
    broker.setPersistenceAdapter(adapter);

    // Turn flow control off
    PolicyEntry policy = new PolicyEntry();
    policy.setOptimizedDispatch( true );
    policy.setProducerFlowControl( false );
    policy.setGcInactiveDestinations( true );
    DispatchPolicy dp = new RoundRobinDispatchPolicy();
    policy.setDispatchPolicy( dp );
    PolicyMap policyMap = new PolicyMap();
    policyMap.setDefaultEntry( policy );
    broker.setDestinationPolicy( policyMap );

     // Set system usage
    SystemUsage memoryManager = new SystemUsage();
    MemoryUsage memoryUsage = new MemoryUsage();
    memoryUsage.setPercentOfJvmHeap( 75 );
    memoryManager.setMemoryUsage( memoryUsage );

    StoreUsage storeUsage = new StoreUsage();
    storeUsage.setLimit( 100*ONE_GB );
    memoryManager.setStoreUsage( storeUsage );

    TempUsage tempDiskUsage = new TempUsage();
    tempDiskUsage.setLimit( 100*ONE_GB );
    memoryManager.setTempUsage( tempDiskUsage );
    broker.setSystemUsage( memoryManager );

    // Add transports
    TransportConnector openwireconnector = new TransportConnector();
    openwireconnector.setName( "openwire" );
    openwireconnector.setUri(new URI("tcp://0.0.0.0:61616"));
    broker.addConnector(openwireconnector);

    TransportConnector mqttnioconnector = new TransportConnector();
    mqttnioconnector.setName( "mqtt+nio" );
    mqttnioconnector.setUri(new URI("mqtt+nio://0.0.0.0:1883"));
    broker.addConnector(mqttnioconnector);

    TransportConnector wsconnector = new TransportConnector();
    wsconnector.setName( "ws" );
    wsconnector.setUri(new URI("ws://0.0.0.0:61614"));
    broker.addConnector(wsconnector);

    // Start
    broker.start();
    broker.waitUntilStarted();
   return broker;
   }
}
我正在连接到ActiveMQ的另一台服务器中使用SpringJMS侦听器

@Component
public class MqttMessageListener {
    @JmsListener(destination = "Consumer.A.VirtualTopic.Message")
    public void processMessage(BytesMessage bytesMessage) {
     // I consume and discard here just for testing.  No work is being done to isolate issue.    
    }
}

@Configuration
@EnableJms
public class AppConfig {
    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
       DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setConcurrency(“3-10”);  // I have tried many variation including 300-1000 although it seems to top out at 500.
    factory.setAutoStartup( true );
    return factory;
    }
}
使用上述MqttMessageListener.processMessage方法,我只能以大约15k毫秒/秒的速度使用。由于cpu空闲率为30%以上,磁盘/网络利用率较低,我不确定为什么不能做得更好

问题:

  • 我怎样才能找到有限的资源
  • 它们是否是确定这是ActiveMQ交付还是消费端的问题的简单方法?两者都是Spring引导应用程序

  • 很难猜测。您可能希望尝试ActiveMQ Artemis,它应该能够更好地处理高并发性(非阻塞)。