JMS的定义
JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持,可以类比JDBC技术,不同的厂商对JDBC做了不同的实现。
JMS的组成
JMS由JMS provider、JMS producer、JMS consumer、JMS message组成。下面给出这些概念的定义。
JMS provider
实现JMS接口和规范的消息中间件,也就是我们的MQ服务。
JMS producer
消息生产者,创建和发送JMS消息的客户端应用。
JMS consumer
消息消费者,接收和处理JMS消息的客户端应用。
JMS message
JMS message由消息头、消息体、消息属性3部分组成。
消息头
消息头有5个比较常见的属性,分别是JMSDestination、JMSDeliveryMode、JMSExpiration
、JMSPriority、JMSMessageID,下面这个表格展示了它们所代表的意义。
属性 | 意义 |
---|---|
JMSDeliveryMode | 持久和非持久模式,一条持久性的消息应该被传送“一次仅仅一次“,这就意味着如果JMS提供者出现故障,该消息并不会丢失,它会在服务器恢复之后再次传递。一条非持久的消息最多会被传送一次,这就意味着服务器如果出现故障,该消息将永远丢失 |
JMSExpiration | 可以设置消息在一定时间以后过期,默认是永不过期。消息过期时间等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值,如果timeToLive值等于零,则JMSExpiration被设为零,表示该消息永不过期。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除 |
JMSPriority | 消息优先级,从0-9十个级别,0-4是普通消息,5-9是加急消息。JMS不要求MQ严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达。默认是4级 |
JMSMessageID | 唯一识别每个消息的标识由MQ产生 |
JMSDestination | 消息发送的目的地,主要是指Queue和Topic |
下面的代码演示了怎么设置这些属性。 |
public class JmsProduce {
public static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
public static final String QUEUE_NAME = "queue02";
public static void main(String[] args) throws JMSException {
//1.创建连接工场,按照给定Url地址,采用默认的用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
//2通过连接工场,获得连接connection并启动访问
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//3.创建回话session,第一个参数是事务,第二个参数是签收
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4.创建目的地(是队列还是主题(topic))
Queue queue = session.createQueue(QUEUE_NAME);
//5.创建消息的生产者
MessageProducer messageProducer = session.createProducer(queue);
//6.通过使用messageProducer生产3条消息发送到MQ的队列里面
for (int i = 1; i <= 3; i++) {
//7.创建消息
TextMessage textMessage = session.createTextMessage("msg---" + i);
//设置消息头的属性
textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT); //设置消息的持久化
textMessage.setJMSExpiration(400L); //设置消息过期时间
textMessage.setJMSPriority(6); //设置消息优先级
textMessage.setJMSDestination(queue); //设置消息的目的地
//8.通过messageProducer发送给mq
messageProducer.send(textMessage);
}
//关闭资源
messageProducer.close();
session.close();
connection.close();
System.out.println("消息发送到MQ");
}
}
消息体
消息体封装了具体的消息数据,消息体有五种消息格式,发送和接收的消息体类型必须一致对应。
五种消息体格式
消息体格式 | 代表的意思 |
---|---|
TextMessage | 普通字符串消息,包含String |
MapMessage | 一个Map类型的消息,key为String类型,值为Java基本类型 |
BytesMessage | 二进制数组消息,包含一个byte[] |
StreamMessage | Java数据流消息,用标准流操作来顺序的填充和读取 |
ObjectMessage | 对象消息,包含一个可序列化的Java对象 |
消息属性
如果需要去除消息头字段以外的值,那么可以使用消息属性,消息属性是以属性名和属性值对的形式制定的,可以将属性视为消息头的扩展,属性指定一些消息头没有包括的附加信息,比如可以在属性里指定消息选择器。消息的树形就像可以分配给一条消息的附加消息头一样。它们允许开发者添加有关消息的不透明附加消息。
消息发送和接收模型
JMS支持两种消息发送和接收模型,一种是P2P模型,另一种是发布订阅(Publish/Subscribe)模型。
P2P模型
P2P模型采用点对点的方式发送和接收消息,P2P模型是基于队列的,消息生产者发送消息到队列,消息消费者从队列中接收消息,因为队列的存在,消息的异步传输成为可能。P2P模型的特点是每个消息只有一个消费者,当发送者发送消息以后,不管接收者有没有在运行都不影响消息被发布到队列中,接收者在成功接收消息后会向发送者发送接收成功的信息。
发布订阅模型
发布订阅模型定义了如何向一个内容节点发布和订阅消息,这个内容节点称为主题(Topic)。只有先创建订阅者以后,才可以消费消息生产者的信息,并且订阅者需要一直保持运行的状态。发布订阅模型允许一个消息被多个消费者消费,也就是一个消息可以被多个消费者订阅,每个消费者都可以接收到这个信息。
这两个模型的具体使用可以参考我的另一篇文章,文章是以ActiveMQ为例子的。