一个JMS消息分为:
1.消息头
2.属性
3.消息体(有效负载)
javax.jms.Message接口有对应的getJMSDestination()方法。
持久化 : javax.jms.DeliveryMode.PERSISTENT
非持久化 : javax.jms.DeliveryMode.NON_PERSISTENT
javax.jms.MessageProducer接口,中有设置该消息头的方法。
JmsTemplate设置方式如下:
JmsTemplate.setDeliveryPersistent(boolean deliveryPersistent);
MessageProducer.setTimeToLive()//进行设置。
JmsTemplate.setTimeToLive(long timeToLive)
默认不过期,javax.jms.Message.DEFAULT_TIME_TO_LIVE(该值为0,表示永不过期)
默认优先级为javax.jms.Message.DEFAULT_PRIORITY(即为4)。
JmsTemplate没有主动设置的部分,sendAndReceive方法时会临时生成一个队列。
MessageListenerAdapter.onMessage会进行设置。
类似附加消息头。可以是boolean,Byte,Short,Integer,Long,float,double,Object类型
一般用于消息选择器。Message接口有对应的get,set方法。
jmsTemplate 的设置方式如下:
jmsTemplate.convertAndSend(queue, obj, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws JMSException {
for (Entry<String, String> head : appendHeaders.entrySet()) {
message.setStringProperty(head.getKey(), head.getValue());
}
return message;
}
});
默认以JMSX开头,这些消息头是可选的。
名称 | 类型 | 由谁设置 | 作用 |
---|---|---|---|
JMSXUserID | String | MQ在发送时设置 | 发送消息的UserId |
JMSXAppID | String | MQ在发送时设置 | 发送消息的应用ID |
JMSXDeliveryCount | int | MQ在接收时设置 | 消息尝试发送的次数,第一次为1,第二次为2 |
JMSXGroupID | String | client(调用者)端 | 消息所属的分组ID |
JMSXGroupSeq | int | Client(调用者)端 | 消息在组中的序号,第一个消息为1,第二个消息为2 |
JMSXProducerTXID | String | MQ在接收时设置 | 消息生成时的事务ID |
JMSXConsumerTXID | String | MQ在接收时设置 | 消息被消费时的事务ID |
JMSXRcvTimestamp | long | MQ在接收时设置 | JMS把消息发送的消费者的时间 |
JMSXState | int | MQ | 假设存在一个消息仓库, 该消息仓库包含每个发送到消费者 的消息的独立副本。 这些副本的存在从最初的信息开始被送时就存在 每个副本的状态,是如下状态其中之一: 1(等待)2(就绪)3(过期)4(保留) 因为状态对生成者和消费者都无用, 所以不由他们提供。 这个状态仅仅用于在仓库中查询, JMS没有对应的API |
用于支持厂商的私有特性。我在工作中没有使用到,不做介绍。
JMS提供了6个消息接口,分别是:
若使用Message,仅仅包含消息头和消息属性。基本仅仅用作事件通知。广播,警告,或者通知 中。
使用setText设置有效负载。getText获取消息。
setObject方法,注意这个对象必须要序列化。
原始字节流作为有效负载
设置消息类似java.io.DataInputStream和java.io.DataOutputStream方法。
BytesMessage byteMessage=Session.createByteSession();
byteMessage.writeChar('c');
byteMessage.writeInt(10);
byteMessage.writeUTF("O my god");
负载为java原数据类型流.允许将null写入流。读取的顺序与写入的顺序一致。
读取时的类型转换规则如下:
写类型 | 读可转换的类型 |
---|---|
boolean | boolean,String |
byte | byte,short,int,long,String |
short | short,int,long,String |
char | char,String |
long | long,String |
int | int,long,String |
float | float,double,String |
String | String,boolean,byte,short,int,long,float,double |
byte[] | byte[] |
若读取时遇到异常,尝试重新读取,需要调用reset方法,将读取指针返回到开始的地方。
负载为一组键值对.
JMS客户端试图读取,一个不存在的值时,该值视为null。
注意:
getObject方法会对不存在的映射放回null
大多数的原始类似取值函数会返回,java.lang.NumberFormatException。
getBoolean()方法将为null值返回false;
getString(),可能返回null,或者一个空字符串。
getChar(),会抛出java.lang.NullPointerException。
为了避免上述问题,MapMessage提供了一个itemExists()的测试方法。另外getMapNames()可以让JMS客户端列举出Key。
这篇blog,基本上都是JMS消息的概念,下篇blog会介绍activemq的负载均衡的搭建,预计下周完成。