activemq调优
一.设置ConnectionFactory
1.首先CachingConnectionFactory和SingleConnectionFactory是spring提供的PooledConnectionFactory是activemq提供的
2.SingleConnectionFactory是单例的所有连接共享同一个Connection,但是session不共享,并且会忽略Connection的close方法调用.
3.CachingConnectionFactory是继承SingleConnectionFactory,所以它拥有SingleConnectionFactory的所有功能,同时它还新增了缓存功能,它可以缓存Session、MessageProducer和MessageConsumer
4.PooledConnectionFactory是activemq提供的,这个类只会缓存connection,session和productor,不会缓存consumer,activemq认为,由于消费者一般是异步的,也就是说,broker代理会把生产者发送的消息放在一个消息者的预取缓存中。当消息者准备好的时候就会从这个预取缓存中取出来进行处理。
5.消息处理的及时性不是特别高的情况下用PooledConnectionFactory,因为它不缓存consumer,如果希望处理能够提高速度,自然也可以用CachingConnectionFactory,从这部分提高效率,减小不断创建consumer的时间
二.设置prefetchSize和optimizeAcknowledge
1.optimizeAcknowledge是批量向broker确认消费消息(延迟确认),如果为false就是每消费一条消息都会去确认,为true当消费数大于prefetchSize*0.65就会批量确认消费,可以节省多次确认消费的时间,提高响应效率
但是这种机制有缺陷,如果在已经消费一部分但是还没有确认消费,这时activemq挂了,会导致消息重复消费.
不想重复消费就关闭optimizeAcknowledge,可是每次请求都会确认一下,性能较低,
prefetchSize每次给消费方推多少消息,它不仅减少了client端在获取消息时阻塞的次数和阻塞的时间,还能够大大的减少网络开支.
修改密码(后台服务端连接密码)
1.在mq服务器上的activemq.xml找到<systemUsage>,在其上方添加如下插件
<!-- set connection user authentication-->
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="${activemq.username}" password="${activemq.password}" groups="users,admins"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
2.打开**\apache-activemq\conf中credentials.properties文件进行密码设置
activemq.username=admin
activemq.password=123456
guest.password=123456
3.在springboot工程中仅需要在application.properties文件中添加一下配置即可
spring.activemq.user=admin
spring.activemq.password=123456
修改密码(前台浏览器连接密码)
1.打开**\apache-activemq\conf中jetty-realm.properties文件进行密码设置
admin: admin, admin
user: 123, user
说明:上面有两个账户,分别是admin和user.第一个admin是用户名,第二个admin是密码,第三个admin是所在是组.设置好了,就可以在浏览器验证.
持久化到数据库(Queue模式)
1.配置activemq.xml修改persistenceAdapter
<persistenceAdapter>
<!-- <kahaDB directory="${activemq.data}/kahadb"/> -->
<!-- createTablesOnStartup:default value is true; if true then every time start will create table;so first time we set it be true;others be false -->
<jdbcPersistenceAdapter dataSource="#activemq-ds" createTablesOnStartup="true" />
</persistenceAdapter>
2.在</broker>后面加上
<bean id="activemq-ds" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.17.128:3306/activemq?relaxAutoCommit=true"/>
<property name="username" value="xc"/>
<property name="password" value="root"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
持久化到数据库(Topic模式)
需要在代码中进行
客户端接受消息端(jmsListener)
//创建activeMQConnectionFactory
@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(brokerUrl);
activeMQConnectionFactory.setUserName(user);
activeMQConnectionFactory.setPassword(password);
return activeMQConnectionFactory;
}
// 创建CachingConnectionFactory
@Bean
@Primary
public CachingConnectionFactory connectionFactorys1() {
CachingConnectionFactory c = new CachingConnectionFactory();
c.setTargetConnectionFactory(activeMQConnectionFactory());
c.setSessionCacheSize(100);
c.setClientId("111");
return c;
}
// 设置topice模型的监听ConnectionFactory
@Bean(name="xc1")
@Primary
public JmsListenerContainerFactory<?> jmsListenerContainerTopic1() {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
//设置订阅/发布模式监听
bean.setPubSubDomain(true);
bean.setConnectionFactory(connectionFactorys1());
//设置可以持久化订阅
bean.setSubscriptionDurable(true);
//设置客户端ID
bean.setClientId("111");
return bean;
}
注意:这里的红色处必须设置一样,但每个监听的持久化订阅的ClientId必须不一样,否则会报错.因为他在持久化中要表示这是那个客户端.如下图,数据库显示
服务端发送消息端
@Bean(name ="jmsTemplatetopic")
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactorys1());
//可以不设置,默认是持久化
jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
//设置为订阅/发布模式
jmsTemplate.setPubSubDomain(true);
//必须开启,不然持久化设置无效
jmsTemplate.setExplicitQosEnabled(true);
return jmsTemplate;
}