欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ActiveMQ学习(二)

程序员文章站 2022-07-15 08:59:25
...

什么是JMS(Java Message Service)

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

ActiveMQ学习(二)

JMS组成的四大元素

JMS provider

实现JMS接口和规范的消息中间件,也就是我们的MQ服务器

JMS producer

消息生产者,创建和发送JMS消息的客户端应用

JMS consumer

消息消费者,接收和处理JMS消息的客户端应

JMS message(由三部分组成,消息头、消息体、消息属性)
  • 消息头
    1. JMSDestination:消息发送的目的地,主要是指Queue和Topic
    2. JMSDeliveryMode:持久模式和非持久模式

    一条持久性的消息:应该被传送“仅仅一次”,这就意味着如果JMS提供者出现故障,该消息并不会丢失,他会在服务器恢复后再次传递
    一条非持久的消息:最多会传送一次,这意味着这服务器出现故障,该消息将永远丢失
    ActiveMQ学习(二)

    1. JMSExpiration:消息过期时间,可以设置消息在一定时间后过期,默认是永不过期

    消息过期时间,等于Destination的send方法中的timeToLive值加上发送时刻的GMT时间值。如果发送后,在消息过期时间之后消息还没有被发送到目的地,则消息被清除。

    1. JMSPriority:消息优先级,从0-9是个级别,0到4是普通消息,5到9是加急消息,JMS不要求MQ严按照这十个优先级发送消息,但必须保证加急消息要先与普通消息到达。默认是4级。
    2. JMSMessageID:唯一识别每个消息的标识由MQ产生

消息头的设置,可以像上图DeliveryMode设置一样,通过Message调用set**()方法设置,也可以在send()方法中一起设置
ActiveMQ学习(二)

  • 消息体
    1. 封装具体的消息数据
    2. 5种消息体格式
      • TextMessage:普通的字符串消息,包含一个String
      • MapMessage:一个Map类型的消息,key为String,值为Java的基本类型
      • BytesMessage:二进制数组消息,包含一个byte[]
      • StreamMessage:Java数据流,用标准流操作来顺序填充和读取
      • ObjectMessage:对象消息,包含一个可序列化的Java对象
    3. 发送和接收的消息体类型必须一致对应
  • 消息属性
    1. 如果需要除消息头字段以外的值,那么可以使用消息属性。识别/去重/重点标注等操作非常有用的方法
      ActiveMQ学习(二)

JMS的可靠性

一、持久化

持久化和非持久化,当服务器宕机后,持久化的消息在服务器重启后依然可以消费得到,而非持久化的消息则会永远丢失了

queue的持久化
  1. 可以通过textMessage.setDeliveryMode(DeliverryMode.PERSISTENT)来设置
  2. queue 默认是持久化的
topic的持久化

topic持久化的代码和queue不一样,要进行修改。

生产者
创建生产者之后,设置持久化策略

 		MessageProducer producer = session.createProducer(topic);
        producer.setDeliveryMode(DeliveryMode.PERSISTENT)

连接启动放在持久化之后

 		connection.start();

消费者(订阅者)

通过连接工厂,获得连接并设置clientId,不设置无法创建消费者(订阅者)

        Connection connection = connectionFactory.createConnection();
        connection.setClientID("z3");

得到topic后,创建持久化的消费者(订阅者),再启动连接,启动连接放在持久化之后

        TopicSubscriber durableSubscriber = session.createDurableSubscriber(topic, "xixi");
        connection.start();

测试
先启动消费者(订阅者),在启动生产者,观察控制台

  1. 首先在topic中,会产生一个消费者,并且与之前的topic的消费者不同,不会随着消费者断开连接而消失(就是框中的1,一直存在
  2. 其次在subscribers中,产生了一条记录,当消费者在线时,记录在Active Durable Topic Subscribers那一栏中,离线时,在Offline Durable Topic Subscribers中。
  3. 在第一次启动消费者之后,即使当消费者在离线状态下,生产者发送了消息,当消费者上线后,会把之前的消息接收到

    这里的消息是指,从消费者第一次启动后,没有接收到的消息

ActiveMQ学习(二)ActiveMQ学习(二)

总结

  1. 第一次消费者启动后,就相当于向MQ注册了,所以topic中会一直存在这个消费者,因此存在消费者在线离线的状态。
  2. 无论消费者是否在线,都会接收到,不在线的话,下次连接的时候,会把没有收到的消息接收下来。
  3. topic默认是非持久化的,在ActiveMQ学习(一)中讲过。
二、事务

事务偏生产者

producer

两个参数,第一个叫事务,第二个叫签收

        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

false:关闭事务,那第二个签收参数的设置需要有效,只要执行了send方法,就进入到队列中。

 		producer.send(textMessage);

true:消息需要批量发送,需要缓存区处理。先执行send,再执行commit,消息才真正提交到队列中

 		try {
            session.commit();
        }catch (Exception e){
            session.rollback();
        }finally {
            if (session!=null)
            session.close();
        }
consumer:

两个参数,第一个叫事务,第二个叫签收

        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

用法与生产者一样.

三、签收

签收偏消费者 , 对生产者的设置意义不大,但是由于creatSession方法必须要传两个参数,所以生产者一般设置Session.AUTO_ACKNOWLEDGE
ActiveMQ学习(二)
四种签收方式,常用的是前面两种,自动签收AUTO_ACKNOWLEDGE和手动签收CLIENT_ACKNOWLEDGE

非事务签收

若是AUTO_ACKNOWLEDGE , 则不需要人为去操作,收到消息后自动签收;

若是开启了手动签收

		Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

则必须在收到消息后,手动签收, 否则消息会重复消费

 		textMessage.acknowledge();
事务签收

假如开启了事务, 则无论是自动签收还是手动签收, 只要没有session.commit(), 即事务没有提交 , 则消息都会重复消费 .粗略地来讲 ,就是事务地作用范围大于签收

总结

JMS的点对点总结

ActiveMQ学习(二)

JMS的发布订阅总结

ActiveMQ学习(二)

按照配置文件启动activemq

命令 : 在bin下 , 执行 ./activemq start xbean:file:**(activemq的安装路径)/conf/active02.xml (配置文件的存放路径)

相关标签: activemq