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