ActiveMQ基础

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/CharJay_Lin/article/details/83051421

1.安装ActiveMQ

  1. 下载activeMq安装包 链接
  2. tar -zxvf **.tar.gz
  3. sh bin/activemq start 启动activeMQ服务
  4. http://192.168.98.165:8161/admin 账号密码 admin/admin

2.JMS

2.1简介

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。通俗点说,两个应用程序之间需要进行通信,我们使用一个JMS服务,进行中间的转发,通过JMS 的使用,我们可以解除两个程序之间的耦合。

2.2开源的JMS提供商

Apache ActiveMQ、RabbitMQ、Redis、Jafka/Kafka

2.3什么是MOM

面向消息的中间件(Message Oriented Middleware),使用消息传送提供者来协调消息传输操作。 MOM需要提供API和管理工具。 客户端调用api。 把消息发送到消息传送提供者指定的目的地
在消息发送之后,客户端会技术执行其他的工作。并且在接收方收到这个消息确认之前。提供者一直保留该消息

JMS的概念和规范 链接

image1.png | center | 564x447

3.消息传递域

3.1点对点(p2p)

  1. 每个消息只能有一个消费者
  2. 消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,都可以提取消息

image.png | left | 576x136

  1. 如果session关闭时,有一些消息已经收到,但还没有被签收,那么当消费者下次连接到相同的队列时,消息还会被签收
  2. 如果用户在receive方法中设定了消息选择条件,那么不符合条件的消息会留在队列中不会被接收
  3. 队列可以长久保存消息直到消息被消费者签收。消费者不需要担心因为消息丢失而时刻与jms provider保持连接状态

3.2发布订阅(pub/sub)

  1. 每个消息可以有多个消费者
  2. 生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS规范允许客户创建持久订阅,这在一定程度上放松了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息。

image.png | left | 402x164

  1. 订阅可以分为非持久订阅和持久订阅
  2. 当所有的消息必须接收的时候,则需要用到持久订阅。反之,则用非持久订阅

3.3Broker

本地服务

public static void main(String[] args) {
    BrokerService brokerService=new BrokerService();
    try {
        brokerService.setUseJmx(true);
        brokerService.addConnector("tcp://localhost:61616");
        brokerService.start();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

4.JMS API

ConnectionFactory 连接工厂
Connection 封装客户端与JMS provider之间的一个虚拟的连接
Session 生产和消费消息的一个单线程上下文; 用于创建producer、consumer、message、queue…
Destination 消息发送或者消息接收的目的地
Message Producer/Consumer/Listeners 消息生产者/消费者/监听者

image.png | left | 699x513

5.消息组成

消息头

包含消息的识别信息和路由信息

消息体

TextMessage
MapMessage
BytesMessage
StreamMessage 输入输出流
ObjectMessage 可序列化对象

属性

textMessage.setStringProperty("key","value");//设置属性

6.JMS的可靠性机制

JMS消息之后被确认后,才会认为是被成功消费。消息的消费包含三个阶段: 客户端接收消息、客户端处理消息、消息被确认

6.1事务性会话

Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);

如上,设置为true的时候,消息会在session.commit以后自动签收

6.2非事务性会话

Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);

在该模式下,消息何时被确认取决于创建会话时的应答模式

6.2.1 AUTO_ACKNOWLEDGE

当客户端成功从recive方法返回以后,或者[MessageListener.onMessage] 方法成功返回以后,会话会自动确认该消息(因为没有了事务,所以不需要session.commit就会自动签收)

6.2.2 CLIENT_ACKNOWLEDGE

客户端通过调用消息的textMessage.acknowledge();确认消息。
在这种模式中,如果一个消息消费者消费一共是10个消息,那么消费了5个消息,然后在第5个消息通过textMessage.acknowledge(),那么之前的所有消息都会被消确认

6.2.3 DUPS_OK_ACKNOWLEDGE

延迟确认

6.3本地事务

在一个JMS客户端,可以使用本地事务来组合消息的发送和接收。JMS Session 接口提供了commit和rollback方法。
JMS Provider会缓存每个生产者当前生产的所有消息,直到commit或者rollback,commit操作将会导致事务中所有的消息被持久存储;rollback意味着JMS Provider将会清除此事务下所有的消息记录。在事务未提交之前,消息是不会被持久化存储的,也不会被消费者消费
事务提交意味着生产的所有消息都被发送。消费的所有消息都被确认;
事务回滚意味着生产的所有消息被销毁,消费的所有消息被恢复,也就是下次仍然能够接收到发送端的消息,除非消息已经过期了

7.消息的发送策略

7.1 持久化消息

默认情况下,生产者发送的消息是持久化的。消息发送到broker以后,producer会等待broker对这条消息的处理情况的反馈

//设置消息发送端发送持久化消息的异步方式(提高性能)
connectionFactory.setUseAsyncSend(true);
//回执窗口大小设置(当生产这发送的消息大小超过时则等待)
connectionFactory.setProducerWindowSize(100);

7.2 非持久化消息

//非持久化消息设置
textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
//非持久化消息模式下,默认就是异步发送过程,如果需要对非持久化消息的每次发送的消息都获得broker的回执的话
connectionFactory.setAlwaysSyncSend(true);
//回执窗口大小设置(当生产这发送的消息大小超过时则等待)
connectionFactory.setProducerWindowSize(100);

8.consumer获取消息是pull还是(broker的主动 push)

1)默认情况下,mq服务器(broker)采用异步方式向客户端主动推送消息(push)。也就是说broker在向某个消费者会话推送消息后,不会等待消费者响应消息,直到消费者处理完消息以后,主动向broker返回处理结果

2)prefetchsize:预取消息数量
broker端一旦有消息,就主动按照默认设置的规则推送给当前活动的消费者。 每次推送都有一定的数量限制,而这个数量就是prefetchSize,假如prefetchSize=0 . 此时对于consumer来说,就是一个pull模式

//生产者设置
Destination destination=session.createQueue("first-queue?consumer.prefetchSize=100");

3)Queue
持久化消息 prefetchSize=1000
非持久化消息 prefetchSize=1000

4)topic
持久化消息 prefetchSize=100
非持久化消息 prefetchSize=32766

9.关于acknowledge为什么能够在第5次主动执行ack以后,把前面的消息都确认掉

image1.png | center | 373x32
消表示已经被consumer接收但未确认的消息。
消息确认
ACK_TYPE,消费端和broker交换ack指令的时候,还需要告知broker ACK_TYPE。
ACK_TYPE表示确认指令的类型,broker可以根据不同的ACK_TYPE去针对当前消息做不同的应对策略

REDELIVERED_ACK_TYPE (broker会重新发送该消息) 重发侧策略
DELIVERED_ACK_TYPE 消息已经接收,但是尚未处理结束
STANDARD_ACK_TYPE 表示消息处理成功

猜你喜欢

转载自blog.csdn.net/CharJay_Lin/article/details/83051421
今日推荐