activeMQ的性能
最近activeMQ搭建了一个JMS服务,功能方面没有问题。但是在测试的时候发现发送消息总是特别慢,找了很久都没有发现哪里问题了。测试方案是:用多线程发送1000条数据,只启动服务端和生产消息端,发送消息耗时30多秒。随后启动接收消息端,接收完成只耗时756ms。相关配置如下:
服务端:
<?xml version="1.0" encoding="UTF-8"?>
<!-- START SNIPPET: xbean -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core-5.4.2.xsd">
<bean id="placeholderConfig"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:init.properties</value>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
<broker start="true" useJmx="true" xmlns="http://activemq.apache.org/schema/core" brokerName="testbroker" persistent="true">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" producerFlowControl="true" memoryLimit="${broker.topic.memoryLimit}">
<pendingSubscriberPolicy>
<vmCursor />
</pendingSubscriberPolicy>
</policyEntry>
<policyEntry queue=">" producerFlowControl="true" memoryLimit="${broker.queue.memoryLimit}">
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
<networkConnectors>
<networkConnector name="netConnector" uri="multicast://default?initialReconnectDelay=100" />
<networkConnector uri="static:${broker.tcp.server.url}" name="bridge"
dynamicOnly="false" conduitSubscriptions="true"
decreaseNetworkConsumerPriority="false">
<dynamicallyIncludedDestinations>
<queue physicalName="${broker.tcp.dynamical.queueName}"/>
<topic physicalName="${broker.tcp.dynamical.topicName}"/>
</dynamicallyIncludedDestinations>
<staticallyIncludedDestinations>
<queue physicalName="${broker.tcp.statical.queueName}"/>
<topic physicalName="${broker.tcp.statical.topicName}"/>
</staticallyIncludedDestinations>
</networkConnector>
</networkConnectors>
<!-- persistenceAdapter 持久化配置-->
<!-- dataSource 配置数据库-->
<!-- createTablesOnStartup 启动时创建数据表-->
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#dataSource" createTablesOnStartup="true" useDatabaseLock="false"></jdbcPersistenceAdapter>
</persistenceAdapter>
<!--
<journalPersistenceAdapterFactory journalLogFiles="5" dataDirectory="${basedir}/target/foo" />
-->
<!-- To use a different dataSource, use the following syntax : -->
<plugins>
<易做图AuthenticationPlugin>
<!--该部分是配置发送或接受的用户名和密码,以及所处的用户组-->
<users>
<authenticationUser username="${broker.systemUser.name}" password="${broker.systemUser.password}" groups="users,admins"/>
<authenticationUser username="${broker.legpayUser.name}" password="${broker.legpayUser.password}" groups="users"/>
<authenticationUser username="${broker.libUser.name}" password="${broker.libUser.password}" groups="users"/>
</users>
</易做图AuthenticationPlugin>
<!-- use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->
<!--以下采用的是JAAS的管理机制来配置各种角色的权限
<jaasAuthenticationPlugin configuration="activemq-domain" />-->
<!-- lets configure a destination based authorization mechanism -->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<!-->表示通配符,例如USERS.>表示以USERS.开头的主题,>表示所有主题,read表示读的权限,write表示写的权限,admin表示角色组-->
<authorizationEntry queue=">" read="admins"
write="admins" admin="admins" />
<authorizationEntry queue="USERS.>"
read="users" write="users" admin="users" />
<authorizationEntry queue="GUEST.>"
read="guests" write="guests,users" admin="guests,users" />
<authorizationEntry topic=">" read="admins,users"
write="admins" admin="admins" />
<authorizationEntry topic="USERS.>"
read="users" write="users" admin="users" />
<authorizationEntry topic="GUEST.>"
read="guests" write="guests,users" admin="guests,users" />
<authorizationEntry
topic="ActiveMQ.Advisory.>" read="guests,users"
write="guests,users" admin="guests,users" />
</authorizationEntries>
<!-- let's assign roles to temporary destinations. comment this entry if we don't want any roles assigned to temp destinations -->
<tempDestinationAuthorizationEntry>
<tempDestinationAuthorizationEntry
read="tempDestinationAdmins" write="tempDestinationAdmins"
admin="tempDestinationAdmins" />
</tempDestinationAuthorizationEntry>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
<transportConnectors>
<transportConnector name="transConnector" uri="${broker.tcp.server.url}" />
</transportConnectors>
</broker>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName">
<value>${dataSource.driverClassName}</value>
</property>
<property name="url">
<value>${dataSource.url}</value>
</property>
<property name="username">
<value>${dataSource.username}</value>
</property>
<property name="password">
<value>${dataSource.password}</value>
</property>
<property name="poolPreparedStatements">
<value>${dataSource.poolPrepared}</value>
</property>
<property name="initialSize">
<value>${dataSource.initialSize}</value>
</property>
<property name="maxIdle">
<value>${dataSource.maxIdle}</value>
</property>
<property name="minIdle">
<value>${dataSource.minIdle}</value>
</property>
<property name="maxActive">
<value>${dataSource.maxActive}</value>
</property>
<property name="removeAbandoned">
<value>${dataSource.removeAbandoned}</value>
</property>
<property name="removeAbandonedTimeout">
<value>${dataSource.removeAbandonedTimeout}</value>
</property>
<property name="maxWait">
<value>${dataSource.maxWait}</value>
</property>
</bean>
</beans>
生产消息端:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:init.properties</value>
</list>
</property>
</bean>
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="${broker.tcp.local.url}"></property>
<property name="userName" value="${broker.legpayUser.name}"></property>
<property name="password" value="${broker.legpayUser.password}"></property>
<property name="useAsyncSend" value="false"></property>
</bean>
<!-- 采用TCP长连接方式, 避免每次建立短连接需要的额外工作时间 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<constructor-arg ref="connectionFactory"></constructor-arg>
</bean>
<bean id="tcpQueue" class="org.apache.activemq.command.ActiveMQQueue">
<property name="physicalName" value="${broker.tcp.local.queue}"></property>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory" ref="pooledConnectionFactory" />
</bean>
</property>
<property name="messageConverter" ref="messageConverter" />
<property name="sessionTransacted" value="false"></property>
</bean>
<!-- 消息转换 -->
<bean id="messageConverter" class="com.demo.client.SendMessageConverter" />
<!-- 消息生产 -->
<bean id="messageProducer" class="com.demo.client.MessageProducer">
<property name="template" ref="jmsTemplate" />
<property name="destination" ref="tcpQueue" />
</bean>
</beans>
大家帮忙看看发送消息为什么会这么慢,在网上看到activeMQ测试的结果基本能在3000-5000条/s的范围。 --------------------编程问答-------------------- 1000条是从哪里发往哪里啊?
多线程,是阻塞的吗?用到同步了吗? --------------------编程问答--------------------
生产消息端发到服务端,多线程不是阻塞的,是异步的。 --------------------编程问答-------------------- 你服务器什么配置?性能也会影响发送量的 --------------------编程问答--------------------
服务端、生产消息端、接收消息端、数据库都是在我本机上的。本地测试话,网络不是问题,数据存取也不会慢。测试只是1000条数据而已,内存也应该不是问题。而且接收消息的处理很快756ms就处理完了,只是发送消息的时候特别慢。 --------------------编程问答-------------------- 求高手解答。 --------------------编程问答-------------------- 以前用过一段activemq,好像不会这么慢的.应该是你发送消息时每发送一次都新建立了一次连接? --------------------编程问答-------------------- 如果是批量发送消息,当然不需要频繁建立连接的. --------------------编程问答--------------------
不是,连接的长连接
<!-- 采用TCP长连接方式, 避免每次建立短连接需要的额外工作时间 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<constructor-arg ref="connectionFactory"></constructor-arg>
</bean>
3分钟没有消息才失效。
是在网上看别人测试的结果基本能到3000-5000条/s的范围。接收的时候速度虽然不快但是也算是正常吧,发送消息就明显很慢了。 --------------------编程问答-------------------- 不知道你用的什么应用服务器,都是用的配置文件,
以前是自己写的代码,自己建立连接并进行访问.
只能找找是不是配置文件的问题了. --------------------编程问答-------------------- 不是,连接的长连接
<!-- 采用TCP长连接方式, 避免每次建立短连接需要的额外工作时间 -->
<bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory">
<constructor-arg ref="connectionFactory"></constructor-arg>
</bean>
3分钟没有消息才失效。
是在网上看别人测试的结果基本能到3000-5000条/s的范围。接收的时候速度虽然不快但是也算是正常吧,发送消息就明显很慢了。 --------------------编程问答-------------------- 同求解, 我的配置环境用jetty+spring3+activemq5.5, 只做发送,测试才50条/秒不到 --------------------编程问答-------------------- 请问你这个问题解决了吗? --------------------编程问答-------------------- 用异步发送,brokerUrl加上jms.useAsyncSend=true --------------------编程问答-------------------- 我也遇到相同的问题,发送慢,但是消费相当快。 --------------------编程问答--------------------
加上红线内的后问题解决,不过官方文档说这个可能会丢消息。
补充:Java , Java EE