ActiveMQ 详细入门教程

 

一、JMS(Java Message Service)

它是一种与厂商无关的API,用来访问消息收发系统消息。它类似于JDBC,JDBC是可以用来访问不同关系数据库的API,而JMS则提供同样与厂商无关的访问消息收发服务的方法,这样就可以通过消息收发服务实现从一个JMS客户机向另一个JMS客户机发送消息,所需要的是厂商支持JMS。换句话说,JMS是Java平台上有关面向消息中间件的技术规范。

 

二、简单了解JMS

1. JMS包括以下基本构件:

1)连接工厂,是客户用来创建连接的对象,ActiveMQ提供的是ActiveMQConnectionFactory;

2)连接connection;

3)会话session,是发送和接收消息的上下文,用于创建消息生产者,消息消费者,相比rocketMQ会话session是提供事务性的;

4)目的地destination,指定生产消息的目的地和消费消息的来源对象;

     生产者、消费者,由会话创建的对象,顾名思义。

2. 消息通信机制:

(1)点对点模式(p2p),每个消息只有1个消费者,它的目的地称为queue队列; 

(2) 发布/订阅模式,每个消息可以有多个消费者,而且订阅一个主题的消费者,只能消费自它订阅之后发布的消息。

(3)消息确认机制

Session.AUTO_ACKNOWLEDGE,直接使用receive方法。
Session.CLIENT_ACKNOWLEDGE,通过消息的acknowledge 方法确认消息。
Session.DUPS_ACKNOWLEDGE,该选择只是会话迟钝第确认消息的提交。如果JMS provider 失败,那么可能会导致一些重复的消息。如果是重复的消息,那么JMS provider 必须把消息头的JMSRedelivered 字段设置为true。

 

三、ActiveMQ的引言

ActiveMQ是由Apache出品的,一款最流行的,能力强劲的消息中间件(MOM:Message Orient middleware)。并且是对消息通信规范JMS的一种具体实现

 

四、ActiveMQ的特点

1. 将数据从一个应用程序传送到另一个应用程序,或者从软件的一个模块传送到另外一个模块; 
2. 负责建立网络通信的通道,进行数据的可靠传送。 
3. 保证数据不重发,不丢失 
4. 能够实现跨平台操作,能够为不同操作系统上的软件集成技工数据传送服务

 

五、ActiveMQ的使用场景

1.应用解耦

2.异步消息

3.流量削锋

4.消息通讯

更详细的使用场景参考这篇博客  消息中间件(二)MQ使用场景

 

六、ActiveMQ在linux中的安装

1. 安装JDK

1.导入JDK压缩包
2.解压  tar -zxvf ....
3.vi /etc/profile
4.添加
    export JAVA_HOME=JDK安装的路径
    export PATH=$PATH:$JAVA_HOME/bin
5.source /etc/profile
6.java -version

2. 安装ActiveMQ

1.导入ActiveMQ的压缩包
2.解压
3.启动
	./activeMq start
4.开启日志
	tail -f activeMq.log  开启实时的日志
5.通过客户端工具连接
	ip:8161/admin
	用户名:admin
	密码:admin
	用户名,密码在哪看
	vi /conf/users.properties
	admin=admin

3. 浏览器访问  192.168.174.888:8161

 

七、ActiveMQ与java集成

1.引入依赖

<dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-core</artifactId>
      <version>5.7.0</version>
</dependency>

2. P2P(queue、点对点 )测试代码 (一个生产者,两个消费者)

public class TestP2PProduct {

    @Test
    //生产者
    public void testProduct() throws JMSException {
        //1、创建连接工厂
        String brokerURL = "tcp://192.168.174.139:61616";
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        //2、创建连接
        Connection connection = connectionFactory.createConnection();
        //3、创建回话             是否开启事务        开启自动回执
        Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
        //4、创建生产者
        Destination destination = new ActiveMQQueue("QUEUE-1");
        MessageProducer producer = session.createProducer(destination);
        //5、创建消息
        for (int i=1;i<=100;i++){
            TextMessage textMessage = session.createTextMessage("生产的Message"+i);
            //6、生产者发布消息
            producer.send(textMessage);
        }
        //7、提交
        session.commit();
        //8、释放资源
        connection.close();
        producer.close();
        session.close();
    }

    //消费者1
    @Test
    public void testConsumer() throws JMSException {
        String brokerURL = "tcp://192.168.174.139:61616";
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        Connection connection = connectionFactory.createConnection();
        //注意:
        connection.start();
        Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
        Destination destination = new ActiveMQQueue("QUEUE-1");
        MessageConsumer consumer = session.createConsumer(destination);
        //消费
        for (int i=1;i<=100;i++){
            TextMessage textMessage = (TextMessage) consumer.receive();
            System.out.println("消费者1"+textMessage.getText());
        }
        session.commit();
        connection.close();
        consumer.close();
        session.close();
    }

    //消费者2
    @Test
    public void testConsumer2() throws JMSException {
        String brokerURL = "tcp://192.168.174.139:61616";
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        Connection connection = connectionFactory.createConnection();
        //注意:
        connection.start();
        Session session = connection.createSession(true,Session.AUTO_ACKNOWLEDGE);
        Destination destination = new ActiveMQQueue("QUEUE-1");
        MessageConsumer consumer = session.createConsumer(destination);
        //消费
        for (int i=1;i<=100;i++){
            TextMessage textMessage = (TextMessage) consumer.receive();
            System.out.println("消费者2"+textMessage.getText());
        }
        session.commit();
        connection.close();
        consumer.close();
        session.close();
    }
}

先启动两个消费者,消费者会一直处于等待状态,再启动生产者,结果如下:

队列(p2p)模式的消息,是只会被一个消费者所使用的,而不会被共享,这也就是和发布/订阅模式的差别

3. 发布/订阅模式 测试代码(一个发布者,两个订阅者)

//发布订阅
public class TestTopicProduct {

    public static void main(String[] args) throws JMSException {
        //创建发布的连接工厂
        String brokerURL = "tcp://192.168.174.139:61616";
        TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        //创建连接
        TopicConnection topicConnection = connectionFactory.createTopicConnection();
        //创建回话
        TopicSession topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
        //创建发布
        ActiveMQTopic topic = new ActiveMQTopic("TOPIC-1");
        TopicPublisher publisher = topicSession.createPublisher(topic);
        //创建主题
        for (int i=1;i<=100;i++){
            TextMessage textMessage = topicSession.createTextMessage("Hello-TestTopic "+i);
            //发布
            publisher.send(textMessage);
        }
        //提交
        topicSession.commit();
        //释放
        topicConnection.close();
        topicSession.close();
        publisher.close();
    }
}
public class TestTopicConsumer {
    //订阅者1
    @Test
    public void testConsumer1() throws JMSException {
        String brokerURL = "tcp://192.168.174.139:61616";
        TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        //2.创建连接
        TopicConnection topicConnection = connectionFactory.createTopicConnection();
        topicConnection.start();
        //3.创建回话
        TopicSession topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
        Topic topic = new ActiveMQTopic("TOPIC-1");
        MessageConsumer consumer = topicSession.createConsumer(topic);
        while (true) {
            Message receive = consumer.receive();
            TextMessage textMessage = (TextMessage) receive;
            if (textMessage != null) {
                System.out.println("1 号"+textMessage.getText());
            }else{
                break;
            }
        }

    }

    //订阅者2
    @Test
    public void testConsumer2() throws JMSException {
        String brokerURL = "tcp://192.168.174.139:61616";
        TopicConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerURL);
        //2.创建连接
        TopicConnection topicConnection = connectionFactory.createTopicConnection();
        topicConnection.start();
        //3.创建回话
        TopicSession topicSession = topicConnection.createTopicSession(true, Session.AUTO_ACKNOWLEDGE);
        Topic topic = new ActiveMQTopic("TOPIC-1");
        MessageConsumer consumer = topicSession.createConsumer(topic);
        while (true) {
            Message receive = consumer.receive();
            TextMessage textMessage = (TextMessage) receive;
            if (textMessage != null) {
                System.out.println("2 号"+textMessage.getText());
            }else{
                break;
            }
        }
    }
}

先启动两个消费者,再启动生产者,结果如下:

从结果可以看出,这种模式消费者都各自消费了所有生产者的消息,这就是共享性消息的发布/订阅模式,这就是和队列(p2p)模型的区别。

注意:发布/订阅模式中,如果消费者是在生产者产生消息之启动的,那么是不会对之前的消息进行消费的,这一点和队列模式是有区别的

    ActiveMQ 与 Springboot 的集成

 

发布了118 篇原创文章 · 获赞 20 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/zhang33565417/article/details/100566151