JMSReplyTo
//生产者,声明确认通道
mapMessage.setJMSReplyTo(new ActiveMQQueue("reply"));
//开启消息消费接受返回信息
//消费者
Destination des = message.getJMSReplyTo();//获取确认通道,并向通道放松消息
request/responsed模型实现
JMSCorrelationID
用于消息之间的关联,再reply返回确认消息是,可以知道是确认的哪一条消息(针对单条消息)
多条消息可以是有设置消息头,进行分组
官方例子:
http://activemq.apache.org/how-should-i-implement-request-response-with-jms.html
QueueRequestor同步消息
可以发送同步消息,本质违背了mq的异步通讯原则
源码实现
public Message request(Message message) throws JMSException {
message.setJMSReplyTo(this.getTemporaryQueue());//发送replyto,设置临时队列
this.getSender().send(message);//发送消息
return this.getReceiver().receive();//阻塞消息,等待应答
}
TemporaryQueue
异步监听,当消息过多时会创建响应的临时queue。好处:异步,坏处:考虑网络I/O瓶颈
queue browser
可以查看队列中的消息而不消费,没有订阅的功能。 (不进行ACK,不消费消息)
消息异步发送
建议使用默认,强制开启有可能丢失消息。持久化,不开启事务:同步
new ActiveMQConnectionFactory("tcp://locahost:61616?jms.useAsyncSend=true");//开启异步##
消息缓冲,消息积压
在消费者接受broker推过来的消息时有一个缓冲区,当prefetchsize满的时候造成消息积压。
Pre-fetch默认值
consumer type | default value |
---|---|
queue | 1000 |
queue browser | 500 |
topic | 32766 |
durable topic | 1000 |
ActiveMQConnectionFactory connectio nFactory = new ActiveMQConnectionFactory(
"admin",
"admin",
"tcp://localhost:5671?jms.prefetchPolicy.all=50"
);
当慢速消费时,prefetchSize影响消息倾斜:将消息全部拉到单个consumer中,其他消息闲置,可以将prefetchSize设置为1,每次取一条
消息推拉
发送消息时是推向broker
获取消息时:
- 默认是一条一条的推
- 当customer的prefetchSize满的时候停止推消息
- 当customer的prefetchSize ==0时 拉取消息
异步消息确认
发送消息后异步监听确认消息,并不同步等待。发送到broker后,推拉消息到c等操作。在空闲时期将确认消息返回。如异常时做消息补发,或可以做消息重发
ActiveMQMessageProducer producer = (ActiveMQMessageProducer)session.createProducer(des);
producer.send(mapMessage, new AsyncCallback() {
@Override
public void onSuccess() {
//发送消息后进行计数
countDownLatch.countDown();;
}
@Override
public void onException(JMSException e) {
//异常返回
e.printStackTrace();
}
});
topic增强,可追溯消息
避免topic下错过消息
官方文档位置:http://activemq.apache.org/retroactive-consumer.html
消费者设置,注意与配置文件中配置的topic名称一致
Destination topic = session.createTopic("tpk?consumer.retroactive=true");
<policyEntry topic="tpk">//activemq.xml增加entry,topic里面是topic名称
<subscriptionRecoveryPolicy>
<fixedCountSubscriptionRecoveryPolicy maximumSize="100"/>
</subscriptionRecoveryPolicy>
</policyEntry>
自动档造成消息丢失/手动档导致乱序
自动档位,消费端异常后,仍会ack造成消息丢失无法复原,可以开启事务或者手动ack,避免brocker把消息自动确认消除。(自动档位,receive()方法接收到消息立即确认,listenMessage()监听事件方法执行完毕后进行确认)
手动档位,出现异常后broker长时间未收到consumer的确认信息。connection断开,重新推送给其他的consumer,所以有可能会导致消费顺序错乱
嵌入Hawtio
官方网站
https://hawt.io/
独立jar包的形式运行
java -jar
嵌入ActiveMQ
下载war包,复制到mq的webapps目录下,修改war包名称为hawtio.war
jetty.xml中添加
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/hawtio" />
<property name="war" value="${activemq.home}/webapps/hawtio.war" />
<property name="logUrlOnStart" value="true" />
</bean>
//注意在
<bean id="secHandlerCollection" class="org.eclipse.jetty.server.handler.HandlerCollection">
<property name="handlers">
<list>
<ref bean="rewriteHandler"/>
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/admin" />
<property name="resourceBase" value="${activemq.home}/webapps/admin" />
<property name="logUrlOnStart" value="true" />
</bean>
<bean class="org.eclipse.jetty.webapp.WebAppContext">
<property name="contextPath" value="/api" />
<property name="resourceBase" value="${activemq.home}/webapps/api" />
<property name="logUrlOnStart" value="true" />
</bean>
这下面加
ActiveMQ.bat下添加
(注意是根目录/bin下的,不要再进别的!)
if "%ACTIVEMQ_OPTS%" == "" set ACTIVEMQ_OPTS=-Xms1G -Xmx1G -Dhawtio.realm=activemq -Dhawtio.role=admins -Dhawtio.rolePrincipalClasses=org.apache.activemq.jaas.GroupPrincipal -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config="%ACTIVEMQ_CONF%\login.config"
//删除原有的ACTIVEMQ_OPTS
运行
注意运行,注意是根目录/bin下的,activemq.bat。需要通过命令行启动!
cd到根目录/bin/ 下,activemq start
访问
localhost:8161/hawtio