activeMQ特性与代码使用讲解

首先看一下在java程序里面是如何利用jmsAPI使用activeMQ的
首先是发送一条消息的简单demo’

public class JMSCommonProducer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                connection.start();
        //创建队列(有则不创建)
        Destination destination = session.createQueue("garine-queue");
        //创建生产者
        MessageProducer producer = session.createProducer(destination);
        //创建文本消息,有多种消息类型
        TextMessage textMessage = session.createTextMessage("Hello garine");
        //发送消息
        producer.send(textMessage);
        System.out.println("over");
    }
}

然后就是消费一条消息的简单demo


public class JMSCommonConsumer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列(有则不创建)
        Destination destination = session.createQueue("garine-queue");
        //创建生产者
        MessageConsumer consumer = session.createConsumer(destination);
        //接受文本消息,阻塞等待
        TextMessage textMessage = (TextMessage) consumer.receive();
        System.out.println(textMessage.getText());
        session.close();
    }
}

基于以上的基本代码展开,介绍activemq的一些特性

JMS消息类型
除了基础demo中使用的TextMessage,jms还支持其他四种消息类型,总共有五种:
TextMessage:java.lang.String 对象,如 xml 文件内 容
MapMessage:键/值对的集合,键值是String对象,值 类型可以是Java任何基本类型
BytesMessage:字节对象
StreamMessage:java中的io流
ObjectMessage:可序列化的java对象
Message:没有消息体,只有消息头部和属性的JMS消息

下面尝试传送ObjectMessage,新建一个可序列化对象,发送代码如下:

public class JMSObjectProducer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列(有则不创建)
        Destination destination = session.createQueue("garine-queue");
        //创建生产者
        MessageProducer producer = session.createProducer(destination);
        //创建文本消息,有多种消息类型
        ObjectMessage objectMessage = session.createObjectMessage(new SerializableObject());
        //发送消息
        producer.send(objectMessage);
        System.out.println("over");
        session.close();
    }
}

接收端代码

public class JMSObjectConsumer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        connectionFactory.setTrustAllPackages(true);
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列(有则不创建)
        Destination destination = session.createQueue("garine-queue");
        //创建生产者
        MessageConsumer consumer = session.createConsumer(destination);
        //接受文本消息,阻塞等待
        ObjectMessage objectMessage = (ObjectMessage) consumer.receive();
        System.out.println(objectMessage.getObject());
        session.close();
    }
}

总之就是按照我们的需求构造相应的消息,JMS规范让我们使用activeMQ进行java服务之间消息通信时简单快捷,灵活性很高。

消息模型
跟大多数消息中间件一样,activeMQ提供p2p,pub/sub的消息模型。
point to point:点对点模型到消息只能被一个消费者消费;activemq中队列形式是p2p模型;一个队列可以多个消费者,但是只能被一个消费者消费;当无消费者时消息可以积压在队列,等到消费者上线时再消费也可以;
publish/subcrible:发布/订阅模式,一条消息能给多个消费者消费;activemq中topic形式是pub/sub模式;
而针对publish/subcrible,又延伸出持久订阅和非持久订阅两种模式,需要注意的是,这是针对topic的消息模型而言的
非持久订阅:只能接收在线时topic发布到消息
持久订阅:能够接收在下线时topic发布到消息,不过在下线之前必须已经注册了持久订阅到topic,这样当离线时,broker会为这个持久订阅保留消息
demo中演示的是p2p形式的代码,下面看一下topic持久化订阅的如何实现

public class JMSTopicProducer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创topic(有则不创建)
        Topic destination = session.createTopic("garine-topic");
        //创建生产者
        MessageProducer producer = session.createProducer(destination);
        //创建文本消息,有多种消息类型
        TextMessage textMessage = session.createTextMessage("Hello garine");
        //发送消息
        producer.send(textMessage);
        System.out.println("over");
        session.close();
    }
}
public class JMSPersistenTopicConsumer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.setClientID("persistent-sub-id");
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建topic(有则不创建)
        Topic topic = session.createTopic("garine-topic");
        //创建消费者
        MessageConsumer consumer = session.createDurableSubscriber(topic, "persistent-sub-id");
        //接受文本消息,阻塞等待
        TextMessage textMessage = (TextMessage) consumer.receive();
        System.out.println(textMessage.getText());
        session.close();
    }
}

activeMQ中的会话事务性
事务性会话
特性:
对于消息发送方,消息在session.commi时才会发送到broker,如果session.rollback,那么未提交到消息都作废;
对于消息消费者,消息在session.commit之后,才会进行ack,如果session.rollback,那么会表示broker可以重新发送消息给消费者。必须保证发送端和接收都是事务性会话。
因此开启的事务性会话,提交消息到ack都必须通过session.commit();

非事务性会话
对于发送消息,不需要session.commit,直接发送给broker;
对于消费消息的ack,简单说有以下的特性,后续会展开详细说名ack机制。
非事务性会话的主要特性是其ack模式的特殊
Session.AUTO_ACKNOWLEDGE: 接收到消息时,自动ack确认消息
Session.CLIENT_ACKNOWLEDGE:接收到消息时,客户端调用message.acknowledge(),显式对消息确认。需要注意对是,消息确认时,如果在本次消息确认之前还有别的消息未确认,会在本次消息确认时一并确认,也就是批量确认消息。在activeMQ中批量拉取和批量确认消息是优化的重要手段,后面介绍,目前先记住—>消费端处理流程以及优化策略
Session.DUPS_ACKNOWLEDGE:延迟消息确认,broker端没有收到消息确认时自动重发消息,不在乎消费端接收多次消息

demo中的是未开始事务性会话,如果要开启,可以改为如下一段代码

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

如果需要改变消费端消息确认的方式,那么请不要开启事务会话,并且做如下改变,Session.xxxxxxxx是想要的消息确认方式

Session session = connection.createSession(true, Session.xxxxxxxx);

消息持久化存储
持久化存储针对消息发送方,需要设置消息投递模式为DeliveryMode.PERSISTENT,broker会在接收到消息时存储消息到存储介质,再进行消息分派。
目前支持以下五种持久化策略,详细的持久化策略介绍—>activeMQ持久化策略
Ø KahaDB存储(默认存储方式)
Ø JDBC存储
Ø Memory存储
Ø LevelDB存储
Ø JDBC With ActiveMQ Journal
发送持久化消息可以按照如下方式

        //创建持久化文本消息
        TextMessage textMessage = session.createTextMessage("Hello garine");
        textMessage.setJMSDeliveryMode(DeliveryMode.PERSISTENT);

异步监听消费
最后还有一个就是异步监听消费消息,这是我们常用的代码模式,消费者代码如下:


public class JMSAsyncConsumer {
    public static void main(String[] args) throws JMSException {
        //根据broker URL建立连接工厂
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.0.15:61616");
        //创建连接
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //创建会话
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建队列(有则不创建)
        Destination destination = session.createQueue("garine-queue");
        //创建生产者
        MessageConsumer consumer = session.createConsumer(destination);
        //异步接受文本消息,在回调函数处理消息
        consumer.setMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message) {
                TextMessage textMessage = (TextMessage) message;
                try {
                    System.out.println(textMessage.getText());
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        });
        //session.close();
    }
}

需要注意的是绝对不能关闭session,否则无法监听消息。

以上是大部分activeMQ使用需要注意的点以及特性,是大部分场景下使用activeMq方式。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值