消息中间件编程——ActiveMQ

一、引言

1.实验目的

1、理解消息中间件编程,并选择一个中间件平台(ActiveMQ),介绍其基本原理,编程方法(介绍案例),并进行应用开发(最好与spring开发结合起来)。

2、应用开发:模拟多个10000个节点的消息传递和订阅关系。

   选择生产者和订阅者的数量,分别为n1和n2;
   
   指定n1和n2的订阅关系S;【多对多的关系,且可根据规则进行内容的筛选】
   
   模拟n1产生内容的情形。调整n1,n2,以及S,分析整个系统的运行效率。

2.环境配置

  • 操作系统:Windows 10 X64
  • 编程工具:Intellij IDEA 2019.2×64

二、ActiveMQ介绍

1.概述

ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。在介绍activemq之前,先简单介绍JMS,它是J2EE的13个规范之一,提供的是消息中间件的规范。

(1)JMS简介

JMS包括以下基本构件:

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

2、连接connection;

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

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

5、生产者,由会话创建的对象。

6、消费者,由会话创建的对象。

(2)消息通信机制

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

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

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

2.安装

(1)在清华镜像下载

下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/activemq/5.15.12/

win10可以下载第三个,5.15.12版本:
在这里插入图片描述

(2)下载完解压完目录如下

在这里插入图片描述

(3)启动ActiveMQ服务

在解压目录下的bin/win64,右键以管理员身份运行activemq.bat
在这里插入图片描述

(4)登录,验证是否启动成功

在这里插入图片描述

(5)进入管理页面

用户名和密码都是admin
在这里插入图片描述
管理页面如下:
在这里插入图片描述

3.案例实现(点对点模式)

(1)导入pom依赖

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

(2)创建生产者

import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.*;

/**
 * @Author Administrator
 * @Description: IntelliJ IDEA
 * @create 2020/5/1218:17
 */
public class MqQueueProduct {

    private static final String url="tcp://127.0.0.1:61616";//服务地址,端口默认61616
    private static final String queueName="queue-test";//要创建的消息名称
    public static void main(String[] args) throws JMSException {
        //1.创建ConnectiongFactory,绑定地址
        ConnectionFactory factory=new ActiveMQConnectionFactory(url);
        //2.创建Connection
        Connection connection= factory.createConnection();
        //3.启动连接
        connection.start();
        //4.创建会话
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建一个目标
        Destination destination=session.createQueue(queueName);
        //6.创建一个生产者
        MessageProducer producer=session.createProducer(destination);
        for (int i = 0; i < 20; i++) {
            //7.创建消息
            TextMessage textMessage=session.createTextMessage("我是消息生产者:"+i);
            //8.发送消息
            producer.send(textMessage);
            System.out.println("发送消息:"+i);
        }
        connection.close();
    }
}

运行:
在这里插入图片描述
在ActiveMQ的Queues中查看,消息队列中有了20个消息:
在这里插入图片描述

(3)创建消费者

import javax.jms.*;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * @Author Administrator
 * @Description: IntelliJ IDEA
 * @create 2020/5/1218:29
 */
public class MqQueueConsumer {
    private static final String url="tcp://127.0.0.1:61616";//端口默认
    private static final String queueName="queue-test";//要消费的消息名称
    public static void main(String[] args) throws JMSException {
        //1.创建ConnectiongFactory,绑定地址
        ConnectionFactory factory=new ActiveMQConnectionFactory(url);
        //2.创建Connection
        Connection connection= factory.createConnection();
        //3.启动连接
        connection.start();
        //4.创建会话
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建一个目标
        Destination destination=session.createQueue(queueName);
        //6.创建一个消费者
        MessageConsumer consumer=session.createConsumer(destination);
        //7.创建一个监听器
        consumer.setMessageListener(new MessageListener() {
            public void onMessage(Message arg0) {
                TextMessage textMessage=(TextMessage)arg0;
                try {
                    System.out.println("接收消息:"+textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

运行:
在这里插入图片描述
查看ActiveMQ的queues,可以看到生产者的消息被消费者接收了:
在这里插入图片描述

三、应用开发(和Spring结合)

模拟多个10000个节点的消息传递和订阅关系。(发布/订阅模式)

Subscriber只有在订阅了主题Topic后,才能接收到Publisher发送的消息。这种关系如下图所示:
在这里插入图片描述

(1)创建生产者

import javax.jms.*;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * @Author Administrator
 * @Description: IntelliJ IDEA
 * @create 2020/5/1313:20
 */
public class MqTopicProduct {

    private static final String url="tcp://127.0.0.1:61616";//服务地址,端口默认61616
    private static final String topicName="topic-test";//要创建的消息名称
    public static void main(String[] args) throws JMSException {
        //1.创建ConnectiongFactory,绑定地址
        ConnectionFactory factory=new ActiveMQConnectionFactory(url);
        //2.创建Connection
        Connection connection= factory.createConnection();
        //3.启动连接
        connection.start();
        //4.创建会话
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建一个目标
        Destination destination=session.createTopic(topicName);
        //6.创建一个生产者
        MessageProducer producer=session.createProducer(destination);
        for (int i = 0; i < 10000; i++) {
            //7.创建消息
            TextMessage textMessage=session.createTextMessage("我是消息生产者:"+i);
            //8.发送消息
            producer.send(textMessage);
            System.out.println("发送消息:"+i);
        }
        connection.close();
    }
}

运行:
在这里插入图片描述
查看ActiveMQ的Topics,可以看到消息队列中有10000条消息:
在这里插入图片描述

(2)创建消费者

import javax.jms.*;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * @Author Administrator
 * @Description: IntelliJ IDEA
 * @create 2020/5/1313:18
 */
public class MqTopicConsumer {

    private static final String url="tcp://127.0.0.1:61616";//端口默认
    private static final String topicName="topic-test";//要消费的消息名称
    public static void main(String[] args) throws JMSException {
        //1.创建ConnectiongFactory,绑定地址
        ConnectionFactory factory=new ActiveMQConnectionFactory(url);
        //2.创建Connection
        Connection connection= factory.createConnection();
        //3.启动连接
        connection.start();
        //4.创建会话
        Session session=connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //5.创建一个目标
        Destination destination=session.createTopic(topicName);
        //6.创建一个消费者
        MessageConsumer consumer=session.createConsumer(destination);
        //7.创建一个监听器
        consumer.setMessageListener(new MessageListener() {
            public void onMessage(Message arg0) {
                TextMessage textMessage=(TextMessage)arg0;
                try {
                    System.out.println("接收消息:"+textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

运行:
在这里插入图片描述
查看ActiveMQ的Topics,可以看到发布者发布的消息被接收(订阅)了:
在这里插入图片描述

四、ActiveMQ与其他平台的差异介绍

1、开发语言方面:ActiveMQ和RocketMQ主要为java,RabbitMQ是Erlang,Kafka用的是Scala

2、资料文档方面:ActiveMQ和RabbitMQ参考资料多,Kafka中等,RocketMQ参考资料较少

3、支持的协议方面:ActiveMQ:OpenWire、STOMP、REST、XMPP、AMQP;Kafka:自己定义的一套,基于TCP;RabbitMQ:AMQP;RocketMQ:自己定义的一套

4、数据存储方面:ActiveMQ:内存、磁盘、数据库。支持少量堆积。Kafka:内存、磁盘、数据库。支持大量堆积。RabbitMQ:内存、磁盘。支持少量堆积。RocketMQ:磁盘。支持大量堆积。

5、总体上看:ActiveMQ基于java开发,是已经很完备消息队列,非常稳定,大多数的解决方案网上都能找到,缺点是吞吐量相比RocketMQ,Kafka还不够大,并且版本现在更新的很慢了,社区不活跃,RabbitMQ用的Erlang开发,并发超强,但不好定制化。

五、总结

1、在做应用开发(发布/订阅模式)的时候,这个模式和点对点模式不同,它需要先运行消费者再运行生产者,消费者才能接受到消息。

2、队列模式(点对点)的消费者在运行后也能收到之前的消息,不过属于轮流进行消费,每个消费者接收不到完整的消息。

3、主题模式(发布/订阅)的消费者在运行后只能收到之后的消息,运行之前生产的消息接收不到;并且每个消费者都能接收全部的消息。

六、参考链接

[1] 手把手教你如何玩转消息中间件(ActiveMQ)

[2] 消息中间件_ActiveMQ入门教程

[3] 常用消息中间件的对比(ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值