剖析1条JMS消息

前言

一个JMS消息分为:

1.消息头

2.属性

3.消息体(有效负载)

1.消息头

1.1 系统默认分配的消息头

  • a. JMSDestination :Topic 和Queue用此属性标识目的地,二者都是Destination类型。

            javax.jms.Message接口有对应的getJMSDestination()方法。

  • b.JMSDeliveryMode:传送模式:

            持久化 : javax.jms.DeliveryMode.PERSISTENT

            非持久化 : javax.jms.DeliveryMode.NON_PERSISTENT

            javax.jms.MessageProducer接口,中有设置该消息头的方法。

            JmsTemplate设置方式如下:

JmsTemplate.setDeliveryPersistent(boolean deliveryPersistent);
  • c.JMSMessageID:String类型,消息的唯一标示
  • d.JMSTimeStamp:由MessageProducer在调用send时自动,设置。long类型。用于确定发送消息和该消息被消息者实际接收的时间间隔。
  • e.JMSExpiration:设置消息的过期时间。
MessageProducer.setTimeToLive()//进行设置。

JmsTemplate.setTimeToLive(long timeToLive)

        默认不过期,javax.jms.Message.DEFAULT_TIME_TO_LIVE(该值为0,表示永不过期)

  • f.JMSRedelivered:标示该消息将重复给消费者。如果为true,表示该消息将被重新发送,仅在需要确认消息的模式下有效。
  • g.JMSPriority:JMS优先级,0-4普通,5-9加急,加急会比普通优先发送。

          默认优先级为javax.jms.Message.DEFAULT_PRIORITY(即为4)。

1.2 为开发者分配的消息头

  • a.JMSReplayTo:设置应答队列,仅仅对Queue模式有用。

JmsTemplate没有主动设置的部分,sendAndReceive方法时会临时生成一个队列。

  • b.JMSCorrelationID:业务关联ID,一般情况下用于应答,存储上一条消息的JMSMessageID,表示 是这条消息的应答。

            MessageListenerAdapter.onMessage会进行设置。

  • c.JMSType:可选消息头,用于标注类型和有效负载类型,非MapMessage。某些消息系统需要这个字段。

2.消息属性

    类似附加消息头。可以是boolean,Byte,Short,Integer,Long,float,double,Object类型

2.1应用特定的属性(自定义数据)

一般用于消息选择器。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;

}

});

2.2 JMS定义的属性

默认以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

2.3MQ特定的消息

用于支持厂商的私有特性。我在工作中没有使用到,不做介绍。

3.消息类型

JMS提供了6个消息接口,分别是:

  • Message
  • BytesMessage,
  • MapMessage,
  • ObjectMessage(传递序列化后的消息),
  • StreamMessage,
  • TextMessage。

Message

若使用Message,仅仅包含消息头和消息属性。基本仅仅用作事件通知。广播,警告,或者通知 中。

TextMessage

使用setText设置有效负载。getText获取消息。

ObjectMessage

setObject方法,注意这个对象必须要序列化。

BytesMessage

原始字节流作为有效负载

设置消息类似java.io.DataInputStream和java.io.DataOutputStream方法。

BytesMessage byteMessage=Session.createByteSession();

byteMessage.writeChar('c');

byteMessage.writeInt(10);

byteMessage.writeUTF("O my god");

StreamMessage

负载为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方法,将读取指针返回到开始的地方

MapMessage

    负载为一组键值对.

    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的负载均衡的搭建,预计下周完成。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[WS标准篇]

元数据实际上是服务终结点的描述,终结点由地址(Address)、绑定(Binding)和契约(Contract)经典的ABC三要素组成。认真阅读过《WCF技术剖...

41490
来自专栏公众号_薛勤的博客

MongoDB非关系型数据库开发手册

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

22520
来自专栏武军超python专栏

2018年8月25日多线程编程总结

PYTHON 本身也支持多任务处理,并且提供了如下的操作方式 多线程多任务处理机制   (比较常用) 多进程多任务处理机制   (不常用,大型项目开发或者系...

12540
来自专栏IT技术精选文摘

RMI原理及实现

1 简介 RMI是远程方法调用的简称,像其名称暗示的那样,它能够帮助我们查找并执行远程对象的方法。通俗地说,远程调用就象将一个class放在A机器上,然后在B机...

20280
来自专栏PPV课数据科学社区

python多线程编程(3): 使用互斥锁同步线程

问题的提出 上一节的例子中,每个线程互相独立,相互之间没有任何关系。现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些...

33870
来自专栏好好学java的技术栈

“面试不败计划”:Java多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应...

9620
来自专栏智能大石头

新生命开发团队Orm框架XCode v3.5.2009.0714源码发布(圣诞随心大礼包)

忙忙碌碌有一年!做了很多东西,到头来,似乎又什么都没有做。人继续变老,程序继续改进。     这段时间从我们各个系统抽取了基础的常用的部分,整理后形成了一个...

22070
来自专栏破晓之歌

Django 2.0 新特性 转

2017年12月2日,Django官方发布了2.0版本,成为多年来的第一次大版本提升,那么2.0对广大Django使用者有哪些变化和需要注意的地方呢?

11220
来自专栏平凡文摘

详细分析Java中断机制

15940
来自专栏小勇DW3

使用Redis作为分布式锁的一些注意点

最简单的方法是使用setnx命令。key是锁的唯一标识,按业务来决定命名,value为当前线程的线程ID。

3.5K50

扫码关注云+社区

领取腾讯云代金券