java Message Service(java消息服务是javaEE中的一个技术)
1、JMS的组成结构和特点
1.1JMS provider:实现JMS接口和规范的消息中间件,也就是我们的MQ服务器
1.2JMS producer:消息生产者,创建和发送JMS消息的客户端应用
1.3JMS consumer:消息消费者,接收和处理JMS消息的客户端应用
1.4JMS message:
1.4.1消息头:
JMSDestination:消息发送的目的地,主要是指Queue和Topic
JMSDeliveryMode:持久模式和非持久模式。
一条持久性的消息:应该被传送“一次仅仅一次”,这就意味着如果JMS提供者出现故障,该消息并不会丢失,它会在服务器恢复之后再次传递。一条非持久的消息:最后会传送一次,这意味这服务器出现故障,改消息将永远丢失。
JMSExpiration:可以设置消息在一定时间后过期,默认是永不过期。
消息过期时间,等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值。
如果timeToLive值等于零,则JMSExpiration被设为零,表示该消息永不过期。
如果发送后,在消息过期时间之后消息还没有被发送到目的地,则该消息被清除。
JMSPriority:消息优先级,从0-9十个级别,0到4是普通消息,5到9是加急消息。
JMS不要求MQ严格按照这十个优先级发送消息,但必须保证加急消息要先于普通消息到达,默认是4级。
JMSMessageID:唯一识别每个消息的标识由MQ产生
1.4.2消息体:
封装具体的消息数据,发送和接受的消息体类型必须一致对应。
5种消息体格式:
TextMessage:普通字符串消息,包含一个String
MapMessage:一个Map类型的消息,key为string类型,而值为java的基本类型
BytesMessage:二进制数组消息,包含一个byte[]
StreamMessage:java数据流消息,用标准流操作来顺序的填充和读取
ObjectMessage:对象消息,包含一个可序列化的java对象
2、JMS的可靠性
2.1PERSISTENT:持久性
参数设置说明:
1、非持久messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);非持久化:当服务器宕机,消息不存在。
2、持久
messageProducer.setDeliveryMode(DeliveryMode.PERSISTENT);持久化:当服务器宕机,消息依然存在。
默认是持久性的
2.2事物
生产者producer提交时的事物
false:只要执行send,就进入到队列中。关闭事物,那第2个签收参数的设置需要有效。
true:先执行send再执行commit,消息才被真正的提交到队列中。消息需要批量发送,需要缓冲区处理
package com.hhf.activemq.queue;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* Created by Administrator on 2019/9/21.
*/
public class JmsProduce_TX {
public static final String ACTIVEMQ_URL = "tcp://192.168.136.137:61616";
public static final String QUEUE_NAME = "queue01";
public static void main(String[] args) throws JMSException {
//1.创建连接工场,按照给定的URL地址,采用默认用户名和密码
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
//2.通过连接工场,获得连接connection并启动访问
Connection connection = activeMQConnectionFactory.createConnection();
connection.start(); //连上地址
//3.创建会话session,
// 两个参数,第一个参数叫:事物,第二个参数叫:签收
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); //如果事务设置为true,一定要把事务开启
//4.创建目的地(具体是队列还是主题topic)
//Destination destination = session.createQueue(QUEUE_NAME); 可以赋给目的地,而不直接赋给具体的队列还是主题,但是一般不建议这么做
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("QUEUE_NAME---" + i);//理解为一个字符串
//8.通过messageProducer发送给MQ
messageProducer.send(textMessage);
}
//9.关闭资源
messageProducer.close();
session.commit();//提交事务
session.close();
connection.close();
System.out.println("*****TOPIC_NAME消息发布到MQ完成");
}
}
为什么要用到事物?
保证复杂的业务下面都ok的话,批处理进行提交,同时成功同时失败,如果是try/cach有异常可以把他重新操作回滚。
事物偏生产者/签收偏消费者
2.3Acknowledge:签收
2.3.1非事物:
自动签收(默认):Session.AUTO_ACKNOWLEDGE
手动签收:Session.CLIENT_ACKNOWLEDGE客户端调用acknowledge方法手动签收(textMessage.acknowledge();)
允许重复消息:Session.DUPS_OK_ACKNOWLEDGE
2.3.2事物
生产事物开启,只有commit后才能将全部消息变为已消费
2.3.3签收和事物关系:
在事务性会话中,当一个事物被成功提交则消息被自动签收。如果事物回滚,则消息会被再次传送。
非事物性会话中,消息何时被确认取决于创建会话时的应答模式(acknowledgement mode)
3、JMS的点对点总结
点对点模型是基于队列的,生产者发消息到队列,消费者从队列接收消息,队列的存在使得消息的异步传输成为可能。
和我们平时给朋友发送短信类似。
1: 如果在Session关闭时有部分消息已被收到但还没有被签收(acknowledged),那当消费者下次连接到相同的队列时,这些消息还会被再次接收。
2:队列可以长久地保存消息直到消费者收到消息。消费者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输模式的优势。
4、JMS的发布订阅总结
JMS Pub/Sub模型定义了如何向一个内容节点发布和订阅消息,这些节点被称作topic
主题可以被认为是消息的传输中介,发布者(publisher)发布消息到主题,订阅者(subscribe)从主题订阅消息。
主题使得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送。
当所有的消息必须被接收,则用持久订阅。当丢失消息能够被容忍,则用非持久订阅