ActiveMQ学习笔记-消息特性

ActiveMQ消息属性

消息属性

属性名 类型 默认值 描述
JMSDestination javax.jms.Destination 生产者set进去 发送消息目的地
JMSReplyTo javax.jms.Destination null 用户定义
JMSType String “” 用户定义
JMSDeliveryMode int DeliveryMode.PERSISTENT 消息是否要持久化
JMSPriority int 4 0-9
JMSMessageID String unique 消息唯一标示符
JMSTimestamp long 消息发送时间 毫秒
JMSCorrelationID String null 用户定义
JMSExpiration long 0 0表示用不过气,消息过期时间
JMSRedelivered boolean false 重新传递

JMS定义属性

属性名 类型 默认值 描述
JMSXDeliveryCount int 0 尝试发送消息的次数
JMSXGroupID String null 表示消息的分组
JMSXGroupSeq int 0 消息的序列号
JMSXProducerTXID String null 事务标示

ActiveMQ定义属性

属性名 类型 默认值 描述
JMSActiveMQBrokerInTime long 0 消息到达broker的时间
JMSActiveMQBrokerOutTime long 0 消息离开broker的时间

公告消息(Advisory Message)

ActiveMQ支持的公告消息(相当于监听器)

  • 消费者,生产者和connection开始和停止
  • 临时目的地的创建和销毁
  • 话题和队列上的消息过期
  • broker发送消息到没有消费者的目的地
  • connections开启和停止

    公告消息是一种管理JMS的渠道,我们可以接收到在broker上的生产者消费者目的地的变化。
    当我们通过JMX查看broker时候,可以看到公告话题以ActiveMQ.Advisory为前缀,每个公告拥有类型为Advisory的消息和一些预定义的消息属性

属性名 类型 描述
originBrokerId StringProperty 公告起源的broker的ID
originBrokerName StringProperty 公告起源的broker的名称
originBrokerURL StringProperty 公告起源的第一个broker url

我们可以获得到消息的一些元数据

...

    Destination advisoryDestination = AdvisorySupport.getProducerAdvisoryTopic(destination)
    MessageConsumer consumer = session.createConsumer(advisoryDestination);
    consumer.setMessageListener(this);
....
public void onMessage(Message msg){
    if (msg instanceof ActiveMQMessage){
        try {
             ActiveMQMessage aMsg =  (ActiveMQMessage)msg;
             ProducerInfo prod = (ProducerInfo) aMsg.getDataStructure();
        } catch (JMSException e) {
            log.error("Failed to process message: " + msg);
        }
    }
}

支持的公告话题

客户端的公告消息
我们可以用consumerCount头信息获取当前消费者的数量来得知当前的公告的消息是否已经发送。

Advisory Topics Description properties Data Structure
ActiveMQ.Advisory.Connection ActiveMQ.Advisory.Connection ConnectionInfo, RemoveInfo
ActiveMQ.Advisory.Producer.Queue Producer start & stop messages on a Queue String=’producerCount’ - the number of producers ProducerInfo
ActiveMQ.Advisory.Producer.Topic Producer start & stop messages on a Topic String=’producerCount’ - the number of producers ProducerInfo
ActiveMQ.Advisory.Consumer.Queue Consumer start & stop messages on a Queue String=’consumerCount’ - the number of Consumers ConsumerInfo, RemoveInfo
ActiveMQ.Advisory.Consumer.Topic Consumer start & stop messages on a Topic String=’consumerCount’ - the number of Consumers ConsumerInfo, RemoveInfo

目的地和消息的公告

Advisory Topics 描述 属性 数据结构 默认值 策略属性
ActiveMQ.Advisory.Queue Queue create & destroy null DestinationInfo true none
ActiveMQ.Advisory.Topic Topic create & destroy null DestinationInfo true none
ActiveMQ.Advisory.TempQueue Temporary Queue create & destroy null DestinationInfo true none
ActiveMQ.Advisory.TempTopic Temporary Topic create & destroy null DestinationInfo true none
ActiveMQ.Advisory.Expired.Queue Expired messages on a Queue String=’orignalMessageId’ - the expired id Message true none
ActiveMQ.Advisory.Expired.Topic Expired messages on a Topic String=’orignalMessageId’ - the expired id Message true none
ActiveMQ.Advisory.NoConsumer.Queue No consumer is available to process messages being sent on a Queue null Message false sendAdvisoryIfNoConsumers
ActiveMQ.Advisory.NoConsumer.Topic No consumer is available to process messages being sent on a Topic null Message false sendAdvisoryIfNoConsumers

ActiveMQ5.2新的公告消息

Advisory Topics 描述 属性 数据结构 默认值 策略属性
ActiveMQ.Advisory.SlowConsumer.Queue Slow Queue Consumer String=’consumerId’ - the consumer id ConsumerInfo false advisoryForSlowConsumers
ActiveMQ.Advisory.SlowConsumer.Topic Slow Topic Consumer String=’consumerId’ - the consumer id ConsumerInfo false advisoryForSlowConsumers
ActiveMQ.Advisory.FastProducer.Queue Fast Queue producer String=’producerId’ - the producer id ProducerInfo false advisdoryForFastProducers
ActiveMQ.Advisory. FastProducer.Topic Fast Topic producer String=’consumerId’ - the producer id ProducerInfo false advisdoryForFastProducers
ActiveMQ.Advisory.MessageDiscarded.Queue Message discarded String=’orignalMessageId’ - the discarded id Message false advisoryForDiscardingMessages
ActiveMQ.Advisory.MessageDiscarded.Topic Message discarded String=’orignalMessageId’ - the discarded id Message false advisoryForDiscardingMessages
ActiveMQ.Advisory.MessageDelivered.Queue Message delivered to the broker String=’orignalMessageId’ - the delivered id Message false advisoryForDelivery
ActiveMQ.Advisory.MessageDelivered.Topic Message delivered to the broker String=’orignalMessageId’ - the delivered id Message false advisoryForDelivery
ActiveMQ.Advisory.MessageConsumed.Queue Message consumed by a client String=’orignalMessageId’ - the delivered id Message false advisoryForConsumed
ActiveMQ.Advisory.MessageConsumed.Topic Message consumed by a client String=’orignalMessageId’ - the delivered id Message false advisoryForConsumed
ActiveMQ.Advisory.FULL A Usage resource is at its limit String=’usageName’ - the name of Usage resource null false advisoryWhenFull
ActiveMQ.Advisory.MasterBroker A broker is now the master in a master/slave configuration null null true none

5.4后新公告

Advisory Topics 描述 属性 数据结构 默认值 策略属性
ActiveMQ.Advisory.MessageDLQd.Queue Message sent to DLQ String=’orignalMessageId’ - the delivered id Message Always on advisoryForConsumed
ActiveMQ.Advisory.MessageDLQd.Topic Message sent to DLQ String=’orignalMessageId’ - the delivered id Message Always on advisoryForConsumed

Network bridge advisories

Advisory Topics 描述 属性 数据结构 默认值
ActiveMQ.Advisory.NetworkBridge Network bridge being stopped or started Boolean=”started” - true if bridge is started, false if it is stopped Boolean=”createdByDuplex” - true if the bridge is created by remote network connector BrokerInfo - provides data of the remote broker Always on

开启公告消息

公告消息默认是不开启的,我们可以使用下面的配置开启公告配置

<destinationPolicy>
   <policyMap><policyEntries> 
      <policyEntry topic=">" advisoryForConsumed="true" />
   policyEntries>policyMap>
destinationPolicy>

关闭公告消息

xml配置如下

"false">...

java code 配置

BrokerService broker = new BrokerService();
broker.setAdvisorySupport(false);
...
broker.start();

url链接串

"tcp://localhost:61616?jms.watchTopicAdvisories=false"

设置ConnectionFactory的属性

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
factory.setWatchTopicAdvisories(false);

ActiveMQ一些静态方法

AdvisorySupport.getConsumerAdvisoryTopic()
AdvisorySupport.getProducerAdvisoryTopic()
AdvisorySupport.getExpiredTopicMessageAdvisoryTopic()
AdvisorySupport.getExpiredQueueMessageAdvisoryTopic()
AdvisorySupport.getNoTopicConsumersAdvisoryTopic()
AdvisorySupport.getNoQueueConsumersAdvisoryTopic()
AdvisorySupport.getDestinationAdvisoryTopic()
AdvisorySupport.getExpiredQueueMessageAdvisoryTopic()
AdvisorySupport.getExpiredTopicMessageAdvisoryTopic()
AdvisorySupport.getNoQueueConsumersAdvisoryTopic()
AdvisorySupport.getNoTopicConsumersAdvisoryTopic()

//Version 5.2 onwards


AdvisorySupport.getSlowConsumerAdvisoryTopic()
AdvisorySupport.getFastProducerAdvisoryTopic()
AdvisorySupport.getMessageDiscardedAdvisoryTopic()
AdvisorySupport.getMessageDeliveredAdvisoryTopic()
AdvisorySupport.getMessageConsumedAdvisoryTopic()
AdvisorySupport.getMasterBrokerAdvisoryTopic()
AdvisorySupport.getFullAdvisoryTopic()

Blob 消息(Blob Message)

发送大文件信息
文件地址,或者url等共享文件系统的文档

BlobMessage message = session.createBlobMessage(new URL("http://some.shared.site.com");
producer.send(message);
// lets use a local file
BlobMessage message = session.createBlobMessage(new File("/foo/bar");
producer.send(message);
// lets use a stream
InputStream in = ...;
BlobMessage message = session.createBlobMessage(in);
producer.send(message);

接收信息

public class MyListener implements MessageListener {
  public void onMessage(Message message) {
    if (message instanceof BlobMessage) {
      BlobMessage blobMessage = (BlobMessage) message;
      InputStream in = blobMessage.getInputStream();

      // process the stream...
    }
  }
}

Delay and Schedule Message Delivery

开启定时发送配置

"true">
...

定时发送的策略org.apache.activemq.ScheduledMessage的属性名称

属性名称 类型 描述
AMQ_SCHEDULED_DELAY long 毫秒单位,等待多久时间发送到broker
AMQ_SCHEDULED_PERIOD long 第一次发送后等待调度的周期调度的时间
AMQ_SCHEDULED_REPEAT int 重复调度的次数
AMQ_SCHEDULED_CRON String cron的配置策略

第一次等待发送60秒

MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long time = 60 * 1000;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, time);
producer.send(message);

第一次发送延时30,重复10次,每次间隔10秒重复发送

MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long delay = 30 * 1000;
long period = 10 * 1000;
int repeat = 9;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
producer.send(message);

使用cron的形式配置

MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *");
producer.send(message);

cron的配置是优先级于其他的定时配置的,
那么这样子的配置的话就是每小时发送一次,第一次发送延迟1秒,发送10次,间隔1秒

MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
message.setStringProperty(ScheduledMessage.AMQ_SCHEDULED_CRON, "0 * * * *");
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 1000);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, 1000);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, 9);
producer.send(message);

JMS流(JMS Streams)

该模块已经遗弃,不推荐使用

消息转换(Message Transformation)

有时候我们希望对消息进行转换,比如将对象类型的转换为Xml的格式。
ActiveMQ4.2以后提出了可插拔的策略MessageTransformer接口,该接口允许我们

  • 在JMS提供者发送到消息总线前加强或者转换消息
  • 在接收到消息后但是还未发送到消费者前加强或者转换消息

可以使用setTransformer方法的类

  • ActiveMQConnectionFactory
  • ActiveMQConnection
  • ActiveMQSession
  • ActiveMQMessageConsumer
  • ActiveMQMessageProducer

对象消息

ObjectMessage依赖于java语言的序列化,这样子很容易被攻击者攻击,所以在脚本里面会配置白名单${ACTIVEMQ_HOME}/bin/env脚本。ObjectMessage的使用从5.12.2开始版本是不推荐,但是这里我们还是介绍一下。

-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=java.lang,javax.security,java.util,org.apache.activemq,org.fusesource.hawtbuf,com.thoughtworks.xstream.mapper,com.mycompany.myapp

或者使用通配

-Dorg.apache.activemq.SERIALIZABLE_PACKAGES=*

客户端代码或者Spring配置文件的配置

ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
factory.setTrustedPackages(new ArrayList(Arrays.asList("org.apache.activemq.test,org.apache.camel.test".split(","))));
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
factory.setTrustAllPackages(true);
id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"/>
    <property name="trustedPackages">
        <list>
            org.apache.activemq.test
            org.apache.camel.test
        list>
    property>

id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="connectionFactory"/>

id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig"/>
id="connectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">
    <property name="brokerURL" value="tcp://localhost:61616"/>
    <property name="trustAllPackages" value="true"/>

id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
    <property name="connectionFactory" ref="connectionFactory"/>

id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
    <property name="configuration" ref="jmsConfig"/>

结构化消息属性和Map消息

JMS允许我们使用Map或者List来属性来映射任意语言的配置,这样子消息就可以方便在C,C++等语言转换了。
- Message.setObjectProperty(key, value)
- MapMessage.setObject(key, value)

你可能感兴趣的:(activemq)