ActiveMQ系列(四)ActiveMQ核心功能持久化、事务、签收

本文总结下ActiveMQ的核心功能,涉及一些概念和API。

一. Jms生产者Demo

先上一个生产者的小demo,然后围绕demo展开:

import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class JmsProduce {
    public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";
    public static final String QUEUE_NAME = "queue01";

    public static void main(String[] args) throws JMSException {
        //创建连接工厂,按照给定的url地址,使用默认用户名和密码
        ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
        //通过连接工厂获取连接,并启动
        Connection connection = activeMQConnectionFactory.createConnection();
        connection.start();

        //创建会话session,true开启事务,false不开启事务
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        //创建目的地,是队列还是topic
        Queue queue = session.createQueue(QUEUE_NAME);
        //创建消息的生产者
        MessageProducer producer = session.createProducer(queue);
        //持久化模式设置
        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        
        try {
            //生产3条消息到队列
            for (int i = 1; i <= 3; i++) {
                //创建消息
                TextMessage textMessage = session.createTextMessage("msg--" + i);
                //使用生产者发送消息
                producer.send(textMessage);
            }
            session.commit();
        } catch (JMSException e) {
        	//异常情况回滚提交
            session.rollback();
        } finally {
            //关闭资源
            producer.close();
            //如果上边开启事务,那么这里要提交,不然消息不进入队列

            session.close();
            connection.close();
        }

        System.out.println("发布消息到队列完成!");
    }
}

上述是ActiveMQ的一种生产者的原生标准实现,生产3个消息到队列Queue中(或者主题Topic中),并且使用了事务模式。

本demo使用了JMS包,下面先总结下JMS。

二. JMS介绍

1.jms是什么

上述demo中使用了javax.jms.包中的内容,比如Connection/Session/Queue/MessageProducer/TextMessage等。JMS(Java Message Service),java消息服务,是JavaEE规范中的一个模块,制定了消息接收发送的一套标准规范,其中落地产品有很多(各种MQ),ActiveMQ就是其中一款落地产品,它完全遵守了JMS规范。

JMS提供了一套API,为标准消息协议和消息服务提供了一组接口,包括创建,发送,读取消息等。

2.jms组成的四大元素

  • jms peovider :实现jms接口和规范的消息中间件,也就是MQ服务器;
  • jms producer :消息生产者,创建和发送jms消息的客户端应用;
  • jms consumer :消息消费者,接收和处理jms消息的客户端应用;
  • jms message :发送和被接受的消息,包含消息头,消息体,消息属性;

在这里插入图片描述

3.jms 消息头
列举几个比较重要参数:

  • JMSDestination :消息发送的目的地,主要指Queue还是Topic;Message接口提供了setJMSDestination方法;
  • JMSDeliveryMode :设置持久化或者非持久化模式,非持久化模式下,MQ宕机,消息丢失,但是持久化模式不会丢失;
  • JMSExpiration :设置消息过期时间,过期后会清除,默认是永不过期;
  • JMSPriority :消息优先级,包含0-9是个级别,0-4是普通消息,5-9是加急消息,默认是4。JMS规范不要求MQ严格按照这个优先级顺序发送,但是要保证5-9的早于0-4的。
  • JMSMessageID :唯一识别每个消息的标识,由MQ产生或者自己设定;

以上参数可以针对每条消息单独设置,也可以在send方法中统一设置。

4.消息体
消息体封装具体的消息数据,有多种类型格式,消息发送方和接收方的格式必须保持一致。
5种消息体格式:

  • TextMessage :普通字符串,包含一个string;
  • MapMessage :map类型,其中key为String类型,
  • BytesMessage :二进制数组消息,包含一个byte[];
  • StreamMessage :java数据流消息,用标准流来顺序填充和读取;
  • ObjectMessage :对象消息,包含一个可序列话的java对象;

5.消息属性
识别,去重,重点标注等操作。
接口方法:
setStringProperty(String name, String value);
除此之外,还有setIntProperty等类型;需要注意的是,生产者与消费者的类型要保持一致。

三. 消息的持久化

jms消息默认是持久化的,可以通过JMS接口的如下方法设置持久与非持久:

void setDeliveryMode(int deliveryMode) throws JMSException;

public interface DeliveryMode {
	//非持久
    static final int NON_PERSISTENT = 1;
	//持久
    static final int PERSISTENT = 2;
}

非持久模式下,MQ如果宕机再启动,消息会丢失;持久化模式下,消息只要没消费掉,不会丢失。

四. 消息事务

1.生产者事务

文章开头的demo中,有如下内容:

//创建会话session,true开启事务,false不开启事务
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);

第一个参数,true表示开启事务;false表示关闭事务;

开启了事务模式,那么就需要提交事务:
session.commit();
提交事务之前,消息不进入队列;只有提交后,消息才进入队列,消费者才能消费到。

2.消费者事务
消费者的事务使用代码和生产者一样。
消费者中,要注意commit,否则消费者会重复消费消息,消息一直在队列中消费不掉;只有提交事务后,才能被消费掉。

五. 消息签收

签收针对的是消费者,在消费者中,一般也会有如下代码:

//创建会话session,true开启事务,false不开启事务
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

其中,第二个参数是签收模式。在非事务模式下,共有如下几种类型:

  • Session.AUTO_ACKNOWLEDGE = 1; //自动签收,默认就是这种方式;在这种模式下,消费者会自动签收消息,也就是在拿到消息时,就默认签收了,不用在调用方法进行签收;

  • Session.CLIENT_ACKNOWLEDGE = 2; //手动签收,在这种模式下,消费者拿到消息后,需要使用如下方法进行手动签收,
    textMessage.acknowledge ();
    ,否则,消息会残留在消息队列中,导致重复消费。

  • Session.DUPS_OK_ACKNOWLEDGE = 3; //允许重复签收,这种模式基本不使用。

注意,上述模式是针对非事务模式的;
如果在事务模式下,那么签收模式会失效,即使配置的是手动签收,在事务模式下,也会被自动签收。

六.传输协议种类

Demo中,使用了如下连接,可以发现,使用的的是tcp协议,

 public static final String ACTIVEMQ_URL = "tcp://192.168.17.101:61616";

除了此种协议,ActiveMQ还支持其他类型协议:

1.transmission Control Protocol(TCP)

tcp是默认使用的协议,端口61616;
使用格式:tcp://hostname:port?key=value ,key和value可以不添加,具体内容有:
在这里插入图片描述
全部内容看官方文档:
http://activemq.apache.org/tcp-transport-reference

2.New I/O API Protocol (NIO)

nio基于tcp协议,进行了扩展和优化,比tcp协议具有更好的性能,实际生产中,也大多使用此种协议。
要使用此种模式,需要修改ActiveMQ的配置文件:conf / activemq.xml ,增加

<transportConnector name="nio" uri="nio://0.0.0.0:61616"/>  

在这里插入图片描述
使用格式:nio://hostname:port?key=value ,其中key和value同tcp配置。

具体参考官方文档:
http://activemq.apache.org/configuring-version-5-transports.html

auto模式
从5.13.0版本开始,activemaq支持auto自动模式,可以从多种类型的协议中自动探测最终使用哪种协议。
在这里插入图片描述
官方文档:http://activemq.apache.org/auto

3.AMQP 协议
4.stomp协议
5.Secure Sockets Layer Protocol (SSL)安全连接
6. mqtt 协议
7. ws 协议

上述其他协议使用不多,具体看官方文档:

http://activemq.apache.org/configuring-version-5-transports.html

发布了62 篇原创文章 · 获赞 29 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csdn_20150804/article/details/104592674