ActiveMQ 3.JAVA編程實現ActiveMQ通訊

ActiveMQ

@Author:hanguixian

@Email:[email protected]

三 JAVA編程實現ActiveMQ通訊

1 JMS編程總體架構

activeMQ8

2目的地Destination

  • 隊列queue
  • 主題topic

activeMQ9

  • 比較
Topic Queue
工作模式 訂閱發佈模式,如果當前沒有訂閱者,消息將會被丟棄。如果有多個訂閱者,那麼這些訂閱者都會收到消息 負載均衡模式,如果當前沒有消費者,消息也不會丟棄如果有多個消費者,那麼-條消息也只會發送給其中-個消費者, 並且要求消費者ack信息
有無狀態 無狀態 Queue數據默認會在mq服務器上以文件形式保存,比如Active MQ一般保存在${AMQ_ HOME}\data\kr -store\data下面。也可以配置成DB存儲。
傳遞完整性 如果沒有訂閱者,消息會被丟棄 消息不會丟棄
處理效率 由於消息要按照訂閱者的數量進行復制,所以處理性能會隨着訂閱者的增加而明顯降低,並且還要結合不同消息協議自身的性能差異 由於條消息只發送給一個消費者, 所以就算消費者再多,性能也不會有明顯降低。當然不同消息協議的具體性能也是有差異的

3 在點對點的消息傳遞域中,目的地被稱爲隊列(Queue)

  • 每個消息只能有一個消費者,類似1對1的關係。好比個人快遞自己領取自己的。
  • 消息的生產者和消費者之間沒有時間上的相關性。無論消費者在生產者發送消息的時候是否處於運行狀態,消費者都可以提取消息。好比我們的發送短信,發送者發送後不見得接收者會即收即看。
  • 消息被消費後隊列中不會再存儲,所以消費者不會消費到已經被消費掉的消息。

4 在發佈訂閱消息傳遞域中,目的地被稱爲主題(topic)

  • 生產者將消息發佈到topic中, 每個消息可以有多個消費者,屬於1: N的關係
  • 生產者和消費者之間有時間上的相關性。訂閱某一個主題的消費者只能消費自它訂閱之後發佈的消息。
  • 生產者生產時,topic不保存消息它是無狀態的不落地,假如無人訂閱就去生產,那就是一條廢消息,所以,一般先啓動消費者再啓動生產者。
  • JMS規範允許客戶創建持久訂閱,這在一定程度上放鬆了時間上的相關性要求。持久訂閱允許消費者消費它在未處於激活狀態時發送的消息。好比微信公衆號訂閱

5 入門代碼

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hgx</groupId>
    <artifactId>activemq-start</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <dependencies>
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.15.10</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

  • 隊列queue生產者
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class FirstQueueProvider {

    private static final String url = "tcp://xxx:61616";

    public static void main(String[] args) throws JMSException {

        //1.創建連接工廠,按照給定的URL地址,使用默認的用戶和密碼
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        //2.通過連接工廠獲取connection並訪問
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //3.創建會話session
        //兩個參數,第一參數:事務,第二個參數:簽收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.創建目的地,具體是隊列Queue還是主題topic
        Queue queue01 = session.createQueue("queue01");
        //5.創建消息的生產者
        MessageProducer messageProducer = session.createProducer(queue01);
        //6. 通過消息生產者生產消息到MQ
        for (int i = 0; i < 3; i++) {
            //6.1 創建消息
            //文本消息
            TextMessage textMessage = session.createTextMessage("hello activeMQ--msg " + i);
            //6.2 發送到MQ
            messageProducer.send(textMessage);
        }

        //7.關閉資源
        messageProducer.close();
        session.close();
        connection.close();

        System.out.println("消息發送成功************");
    }
}
  • 隊列queue消費者
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;

public class FirstQueueConsumer {
    private static final String url = "tcp://xxx:61616";

    public static void main(String[] args) throws JMSException, IOException {
        //1.創建連接工廠,按照給定的URL地址,使用默認的用戶和密碼
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        //2.通過連接工廠獲取connection並訪問
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //3.創建會話session
        //兩個參數,第一參數:事務,第二個參數:簽收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.創建目的地,具體是隊列Queue還是主題topic
        Queue queue01 = session.createQueue("queue01");
        //5.創建消費者
        MessageConsumer messageConsumer = session.createConsumer(queue01);

        //消費方式1:同步阻塞方式(receive)訂閱者或接收者調用MessageConsumer的receive方法來接收,receive方法在接收到消息之前或超時之前將一直阻塞
//        while (true) {
//            Message message = messageConsumer.receive(6000);
//            if (message instanceof TextMessage) {
//                TextMessage textMessage = (TextMessage) message;
//                System.out.println(textMessage.getText());
//            } else {
//                break;
//            }
//
//        }

        //消費方式2:異步非阻塞方式(監聽器onMessage()方法)訂閱者或接收者通過MessageConsumer的setMessageListener註冊監聽器,當消息到達之後,系統自動調用監聽器MessageListener的onMessage方法
        messageConsumer.setMessageListener(new MessageListener() {
            public void onMessage(Message message) {
                if (message instanceof TextMessage) {
                    TextMessage textMessage = (TextMessage) message;
                    try {
                        String text = textMessage.getText();
                        System.out.println(text);
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        System.in.read();

        //關閉資源
        messageConsumer.close();
        session.close();
        connection.close();
    }

}
  • 主題topic生產者
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;

public class FirstTopicProvider {

    private static final String url = "tcp://xxx:61616";

    public static void main(String[] args) throws JMSException {

        //1.創建連接工廠,按照給定的URL地址,使用默認的用戶和密碼
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        //2.通過連接工廠獲取connection並訪問
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //3.創建會話session
        //兩個參數,第一參數:事務,第二個參數:簽收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.創建目的地,具體是隊列Queue還是主題topic
        Topic topic01 = session.createTopic("topic01");
        //5.創建消息的生產者
        MessageProducer messageProducer = session.createProducer(topic01);
        //6. 通過消息生產者生產消息到MQ
        for (int i = 0; i < 3; i++) {
            //6.1 創建消息
            //文本消息
            TextMessage textMessage = session.createTextMessage("hello activeMQ--topic msg " + i);
            //6.2 發送到MQ
            messageProducer.send(textMessage);
        }

        //7.關閉資源
        messageProducer.close();
        session.close();
        connection.close();

        System.out.println("消息發送成功************");
    }
}
  • 主題topic消費者
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;

public class FirstTopicConsumer {
    private static final String url = "tcp://xxx:61616";

    public static void main(String[] args) throws JMSException, IOException {
        //1.創建連接工廠,按照給定的URL地址,使用默認的用戶和密碼
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);
        //2.通過連接工廠獲取connection並訪問
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //3.創建會話session
        //兩個參數,第一參數:事務,第二個參數:簽收
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //4.創建目的地,具體是隊列Queue還是主題topic
        Topic topic01 = session.createTopic("topic01");
        //5.創建消費者
        MessageConsumer messageConsumer = session.createConsumer(topic01);
        messageConsumer.setMessageListener(message->{
            if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    String text = textMessage.getText();
                    System.out.println(text);
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
        System.in.read();

        //關閉資源
        messageConsumer.close();
        session.close();
        connection.close();
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章