ActiveMQ学习笔记(三)JMS可靠性

什么是JMS?

java消息服务指的是两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,等于支持JAVA应用程序开发。
在JAVAEE中,当两个应用程序使用JMS进行通信时,他们之间不是直接相连的,而是通过一个共同的消息收发服务组件关联起来已达到解耦/异步削峰的效果。

ActiveMQ学习笔记(三)JMS可靠性_第1张图片

JMS组成四大元素

JMS provider 实现JMS接口和规范的消息中间件,也就是MQ服务器
JMS producer 消息生产者,创建和发送JMS消息的客户端应用
JMS consumer 消息消费者,接收和处理JMS消息的客户端应用
JMS message

  • 消息头
    - JMSDestination 消息发送的目的地
    - JMSDeliveryMode 是持久还是非持久
    - JMSExpiration 消息的过期时间,默认永不过期,消息过期时间=Destination的send方法中timetoLive值+发送时刻的GMT时间值。如果timetoLive等于0,则JMSExpiration被设为0,该消息永不过期。如果发送后,在消息过期时间之后消息还没被发送到目的地,该消息被清楚
    - JMSPriority 优先级 0-9 十个级别,默认4级
    - JMSMessageID 唯一识别每个消息的标识由MQ产生

  • 消息体(封装具体的消息数据)
    - TextMessage 普通字符串消 息,包含一个 String
    - MapMessage Map 类型的消息, k-> String v -> Java 基本类型
    - BytesMessage 二进制数组消息,包含一个byte[]
    - StreamMessage Java 数据流消息, 用标准流操作来顺序的填充读取
    - ObjectMessage 对象消息,包含一个可序列化的Java对象

  • 消息属性
    如果需要消息头字段以外的值,可以使用
    识别/去重/重点标注等操作

消息的可靠性

持久性

queue:
设置非持久化 服务器宕机,消息不存在
在这里插入图片描述
设置持久化 服务器宕机,消息存在(默认)
在这里插入图片描述
topic:
消费者发布订阅:
一定要先运行一次消费者,等于向MQ注册,类似我订阅了这个主题
然后再运行和生产者发送信息
此时不论消费者是否在线,都能接收到消息。当消费者下次连接的时候,会把没有收过的消息都接收下来

public class JmsConsumer_topic {
    public static final String ACTIVEMQ_URL = "tcp://10.1.240.97:61616";
    public static final String TOPIC_NAME = "topic01";
    public static void main(String[] args) throws JMSException, IOException {
        System.out.println("1号消费者");
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.setClientID("1hao");
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        TopicSubscriber topicSubscriber = session.createDurableSubscriber(topic,"remark..");
        connection.start();
        Message message = topicSubscriber.receive();
        while(null!=message){
            TextMessage textMessage = (TextMessage) message;
            System.out.println("***收到的持久化topic"+textMessage.getText());
            message=topicSubscriber.receive(1000l);
        }
        session.close();
        connection.close();
    }
}

生产者


package com.atguigu.activemq.queue;

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

public class JmsProduce_topic {
    public static final String ACTIVEMQ_URL = "tcp://10.1.240.97:61616";
    public static final String TOPIC_NAME= "topic01";
    public static void main(String[] args) throws JMSException {

        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        Connection connection = activeMQConnectionFactory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Topic topic = session.createTopic(TOPIC_NAME);
        MessageProducer producer = session.createProducer(topic);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT);
        connection.start();//位置与非持久化的不同
        for(int i=1;i<=3;i++){
            TextMessage textMessage = session.createTextMessage("msg--" + i);
            producer.send(textMessage);
        }
        producer.close();
        session.close();
        connection.close();
        System.out.println("topic消息发送完成!");

    }
}


消费者启动:
ActiveMQ学习笔记(三)JMS可靠性_第2张图片
生产者启动:
ActiveMQ学习笔记(三)JMS可靠性_第3张图片

事务

produce提交时的事务
在这里插入图片描述
如果是false:只要执行 producer.send(textMessage),就进入到队列
如果是true:执行send后,在session关闭前需要执行commit,消息才真正提交到队列中

consumer提交的事务:
对于消息消费者来说,开启事务的话,可以避免消息被多次消费,以及后台和 服务器数据的不一致性。举个栗子: 如果消息消费的 createSession 设置为 ture ,但是没有 commit ,此时就会 造成非常严重的后果,那就是在后台看来消息已经被消费,但是对于服务器来说 并没有接收到消息被消费,此时就有可能被多次消费

Acknowledge 签收 (俗称ack)

非事务:
Session.AUTO_ACKNOWLEDGE 自动签收,默认
Session.CLIENT_ACKNOWLEDGE 手动签收
手动签收需要 textMessage.acknowledge();
事务:

 Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE); //Session session = connection.createSession(true,Session.CLIENT_ACKNOWLE DGE); // 也是自动签收  ……  session.commit(); 

事务:
开启事务后,设置手动签收和自动签收没有多大的意义,都默认自动签 收,也就是说事务的优先级更高一些。开启事务没有commit,就会重复消费

JMS点对点总结:

基于队列,生产者发布消息到队列,消费者从队列接收消息,队列的存在使得消息的异步传输成为可能,和平时给朋友发送短信类似
1.如果在session关闭时有部分消息被收到但是还没有被签收,当消费者下次连到相同的队列时,这些消息还会被再次接收
2.队列可以长久的保存消息直到消费者收到消息。消费者不需要担心消息会丢失而时刻和队列保持激活的连接状态,体现了异步传输模式的优势

JMS发布订阅总结:

主题可以被认为是消息的传输中介,发布者发布消息到主题,订阅者从主题订阅消息
主题使得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送

Broker

相当于一个服务器实例
broker 就是实现了用代码形式启动 ActiveMQ 将 MQ 内嵌到 Java 代码中,可 以随时启动,节省资源,提高了可靠性。 就是将 MQ 服务器作为了 Java 对象
1.导入依赖

 
 com.fasterxml.jackson.core 
  jackson‐databind 
   2.9.5 
   

代码实现:

public class Embebroker { 
public static void main(String[] args) throws Exception { 
 // broker 服务 
 BrokerService brokerService = new BrokerService(); 
 //把小型 activemq 服务器嵌入到 java 代码
  brokerService.setUseJmx(true);  
  //原本的是 192.…… 是linux 上的服务器,而这里是本地windows 的小型mq 服务器 
 brokerService.addConnector("tcp://localhost:61616"); 
 brokerService.start(); 
  } 
   }

你可能感兴趣的:(ActiveMQ学习笔记(三)JMS可靠性)