ActiveMQ study notes

As a message storage and distribution component, AcitveMQ involves all aspects of data interaction between the client and the broker. It not only guarantees the storage security of messages, but also provides additional means to ensure that the distribution of messages is reliable.

There are two types of message models in ActiveMQ

  1. Point -to-point (PTP) Queue messaging model
  2. Publish/subscribe (publish/subscribe, pub/sub for short) Topic messaging model


Types of Topic Queue
Overview Publish Subscribe messaging Point-to-Point
with or without status Topic data does not land by default and is stateless. Queue data will be saved as files on the mq server by default. For example, Active MQ is generally saved under $AMQ_HOME\data\kr-store\data. It can also be configured as DB storage.
Integrity Guarantee There is no guarantee that every piece of data published by the publisher will be accepted by the Subscriber. Queue ensures that each piece of data can be received by the receiver.
Whether the message will be lost Generally speaking, when a publisher publishes a message to a topic, only the sub that is listening to the topic address can receive the message; if there is no sub listening, the topic is lost. The sender sends a message to the target Queue, and the receiver can receive the message on this Queue asynchronously. Messages on the Queue will not be lost if there is no receiver to fetch them for a while.
Message Publishing and Receiving Policy One-to-many message publishing and receiving strategy, multiple subs listening to the same topic address can receive messages sent by the publisher. Sub receives notification mq server One-to-one message publishing and receiving strategy, a message sent by a sender can only be received by one receiver. After the receiver is received, it notifies the mq server that it has been received, and the mq server deletes or other operations on the messages in the queue.

message confirmation mode

The sign that the client successfully receives a message is that the message is signed for. Successfully receiving a message generally includes
the following three stages:
1. The client receives the message;
2. The client processes the message;
3. The message is acknowledged. Confirmation can be initiated by ActiveMQ or by the client, depending on the setting of the Session confirmation mode.
In a Session with a transaction, confirmation occurs automatically when the transaction commits. If the transaction is rolled back, all received messages will be delivered again.
In a Session without a transaction, when and how a message is acknowledged depends on the Session's settings.


model illustrate
Session.AUTO_ACKNOWLEDGE In the default message confirmation mode, the session will take the initiative to acknowledge the message according to the successful return of MessageConsumer.receive() or the method of callback MessageListener.onMessage().
Session.CLIENT_ACKNOWLEDGE In this mode, the client application code explicitly calls the Message.acknowledge() method to acknowledge the message.
Session.DUPS_OK_ACKNOWLEDGE In this mode, jms session can automatically confirm the receipt message, but it is a lazy message confirmation mode. Once the application system fails, some messages may be processed but there is no receipt. Once the system restarts, the message will appear again. Post a topic.
This is the fastest mode of message acknowledgment, however, the consumer must deal with repeated message processing problems. (For example: how to detect and discard the processing logic of resent messages)
Session.SESSION_TRANSACTED When applying transactions, sessions have SESSION_TRANSACTED mode implied. The response to the transaction commit is then equivalent to an acknowledgment of the message.
Transactional mode is very effective when using JMS transactions to send a set of messages (multiple messages). But avoid applying a transaction to send a message, as this would incur the extra overhead of committing or rolling back the transaction.
ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE It is not a standard message acknowledgment mode, very similar to CLIENT_ACKNOWLEDGE, but unfortunately its message acknowledgment is a way to call back. After completing the message processing, it will not go to the management message to confirm.

ActiveMQ supports two kinds of transactions

  • JMS transactions. This can be achieved by using Session's commit() and rollback(). (similar to JDBC Connection object)
  • XA transactions. XASession and XAResource are implemented by communicating with the Message Broker.

Transaction principle
In a session that supports transactions, the producer sends a message with a transactionID in the message. After the broker receives the message, it determines whether there is a transactionID, and if so, saves the message in the transaction store and waits for the commit or rollback message. So ActiveMQ's transaction is for the broker rather than the producer. Regardless of whether the session commits, the broker will receive the message.

If the producer's sending mode selects persistent, the message will enter the death queue after it expires. Before the message enters the death queue, ActiveMQ will delete the transaction ID in the message, so that the expired message will not be in the transaction, will not be saved in the transaction store, and will directly enter the death queue.


point-to-point sender

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class PTPSend {
    //连接账号
    private String userName = "";
    //连接密码
    private String password = "";
    //连接地址
    private String brokerURL = "tcp://192.168.0.130:61616";
    //connection的工厂
    private ConnectionFactory factory;
    //连接对象
    private Connection connection;
    //一个操作会话
    private Session session;
    //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
    private Destination destination;
    //生产者,就是产生数据的对象
    private MessageProducer producer;
    
    public static void main(String[] args) {
        PTPSend send = new PTPSend();
        send.start();
    }
    
    public void start(){
        try {
            //根据用户名,密码,url创建一个连接工厂
            factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
            //从工厂中获取一个连接
            connection = factory.createConnection();
            //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
            connection.start();
            //创建一个session
            //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
            //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
            //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
            //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
            //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
            destination = session.createQueue("text-msg");
            //从session中,获取一个消息生产者
            producer = session.createProducer(destination);
            //设置生产者的模式,有两种可选
            //DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
            //DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            
            //创建一条消息,当然,消息的类型有很多,如文字,字节,对象等,可以通过session.create..方法来创建出来
            TextMessage textMsg = session.createTextMessage("呵呵");
            for(int i = 0 ; i < 100 ; i ++){
                //发送一条消息
                producer.send(textMsg);
            }
            
            System.out.println("发送消息成功");
            //即便生产者的对象关闭了,程序还在运行哦
            producer.close();
            
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

点对点的接收端

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class PTPReceive {
    //连接账号
    private String userName = "";
    //连接密码
    private String password = "";
    //连接地址
    private String brokerURL = "tcp://192.168.0.130:61616";
    //connection的工厂
    private ConnectionFactory factory;
    //连接对象
    private Connection connection;
    //一个操作会话
    private Session session;
    //目的地,其实就是连接到哪个队列,如果是点对点,那么它的实现是Queue,如果是订阅模式,那它的实现是Topic
    private Destination destination;
    //消费者,就是接收数据的对象
    private MessageConsumer consumer;
    public static void main(String[] args) {
        PTPReceive receive = new PTPReceive();
        receive.start();
    }
    
    public void start(){
        try {
            //根据用户名,密码,url创建一个连接工厂
            factory = new ActiveMQConnectionFactory(userName, password, brokerURL);
            //从工厂中获取一个连接
            connection = factory.createConnection();
            //测试过这个步骤不写也是可以的,但是网上的各个文档都写了
            connection.start();
            //创建一个session
            //第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
            //第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
            //Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
            //Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
            //DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建一个到达的目的地,其实想一下就知道了,activemq不可能同时只能跑一个队列吧,这里就是连接了一个名为"text-msg"的队列,这个会话将会到这个队列,当然,如果这个队列不存在,将会被创建
            destination = session.createQueue("text-msg");
            //根据session,创建一个接收者对象
            consumer = session.createConsumer(destination);
            
            
            //实现一个消息的监听器
            //实现这个监听器后,以后只要有消息,就会通过这个监听器接收到
            consumer.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message message) {
                    try {
                        //获取到接收的数据
                        String text = ((TextMessage)message).getText();
                        System.out.println(text);
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            });
            //关闭接收端,也不会终止程序哦
//            consumer.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}




个人感觉写的比较好的相关文章

基于ActiveMQ的消息中间件系统 OneMM逻辑与物理架构设计详解

ActiveMQ消息队列的使用及应用


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325895354&siteId=291194637