activemq學習筆記


官方文檔地址
https://activemq.apache.org/index.html

簡介

activemq是實現消息隊列的一個框架,主要有兩套功能:隊列,發佈/訂閱
隊列涉及到兩個概念:生產者與消費者。一個生產消息,一個消費消息。
發佈/訂閱涉及到三個概念:發佈者,訂閱者,主題。主題其實就是一個字符串,一個名字。發佈者在這個名下發消息,所有訂閱這個主題(監控這個字符串)的訂閱者收到消息。
具體來說這其中還有很多特性,最核心的大概就是完全的解耦了吧。其他還有不少額外的功能,比如異步發送,持久化,等待隊列等等。

安裝

windows本地測試
https://activemq.apache.org/components/classic/download/
下載解壓。
啓動方法一:apache-activemq-5.15.11\bin\win64\InstallService.bat 註冊服務,之後在服務頁面將activeMq服務開啓即可使用。
啓動方法二:在dos進入目錄apache-activemq-5.15.11\bin,執行activemq start來啓動(關閉窗口會導致服務關閉)
這種方法在windows下問題不少,需要計算機名中沒有- ,Internet Connection Sharing (ICS)服務必須關閉,不然會報端口占用的錯誤。address already in use: JVM_BIND

在瀏覽器中輸入http://127.0.0.1:8161進入管理頁面。
默認賬號/密碼是admin/admin
在這裏插入圖片描述

示例

添加依賴包

		<dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.9.0</version>
        </dependency>

隊列測試代碼

https://activemq.apache.org/hello-world
最簡單的一套測試代碼

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * Hello world!
 */
public class App {

    public static void main(String[] args) throws Exception {
    	org.apache.activemq.broker.jmx.ManagementContext a;
        thread(new HelloWorldProducer(), false);
        thread(new HelloWorldProducer(), false);
        thread(new HelloWorldConsumer(), false);
        
        thread(new HelloWorldConsumer(), false);
        thread(new HelloWorldConsumer(), false);
        thread(new HelloWorldConsumer(), false);
//        Thread.sleep(1000);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        Thread.sleep(1000);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldProducer(), false);
//        Thread.sleep(1000);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldConsumer(), false);
//        thread(new HelloWorldProducer(), false);
    }

    public static void thread(Runnable runnable, boolean daemon) {
        Thread brokerThread = new Thread(runnable);
        brokerThread.setDaemon(daemon);
        brokerThread.start();
    }

    public static class HelloWorldProducer implements Runnable {
        public void run() {
            try {
                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");
                
                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

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

                // Create the destination (Topic or Queue)
                //創建主題或隊列
                Destination destination = session.createQueue("TEST.FOO");
                //session.createTopic("TOPIC.FOO");

                // Create a MessageProducer from the Session to the Topic or Queue
                MessageProducer producer = session.createProducer(destination);
                //持久化
                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

                // Create a messages
                String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode();
                TextMessage message = session.createTextMessage(text);

                // Tell the producer to send the message
                //發送消息
                //System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName());
                System.out.println("Sent message: "+ this.hashCode() + " : " + Thread.currentThread().getName());
                producer.send(message);

                // Clean up
                session.close();
                connection.close();
            }
            catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }
    }

    public static class HelloWorldConsumer implements Runnable, ExceptionListener {
        public void run() {
            try {

                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost");

                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

                connection.setExceptionListener(this);

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

                // Create the destination (Topic or Queue)
                Destination destination = session.createQueue("TEST.FOO");

                // Create a MessageConsumer from the Session to the Topic or Queue
                MessageConsumer consumer = session.createConsumer(destination);

                // Wait for a message
                Message message = consumer.receive(1000);

                if (message instanceof TextMessage) {
                    TextMessage textMessage = (TextMessage) message;
                    String text = textMessage.getText();
                    System.out.println("Received: " + text);
                } else {
                    System.out.println("Received: " + message);
                }

                consumer.close();
                session.close();
                connection.close();
            } catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }

        public synchronized void onException(JMSException ex) {
            System.out.println("JMS Exception occured.  Shutting down client.");
        }
    }
}

執行後控制檯輸出

Sent message: 365885423 : Thread-0
Sent message: 1671555210 : Thread-1
Received: Hello world! From: Thread-1 : 1671555210
Received: Hello world! From: Thread-0 : 365885423
Received: null
Received: null

代碼很簡單沒有什麼需要解釋的,但是有一個問題是,執行的結果無法在監控頁面http://127.0.0.1:8161/admin/queues.jsp 中顯示出來,推測應該是與這個vm的協議有關,將連接url換成tcp://127.0.0.1:61616 執行後可以在監控頁面顯示。具體要替換的url在
apache-activemq-5.15.11\conf\activemq.xml 中有配置
在這裏插入圖片描述

package yyst.myTest.activemq;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.ExceptionListener;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * Hello world!
 */
public class App {

	//private static final String ACTIVEMQ_URL = "vm://localhost";
	private static final String ACTIVEMQ_URL = "tcp://127.0.0.1:61616";
	
    public static void main(String[] args) throws Exception {
        thread(new HelloWorldProducer(), false);//發送
        thread(new HelloWorldProducer(), false);
        thread(new HelloWorldConsumer(), false);//接收
    }

    public static void thread(Runnable runnable, boolean daemon) {
        Thread brokerThread = new Thread(runnable);
        brokerThread.setDaemon(daemon);
        brokerThread.start();
    }

    public static class HelloWorldProducer implements Runnable {
        public void run() {
            try {
                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
                
                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

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

                // Create the destination (Topic or Queue)
                //創建主題或隊列
                Destination destination = session.createQueue("TEST.FOO");
                //session.createTopic("TOPIC.FOO");

                // Create a MessageProducer from the Session to the Topic or Queue
                MessageProducer producer = session.createProducer(destination);
                //持久化
                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

                // Create a messages
                String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode();
                TextMessage message = session.createTextMessage(text);

                // Tell the producer to send the message
                //發送消息
                //System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName());
                System.out.println("Sent message: "+ this.hashCode() + " : " + Thread.currentThread().getName());
                producer.send(message);

                // Clean up
                session.close();
                connection.close();
            }
            catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }
    }

    public static class HelloWorldConsumer implements Runnable, ExceptionListener {
        public void run() {
            try {

                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);

                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

                connection.setExceptionListener(this);

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

                // Create the destination (Topic or Queue)
                Destination destination = session.createQueue("TEST.FOO");

                // Create a MessageConsumer from the Session to the Topic or Queue
                MessageConsumer consumer = session.createConsumer(destination);

                // Wait for a message
                Message message = consumer.receive(1000);

                if (message instanceof TextMessage) {
                    TextMessage textMessage = (TextMessage) message;
                    String text = textMessage.getText();
                    System.out.println("Received: " + text);
                } else {
                    System.out.println("Received: " + message);
                }

                consumer.close();
                session.close();
                connection.close();
            } catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }

        public synchronized void onException(JMSException ex) {
            System.out.println("JMS Exception occured.  Shutting down client.");
        }
    }
}

在這裏插入圖片描述
如果僅僅是測試的話,也可以再這裏進行
http://127.0.0.1:8161/admin/send.jsp
在這裏插入圖片描述

發佈/訂閱

與隊列的代碼差不多,基本就是createQueue改成createTopic,然後消費者的接收方法改爲監聽。
生產者

    public static class HelloWorldTopicProducer implements Runnable {
        public void run() {
            try {
                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);
                
                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

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

                // Create the destination (Topic or Queue)
                //創建主題或隊列
                Destination destination = session.createTopic("TOPIC.FOO");
                //session.createTopic("TOPIC.FOO");

                // Create a MessageProducer from the Session to the Topic or Queue
                MessageProducer producer = session.createProducer(destination);
                //持久化
                producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
                
                // Create a messages
                String text = "Hello world! From: " + Thread.currentThread().getName() + " : " + this.hashCode();
                TextMessage message = session.createTextMessage(text);

                // Tell the producer to send the message
                //發送消息
                //System.out.println("Sent message: "+ message.hashCode() + " : " + Thread.currentThread().getName());
                System.out.println("Sent message: "+ this.hashCode() + " : " + Thread.currentThread().getName());
                producer.send(message);

                // Clean up
                session.close();
                connection.close();
            }
            catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }
    }

消費者

    public static class HelloWorldTopicConsumer implements Runnable, ExceptionListener {
        public void run() {
            try {

                // Create a ConnectionFactory
                ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ACTIVEMQ_URL);

                // Create a Connection
                Connection connection = connectionFactory.createConnection();
                connection.start();

                connection.setExceptionListener(this);

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

                // Create the destination (Topic or Queue)
                Destination destination = session.createTopic("TOPIC.FOO");

                // Create a MessageConsumer from the Session to the Topic or Queue
                MessageConsumer consumer = session.createConsumer(destination);

                consumer.setMessageListener(new MessageListener() {
                    public void onMessage(Message message) {
                        TextMessage textMessage = (TextMessage) message;
                        try {
                            System.out.println("消費的消息:" + textMessage.getText());
                        } catch (JMSException e) {
                            e.printStackTrace();
                        }
                    }
                });

//                consumer.close();
//                session.close();
//                connection.close();
            } catch (Exception e) {
                System.out.println("Caught: " + e);
                e.printStackTrace();
            }
        }

        public synchronized void onException(JMSException ex) {
            System.out.println("JMS Exception occured.  Shutting down client.");
        }
    }

測試代碼

    	thread(new HelloWorldTopicConsumer(), false);
    	thread(new HelloWorldTopicProducer(), false);
    	Thread.sleep(1000);
    	thread(new HelloWorldTopicConsumer(), false);
    	thread(new HelloWorldTopicConsumer(), false);
    	Thread.sleep(1000);
    	thread(new HelloWorldTopicProducer(), false);

輸出

Sent message: 514035740 : Thread-1
消費的消息:Hello world! From: Thread-1 : 514035740
Sent message: 1898887496 : Thread-6
消費的消息:Hello world! From: Thread-6 : 1898887496
消費的消息:Hello world! From: Thread-6 : 1898887496
消費的消息:Hello world! From: Thread-6 : 1898887496
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章