ActiveMQ快速入门(上)

下载安装

  1. 官网下载.
  2. 解压后进入 bin 目录 ./activemq start 启动
  3. activemq默认端口为 61616
  4. activemq 前台端口默认为 8161
  5. 用户名密码默认是 admin admin
  6. 在这里插入图片描述

基本概念

引入依赖

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

        <dependency>
            <groupId>org.apache.xbean</groupId>
            <artifactId>xbean-spring</artifactId>
            <version>4.5</version>
        </dependency>

JMS 总体架构图

在这里插入图片描述

TOPIC. (主备)

在这里插入图片描述

QUEUE(负载均衡)

在这里插入图片描述

编码

Queue

生产者代码

    public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

        connection.start();

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

        Queue queue = session.createQueue("my-queue");

        MessageProducer producer = session.createProducer(queue);

        TextMessage textMessage = session.createTextMessage("哈哈,这是消息");

        producer.send(textMessage);

        producer.close();

        session.close();

        connection.close();
    }

消费者代码

  public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

        connection.start();

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

        Queue queue = session.createQueue("my-queue");

        MessageConsumer consumer = session.createConsumer(queue);

        while (true){
            Message message = consumer.receive();
            if (message == null){
                break;
            }
            TextMessage msg = (TextMessage)message;
            System.out.println(msg.getText());
        }

        consumer.close();
        session.close();
        connection.close();
    }

Topic

消费者

  public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

        connection.start();

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

        Topic topic = session.createTopic("my-topic");

        MessageConsumer consumer = session.createConsumer(topic);

        while (true){
            Message message = consumer.receive();
            if (message == null){
                break;
            }

            TextMessage msg = (TextMessage)message;
            System.out.println(msg.getText());
        }

        consumer.close();

        session.close();

        connection.close();
    }

生产者

    public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

        connection.start();

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

        Topic topic = session.createTopic("my-topic");

        MessageProducer producer = session.createProducer(topic);

        TextMessage textMessage = session.createTextMessage("哈哈,这是topic的消息");

        producer.send(textMessage);

        producer.close();

        session.close();

        connection.close();
    }

Topic和Queue的对比

  1. 当没有消费者的时候,发送到Queue 的数据,在消费者启动之后会消费之前的数据.而Topic的消息如果发送的时候没有消费者,那么发送了就丢失了
  2. Queue 是负载均衡策略,所以再多的消费者,queue的性能也不会有影响,而topic会随着消费者增多,性能下降

JMS

java message service 是JavaEE 的一个技术

JMS 组成结构和特点

  1. JMS Provider
    实现JMS规范的消息中间件,也就是MQ服务器
  2. JMS Producer
    消息生产者,是MQ客户端
  3. JMS Consumer
    消息消费者,是MQ客户端

JMS Message

  1. 消息头
    JMSDestination: message 可以设置目的地, 亲测无效,目的地还是按照producer指定发送
    JMSDeleveryMode: 分为持久化和非持久化, 非持久化的消息在MQ重启之后就消失了
    JMSExpiration: 超时时间,不懂有什么用
    JMSPriority : 优先级,也觉得没什么用
    JMSMessageID : 消息的唯一id,可以用来保证消息的幂等性
  2. 消息体
    有5中消息体,常用的就用 TextMessage 就好了,Map 其他格式都可以自己转换
  3. 消息属性
    一个kv键值对.在message 中 setStringProperty 之后可以从消费者里面取出来.

消息的可靠性

消息的持久化

	/**
	消息设置持久化
	*/
    textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT);

    textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
	/**
	生产者设置持久化
	*/
	producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    
    producer.setDeliveryMode(DeliveryMode.PERSISTENT);

Queue 默认就是持久化的模式,而Topic 默认是非持久化模式

消息的可靠性分为两个方面,一个是生产者发送到MQ时候的可靠性,另一个是MQ发送到消费者之前,消息不会丢失

Queue 的持久化是默认的,而Topic 的持久化需要修改代码
因为topic的生产者就算设置了持久化的参数,根据topic 的性质,在发送的时候,没有消费者,这条消息也就作废了,所以代码需要修改
消息的生产者. connection.start 方法要往后放.

  public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

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

        Topic topic = session.createTopic("persistent-topic");

        MessageProducer producer = session.createProducer(topic);


        producer.setDeliveryMode(DeliveryMode.PERSISTENT);

        TextMessage textMessage = session.createTextMessage("这是持久化的topic消息");

        connection.start();

        producer.send(textMessage);

        producer.close();

        session.close();

        connection.close();

    }

消费者则需要在 connection 上添加id 和 使用 不一样的consumer

    public static void main(String[] args) throws Exception{
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");

        Connection connection = factory.createConnection();

        connection.setClientID("consumer-01");

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

        Topic topic = session.createTopic("persistent-topic");


        TopicSubscriber consumer = session.createDurableSubscriber(topic, "");


        connection.start();

        while (true){
            Message message = consumer.receive();
            if (message == null){
                break;
            }

            TextMessage msg = (TextMessage)message;
            System.out.println(msg.getText());
        }

        consumer.close();

        session.close();

        connection.close();
    }

topic持久化需要先启动一次消费者,让MQ知道有这么一个id的消费者想要消费这个topic,当该消费者离线再次上线的时候MQ就会把没有消费的消费再发送给消费者

事务

当 connection 在创建 session 的时候,需要传两个参数, 第一个是 是否启用事务 第二个是 签收的级别

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

生产者
如果事务是false , producer 执行send操作,消息就会被发送到队列中.
而如果是true,则需要执行session.commit操作,消息才会被发送到MQ中

消费者
如果消费者配置事务为true,则消费之后也需要将session.commit,不然下次启动还会消费到同样的消息.

ACK模式. 消费者和MQ之间的事情

ACK模式适用于非事务情况,事务的情况下ACK参数无效
消费结束的消息需要调用 acknowledge 方法告诉MQ这条消息已经成功消费了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值