ActiveMQ学习笔记(17)----Message高级特性(一)
1. Messaage Properties
ActiveMQ支持很多消息属性,具体可以参考
http://activemq.apache.org/activemq-message-properties.html
常见得一些属性说明:
1. queue得消息默认是持久化得
2. 消息得优先级默认是4.
3. 消息发送时设置了时间戳。
4. 消息的过期时间默认是永不过期,过期的消息进入DLQ,可以配置DLQ及其处理策略。
5. 如果消息是重发的,将会被标记出来。
6. JMSReplyTo标识响应消息发送到哪个queue.
7. JMSCorelationID标识此消息相关联的消息id,可以用这个标识把多个消息连接起来。
8. JMS同时也记录了消息重发的次数。默认是6次
9. 如果有一组相关联的消息需要处理,可以分组;只需要设置消息组的名字和这个消息的第几个消息。
10. 如果消息中一个事务环境,则TXID将会被设置。
11. 此外ActiveMQ在服务器端额外设置了消息入队和出队的时间戳。
12. ActiveMQ里消息属性的值,不仅可以用基本类型,还可以用List或Map类型
2. Advisory Message
Advisory Message是ActiveMQ自身的系统消息地址,可以监听该地址来获取activemq的系统消息。目前支持获取如下信息:
1: consumers, producers和connections的启动和停止
2. 创建和销毁temporary destinations
3. toppics 和queues 的消息过期
4. brokers发送消息给destination,但是没有consumers
5. connections启动和停止
说明:
1. 所有advisory的topic,前缀是:ActiveMQ.Advisory
2. 所有Advisory的消息类型是:‘Advisory’,所有的Advisory都有的消息属性有:originBrokerId,originBrokerName,originBrokerURL
3. 具体支持的topic和queue,请参照:
http://activemq.apache.org/advisory-message.html
Advisory功能默认是关闭的,打开Advisorie的具体实现如下:
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" advisoryForConsumed="true"/>
</policyEntries>
</policyMap>
</destinationPolicy>
开启之后启动ActiveMQ
查看控制台:
已经可以看到以ActiveMQ.Advisory为前缀的topic了,
监听ActiveMQ.Advisory.Producer.Queue.my-queue,实现如下:
package com.wangx.activemq; import com.wangx.activemq.util.MQUtil;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQMessage; import javax.jms.*; public class MessageReceiver { /**
* topic名字
*/
private static final String QUEUENAME = "ActiveMQ.Advisory.Producer.Queue.my-queue"; public void receive() throws JMSException {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
connection.start();
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//获取Session
//创建队列
Topic queue = session.createTopic(QUEUENAME);
//创建消费者
MessageConsumer messageConsumer = session.createConsumer(queue);
//监听生产者信息
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//将类型转换成ActiveMQMessage
ActiveMQMessage activeMQMessage = (ActiveMQMessage)message;
try {
//打印message
System.out.println(activeMQMessage.getMessage());
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
} public static void main(String[] args) throws JMSException {
MessageReceiver messageReceiver = new MessageReceiver();
messageReceiver.receive();
}
}
当生产者发送消息时,将会打印如下信息:
ActiveMQMessage {commandId = 0, responseRequired = false, messageId = ID:DESKTOP-A6T5N2R-57210-1541398368987-1:1:0:0:82, originalDestination = null, originalTransactionId = null, producerId = ID:DESKTOP-A6T5N2R-57210-1541398368987-1:1:0:0, destination = topic://ActiveMQ.Advisory.Producer.Queue.my-queue, transactionId = null, expiration = 0, timestamp = 0, arrival = 0, brokerInTime = 1541399457800, brokerOutTime = 1541399457800, correlationId = null, replyTo = null, persistent = false, type = Advisory, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = org.apache.activemq.util.ByteSequence@1098f4d, dataStructure = ProducerInfo {commandId = 4, responseRequired = true, producerId = ID:DESKTOP-A6T5N2R-57597-1541399457549-1:1:1:1, destination = queue://my-queue, brokerPath = null, dispatchAsync = false, windowSize = 0, sentCount = 0}, redeliveryCounter = 0, size = 0, properties = {producerCount=1, originBrokerName=localhost, originBrokerURL=tcp://DESKTOP-A6T5N2R:61616, originBrokerId=ID:DESKTOP-A6T5N2R-57210-1541398368987-0:1}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false}
ActiveMQMessage {commandId = 0, responseRequired = false, messageId = ID:DESKTOP-A6T5N2R-57210-1541398368987-1:1:0:0:83, originalDestination = null, originalTransactionId = null, producerId = ID:DESKTOP-A6T5N2R-57210-1541398368987-1:1:0:0, destination = topic://ActiveMQ.Advisory.Producer.Queue.my-queue, transactionId = null, expiration = 0, timestamp = 0, arrival = 0, brokerInTime = 1541399457890, brokerOutTime = 1541399457892, correlationId = null, replyTo = null, persistent = false, type = Advisory, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = org.apache.activemq.util.ByteSequence@1385d8ba, dataStructure = RemoveInfo {commandId = 0, responseRequired = true, objectId = ID:DESKTOP-A6T5N2R-57597-1541399457549-1:1:1:1, lastDeliveredSequenceId = -2}, redeliveryCounter = 0, size = 0, properties = {producerCount=0, originBrokerName=localhost, originBrokerURL=tcp://DESKTOP-A6T5N2R:61616, originBrokerId=ID:DESKTOP-A6T5N2R-57210-1541398368987-0:1}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false}
总结Advisory的使用方式:
1. 要在配置文件里面开启Advisories.
2. 消息发送端没什么变化,不做多余改变或配置,
3. 消息接收端:
1)根据你要接收的消息类型,来设置不同的topic,当然也可以使用AdvisorySupport这个类来辅助创建,比如你想要得到消息生产者的信息,你可以:
Topic queue = session.createTopic(QUEUENAME);
Destination destination = AdvisorySupport.getProducerAdvisoryTopic(queue);
2)由于这个topic默认不是持久化的,所有要先看起接收端,然后再发送消息。
3) 接收消息的时候,接收到的消息类型是ActiveMQMessage,所以需要先转换成ActiveMQMessage,然后再通过getDataStructure方法来得到具体的信息对象。
代码如下:
//将类型转换成ActiveMQMessage
ActiveMQMessage activeMQMessage = (ActiveMQMessage)message;
try {
//打印message
System.out.println(activeMQMessage.getDataStructure());
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
这样可以可以拿到相关信息,
控制台如下:
ProducerInfo {commandId = 4, responseRequired = true, producerId = ID:DESKTOP-A6T5N2R-58264-1541401841935-1:1:1:1, destination = queue://my-queue, brokerPath = null, dispatchAsync = false, windowSize = 0, sentCount = 0}
RemoveInfo {commandId = 0, responseRequired = true, objectId = ID:DESKTOP-A6T5N2R-58264-1541401841935-1:1:1:1, lastDeliveredSequenceId = -2}
2. 延迟和定时消息投递
延迟和定时消息传递(Delay and schedule Message Delivery)
有时候我们不希望消息马上被broker投递出去,而是想要消息60s以后发送给消费者,或者是我们想要让消息每隔一段时间投递一次,一共投递指定的次数。。。类似这种需求,ActiveMQ提供了一种broker端消息定时调度机制。
我们只需要把几个描述消息定时调度的方式参数作为属性添加到消息,broker端的调度器酒睡按照我们想要的行为去处理消息。当然需要再xml中配置schedulerSupport属性为true,
一共四个属性
AMQ_SCHEDULED_DELAY: 延迟投递的时间
AMQ_SCHEDULED_PERIOD: 重复投递的时间间隔
AMQ_SCHEDULED_REPEAT:重复投递次数
AMQ_SCHEDULED_CRON: Cron表达式
ActiveMQ也提供了一个封装的消息类型:org.apache.activemq.ScheduledMessage,可以使用这个类来辅助设置,使用例子如下:延迟60s
在broker上设置schedulerSupport="true",然后使用如下代码设置:
TextMessage textMessage = session.createTextMessage("message" + i);
long time = 30 * 1000;
textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
这样,当生产者发送消息之后,消费者不会马上收到消息,而是会等待30s之后才会开始接收消息
延迟10s,投递3次,间隔5秒的例子
TextMessage textMessage = session.createTextMessage("message" + i);
long delay = 10 * 1000;
long period= 5 * 1000;
int repeat = 3; textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
textMessage.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
messageProducer.send(textMessage);
使用CRON表达式,每个小时发送一次
textMessage.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON,"0 * * * *");
CRON表达式的优先级高于另外三个参数,如果在设置了延时时间,也有repeat和period参数,则会在每次CRON执行的时候,重复投递repeat次,每次间隔period,就是说设置的是叠加效果,例如每小时都会发生消息被投递10次,延迟0秒开始,每次间隔1秒。
ActiveMQ学习笔记(17)----Message高级特性(一)的更多相关文章
- Python 学习笔记 之 02 - 高级特性总结
切片 语法: li.[x:y:z] li为list.tuple等数据类型,x为开始进行切片的位置,y为切片停止的位置(不包含y),z为xy切片后的结果里,每间隔z个元素输出一次结果. x默认为0 ...
- ActiveMQ学习笔记(5)——使用Spring JMS收发消息
摘要 ActiveMQ学习笔记(四)http://my.oschina.net/xiaoxishan/blog/380446 中记录了如何使用原生的方式从ActiveMQ中收发消息.可以看出,每次 ...
- 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性
基于.net的分布式系统限流组件 在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...
- Ext.Net学习笔记17:Ext.Net GridPanel Selection
Ext.Net学习笔记17:Ext.Net GridPanel Selection 接下来是Ext.Net的GridPanel的另外一个功能:选择. 我们在GridPanel最开始的用法中已经见识过如 ...
- SQL反模式学习笔记17 全文搜索
目标:全文搜索 使用SQL搜索关键字,同时保证快速和精确,依旧是相当地困难. SQL的一个基本原理(以及SQL所继承的关系原理)就是一列中的单个数据是原子性的. 反模式:模式匹配 使用Like 或者正 ...
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- C++ 学习笔记(一些新特性总结3)
C++ 学习笔记(一些新特性总结3) public.protected 和 private 继承 public 继承时,基类的存取限制是不变的. class MyClass { public: // ...
- ActiveMQ学习笔记(18)----Message高级特性(二)
1. Blob Message 有些时候,我们需要传递Blob(Binary Large Objects)消息,在5.14之前,(5.12和5.13需要在jetty.xml中手动开启)可以按照如下的方 ...
- ActiveMQ学习笔记(19)----Consumer高级特性(一)
1. Exclusive Consumer 独有消费者:Queue中的消息是按照顺序被分发到consumer的,然而,当你有多个consumers同时从相同的queue中提取消息时,你将失去这个保证. ...
- Message高级特性 & 内嵌Jetty实现文件服务器
1. Messaage Properties 常见属性 更多的属性以及介绍参考:http://activemq.apache.org/activemq-message-properties.html ...
随机推荐
- 结构化编程-Structured programming
结构话编程强调的是对流程的控制: 它为面向过程编程提供天然的支持. Structured programming is a programming paradigm aimed at improvin ...
- 深入分析C++虚函数表
C++中的虚函数(Virtual Function)是用来实现动态多态性的,指的是当基类指针指向其派生类实例时,可以用基类指针调用派生类中的成员函数.如果基类指针指向不同的派生类,则它调用同一个函数就 ...
- RabbitMQ学习笔记(3)----RabbitMQ Worker的使用
1. Woker队列结构图 这里表示一个生产者生产了消息发送到队列中,但是确有两个消费者在消费同一个队列中的消息. 2. 创建一个生产者 Producer如下: package com.wangx.r ...
- Python 进行网络编程
Date: 2019-06-10 Author: Sun 1. Python TCP通信实现 socket()函数 Python 中,我们用 socket()函数来创建套接字,语法格式如下: sock ...
- Qwiklab'实验-Hadoop, IoT, IAM, Key Management'
title: AWS之Qwiklab subtitle: 1. Qwiklab'实验-Hadoop, IoT, IAM, Key Management Service' date: 2018-09-1 ...
- Kz.layedit-layui.layedit富文本编辑器拓展
项目介绍 首先欢迎使用 Kz.layedit!本项目基于layui.layedit富文本编辑器,在其之上拓展而来. 新增功能 html源码模式.插入hr水平线.段落格式.字体颜色.字体背景色.批量上传 ...
- 【HiJ1m】在NOIP2017前写过的有用的东西汇总
http://www.cnblogs.com/Elfish/p/7544623.html 高级树状数组 http://www.cnblogs.com/Elfish/p/7554420.html BST ...
- POJ 3122 Pie( 二分搜索 )
链接:传送门 题意:一个小朋友开生日派对邀请了 F 个朋友,排队上有 N 个 底面半径为 ri ,高度为 1 的派,这 F 个朋友非常不友好,非得"平分"这些派,每个人都不想拿到若 ...
- 一般树--common tree
参照libyang中的lyd_tree的组织结构,写了一套通用树接口. github 的地址:https://github.com/HellsingAshen/mytc/tree/master/tc_ ...
- hadoop中HDFS文件系统 nameNode出现的问题 nameNode无法打开
1,修改core-site.xml文件,先改成localhost,将所有进程关闭stop-all.sh(或者是先关闭所有进程,然后再修改文件),然后重启,在修改core-site.xml文件成ip地址 ...