ActiveMQ——Day01

ActiveMQ

1. 什么是MQ

面向消息的中间件,提供可靠的消息传递机制进行与平台无关的数据交流,基于数据通信来进行分布式系统的集成。

通过提供消息传递和消息排队模型在分布式环境下提供应用解耦,弹性收缩,冗余存储,流量削峰,异步通信,数据同步等。

发送者把消息发送给服务器,消息服务器把消息存放在若干队列/主题中,在合适的时候转发给接收者。发送和接收是异步的,无需等待的,发送者的接收者的声明周期也没有关系。在发布/订阅的模式下,可以完成一对多的通信,可以让一条消息有多个接收者(类似于微信公众号)。

用来解应用于应用之间的耦合,Spring是用来解Java类于类的耦合。

2. ActiveMQ概念

是apache出品的,完全支持JMS1.1和J2EE1.4规范的。

特点:

  1. 多种语言和协议编写客户端:Java、C、C++、C#、Ruby、Perl、Python、PHP。应用协议:Stomp、OpenWire、REST、WS Notification、XMPP、AMQP
  2. 对Spring支持,很容易的于Spring项目整合。
  3. 支持JDBC高速存储。
  4. 支持异步(ajax)
  5. 高性能集群,服务器-客户端,点对点。

3. Win 安装 ActiveMQ

下载地址:apache官网下载,这里下载的是5.15.10版本。下载大的那个,大概60M。

安装:

  1. 必须要JDK1.7以上版本,并且配置环境变量。
  2. 解压完成之后,进入64文件夹(32位系统就进入32位),然后点击activemq.bat启动。启动端口为8161,默认和用户名都是admin。

4. Linux安装ActvieMQ

建议直接上docker。

docker search activemq
docker pull webcenter/activemq

61616 为 容器使用的端口,8161为web界面管理端口,对外为8162。

访问的时候访问8362端口。

docker run -d --name activemq -p 61617:61616 -p 8162:8161 webcenter/activemq

5. 发送模式(介绍)

点对点的模式:

​ 一个生产者向一个特定的队列发布消息,一个消费者从该队列中读取消息。生产者不需要在接收者接收该消息时处于运行状态,接收者也不需要在生产者发送是处于运行状态,

发布者/订阅者模式:

​ 支持向一个特定的消息主题发布消息,订阅者接收来自特定主题的消息,发布者和消费者都不知道对方。分为临时订阅和持久订阅。临时:订阅者下线就会消失;持久订阅:在订阅者未连接时发布的消息将在订阅者重新连接之后重新发布。

6. JMS应用接口

在这里插入图片描述

  1. ConnectionFactory 连接工厂:用户用来创建JMS提供者的连接的被管对象,JMS客户通过可移植的接口访问连接,当下层实现改变时,代码不需要进行修改。根据消息类型不同,用户将使用队列连接工厂或者连接主题工厂。
  2. Connection 连接:代表了应用程序和消息服务器之间的通信链路。在获得了连接工厂后,就可以创建一个与JMS提供者的连接。根据不同的连接类型,允许用户创建会话,用来发送和接收队列或者主题的目标。
  3. Destination 目标:是一个包装了消息标标识符的被管对象,消息目标是指消息发布和接收的地点、队列或者主题。JMS管理员创建这些对象,然后用户通过JNDI发现他们。和连接工厂一样,管理员可以创建两种类型的目标,点对点模式的队列或者发布者/订阅者模型的主题。
  4. MessageConsumer 消息消费者:会话创建的对象,用于接收发送到目标的消息,可以同步和异步的接收队列和主题的消息。
  5. MessageProducer 消息生产者::会话创建的对象,用于发送消息的目标,可以创建某个目标的发送者,也可以创建一个通用的发送者,在发送消息时指定目标。
  6. message 消息:消费者和生产者之间传送的对象。分为三部分:
    1. 消息头(必选):包含用于识别和为消息寻找路由的操作设置;
    2. 消息属性(可选):额外的属性,支持提供者和用户的兼容,可以定制字段和过滤器。
    3. 消息体(可选):允许用户创建五种类型的消息(问本消息、映射消息、字节消息、流消息和对象消息)。
  7. session 会话:一个单线程的上下文,用于发送和接收消息。是连续的,按照发送的顺序一个个的接收的,支持事务,如果开启了事务,上下文将保存一组消息,直到事务被提交才发送这些消息。提交事务之前,用户可以回滚操作取消这些消息,一个会话允许用户创建消息生产者来发送消息,创建消费者来接收消息。

7. 点对点模式

7.1 创建普通maven项目

因为是普通的项目(非web项目)所有暂时没有使用Spring相关。

    <dependencies>

<!--        activeMQ-->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-all</artifactId>
            <version>5.15.5</version>
        </dependency>

<!--        slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>

<!--        lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
    </dependencies>

7.2 消息生产者 1.0 version

/**
 * 队列的消息生产者
 * @date 2020/10/7 14:12
 */
public class TestProducer {

//    服务端的ip和端口号
    private static String brokerUrl = "tcp://106.12.51.117:61617";

//    消息队列的名称
    private static String queueName = "First-Message";

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

//        创建ConnectionFactory对象,并且指定服务端的ip和端口号。
        ConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);

//        使用factory对象创建一个connection对象
        Connection connection = factory.createConnection();

//        开启连接
        connection.start();

//        创建session对象,第一个参数为是否开启事务,第二个为接收者的签收状态。
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

//        使用session对象创建destination对象
        Queue queue = session.createQueue(queueName);

//        创建生产者对象
        MessageProducer producer = session.createProducer(queue);

//        创建一个message对象
        TextMessage textMessage = session.createTextMessage();
        textMessage.setText("Hello ActiveMQ");

//        发送消息
        producer.send(textMessage);

//        关机资源
        producer.close();
        session.close();
        connection.close();

        System.out.println("消息发送成功");
    }

}

7.3 消息接收者 1.0 version(不推荐)

/**
 * 队列的消息消费者
 * @date 2020/10/7 14:26
 */
public class TestConsumer {
    //    服务端的ip和端口号
    private static String brokerUrl = "tcp://106.12.51.117:61617";

    //    消息队列的名称
    private static String queueName = "First-Message";

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

//        创建ConnectionFactory对象,并且指定服务端的ip和端口号。
        ConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);

//        使用factory对象创建一个connection对象
        Connection connection = factory.createConnection();

//        开启连接
        connection.start();

//        创建session对象,第一个参数为是否开启事务,第二个为接收者的签收状态。
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

//        使用session对象创建destination对象
        Queue queue = session.createQueue(queueName);

//        创建消费者对象
        MessageConsumer consumer = session.createConsumer(queue);

//        监听消息(可选参数为等待时间,无参数表示一直等待)
        Message receive = consumer.receive();


        if (receive instanceof TextMessage){
            TextMessage textMessage = (TextMessage) receive;
            System.out.println(textMessage.getText());
        }

//        关机资源
        consumer.close();
        session.close();
        connection.close();

        System.out.println("消息接收成功");
    }

}

7.4 异步线程监听(推荐)

使用异步线程

/**
 * 异步的队列消费者
 * @date 2020/10/7 14:41
 */
public class TestSyncConsumer {

    //    服务端的ip和端口号
    private static String brokerUrl = "tcp://106.12.51.117:61617";

    //    消息队列的名称
    private static String queueName = "First-Message";

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

//        创建ConnectionFactory对象,并且指定服务端的ip和端口号。
        ConnectionFactory factory = new ActiveMQConnectionFactory(brokerUrl);

//        使用factory对象创建一个connection对象
        Connection connection = factory.createConnection();

//        开启连接
        connection.start();

//        创建session对象,第一个参数为是否开启事务,第二个为接收者的签收状态。
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);

//        使用session对象创建destination对象
        Queue queue = session.createQueue(queueName);

//        创建消费者对象
        MessageConsumer consumer = session.createConsumer(queue);

//       异步消息监听
        consumer.setMessageListener(new MessageListener() {
            @SneakyThrows
            public void onMessage(Message message) {
                if (message instanceof  TextMessage){
                    TextMessage textMessage = (TextMessage) message;
                        System.out.println(textMessage.getText());
                }
            }
        });



//        不让程序结束
        System.in.read();

//        关机资源
        consumer.close();
        session.close();
        connection.close();

        System.out.println("消息接收成功");
    }

}

7.5 总结

每个消费只能有一个消费者,1对1的关系;没有时间上的关联性,无论消费者还是生产者发送消息的时候是否处于运行状态,都可以提取消息。被消费之后在队列中不会再存储,所以消费者不会再消费到已经被消费的消息。

7.6 补充

  1. 如果有多个消费者接收一个生产者发送的多条消息会按启动的顺序,轮询消费。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值