ActiveMQ入门到精通3-ActibeMQ API详解

三、ActiveMQ API讲解

我们写一个简单的Hello World实例,让大家感受下ActiveMQ,需要完成发送者和接受者两部分代码的编写。

(1)建立ConnectionFactory工厂对象,需要填入用户名、密码以及要连接的地址,均使用默认即可,默认端口为:tcp://10.0.31.144:61616

(2)通过ConnectionFactory工厂对象创建一个Connection链接,并且调用ConnectionFactory的start方法开启链接,Connection默认是关闭的。

(3)通过Connection对象创建session会话,用于接收消息,参数配置1:是否启用事务,蚕食配置2:签收模式,一般我们设置为自动签收。

签收模式有三种:

Session.AUTO_ACKNOWLEDGE 当客户端从receive或onMessage成功返回时,Session自动签收客户端的这条消息的收条。

Session.CLIENT_ACKNOWLEDGE 客户端通过调用消息(Message)的acknowledge方法签收消息,在这种情况下,签收发生在Session层面:签收一个已消费的消息,会自动的签收这个Session所有已消费的消息的收条。

Session.DUPS_OK_ACKNOWLEDGE 此选项指示Session不必确保对传送消息的签收,他可能引起消息的重复,但是降低了Session的开销,所以之后客户端能容忍接收重复消息时,才可以使用。

(4)通过session创建Destination对象,指的是一个客户端用来指定生产的消息目标或消息来源的对象。在PTP模式中,Destination被称作Queue队列,在Pub/Sub模式中Destination被称作topic主题。在程序中可以使用多个Queue或topic。

(5)我们需要通过session对象创建消息的发送和接受对象MessageProducer和MessageCustomer.

(6)我们可以使用MessageProducer的setDeliverryMode方法设置持久化特性和费持久化特性(DeliverryMode)。

(7)我们使用JMS规范的TextMessage形式创建数据(通过Session对象),并用MessageProducer的send方法发送数据或MessageCustomer的receive方法接收数据。

(8)最后不要忘记关闭Connection链接。

1 工程搭建Maven依赖

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

2 消息发送者

Sender.java


public class Sender {
    public static void main(String[] args) throws Exception{
        //(1)建立ConnectionFactory工厂对象,需要填入用户名、密码以及要连接的地址,均使用默认即可,默认端口为:tcp://10.0.31.144:61616
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("chen","chen123","tcp://10.0.31.144:61616");
        //(2)通过ConnectionFactory工厂对象创建一个Connection链接,并且调用ConnectionFactory的start方法开启链接,Connection默认是关闭的。
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //(3)通过Connection对象创建session会话,用于接收消息,参数配置1:是否启用事务,蚕食配置2:签收模式,一般我们设置为自动签收。
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //(4)通过session创建Destination对象,指的是一个客户端用来指定生产的消息目标或消息来源的对象。在PTP模式中,Destination被称作Queue队列,在Pub/Sub模式中Destination被称作topic主题。在程序中可以使用多个Queue或topic。
        Destination destination = session.createQueue("helloworld");//创建一个queue的消息目标
        //(5)我们需要通过session对象创建消息的发送和接受对象MessageProducer和MessageCustomer.
        MessageProducer messageProducer = session.createProducer(destination);
        //(6)我们可以使用MessageProducer的setDeliverryMode方法设置持久化特性和费持久化特性(DeliverryMode)。
        messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); //非持久化,下次再开启mq时,数据就不存在了
        //(7)我们使用JMS规范的TextMessage形式创建数据(通过Session对象),并用MessageProducer的sen发送数据或MessageCustomer的receive方法接收数据。
        for(int i=1;i<=10;i++){
            TextMessage textMessage = session.createTextMessage("我是消息内容"+i);
            messageProducer.send(textMessage);
        }
        //(8)最后不要忘记关闭Connection链接。
        if(null != connection){
            connection.close();
        }
    }
}

运行后观察MQ服务器:

3 消息接受者

Client.java


public class Client {
    public static void main(String[] args) throws Exception{
        //(1)建立ConnectionFactory工厂对象,需要填入用户名、密码以及要连接的地址,均使用默认即可,默认端口为:tcp://10.0.31.144:61616
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("chen","chen123","tcp://10.0.31.144:61616");
        //(2)通过ConnectionFactory工厂对象创建一个Connection链接,并且调用ConnectionFactory的start方法开启链接,Connection默认是关闭的。
        Connection connection = connectionFactory.createConnection();
        connection.start();
        //(3)通过Connection对象创建session会话,用于接收消息,参数配置1:是否启用事务,蚕食配置2:签收模式,一般我们设置为自动签收。
        Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
        //(4)通过session创建Destination对象,指的是一个客户端用来指定生产的消息目标或消息来源的对象。在PTP模式中,Destination被称作Queue队列,在Pub/Sub模式中Destination被称作topic主题。在程序中可以使用多个Queue或topic。
        Destination destination = session.createQueue("helloworld");//创建一个queue的消息目标
        //(5)我们需要通过session对象创建消息的发送和接受对象MessageProducer和MessageCustomer.
        MessageConsumer messageConsumer = session.createConsumer(destination);
        //(7)我们使用JMS规范的TextMessage形式创建数据(通过Session对象),并用MessageProducer的sen发送数据或MessageCustomer的receive方法接收数据。
        while (true){
            TextMessage msg = (TextMessage) messageConsumer.receive();
            if(null == msg) break;
            System.out.println("客户端收到消息:"+msg.getText());
        }
        //(8)最后不要忘记关闭Connection链接。
        if(null != connection){
            connection.close();
        }
    }
}

运行观察控制台输出:


客户端收到消息:我是消息内容1
客户端收到消息:我是消息内容2
客户端收到消息:我是消息内容3
客户端收到消息:我是消息内容4
客户端收到消息:我是消息内容5
客户端收到消息:我是消息内容6
客户端收到消息:我是消息内容7
客户端收到消息:我是消息内容8
客户端收到消息:我是消息内容9
客户端收到消息:我是消息内容10

观察Mq服务器:

解释:有一个消费端,消费了hellworld 10条消息

​4 消息优先级

MessageProducer的send方法提供了多个参数配置,

send(Destination,Message,int deliveryMode,int priority,long timeToLive):

deliveryMode:传送模式,PERSISTENT(默认)和NON_PERSISTENT,如果容忍消息丢失,可以使用NON_PERSISTENT。

priority:消息优先级,从0-9十个级别,0-4是普通消息,5-9是加急消息,默认是4。

timeToLive:消息过期时间,默认情况下消息永不过期。

要使用ActiveMQ的消息优先级,

首先,在activemq.xml中配置

<policyEntry queue=">" producerFlowControl="false" prioritizedMessages="true" useCache="false" expireMessagesPeriod="0" queuePrefetch="1" />

其次,因为每个消息都是长时间的操作,一定要等消息里的命令完全执行完毕后,再向ActiveMQ发送ACK,这样就可以保证所有的消息都是按照优先级来消费的。

5 消息的同步和异步接收

消息的同步接收是指:客户端主动去接收消息,客户端课采用MessageConsume的receive方法去接收下一个消息。

消息的异步接收是指:当消息到达MQ服务器时,MQ服务器主动通知客户端,客户点通过注册一个实现MessageListener接口的对象到MessageConsumer。MessageListener只有一个必须实现的方法:onMessage,它只接受一个参数Message。在为每个发送到Destination的消息实现onMessage时,调用该方法。

示例:参考下一节消息过滤的内容。

6 消息过滤

MessageConsumer是一个由Session创建的对象,用来从Destination接收消息。


session.createConsumer(Destination destination);
session.createConsumer(Destination destination,String messageSelector);
session.createConsumer(Destination destination,String messageSelector,boolean noLocal);
session.createDurableSubscriber(Topic topic,String name);
session.createDurableSubscriber(Topic topic,String name,boolean noLocal);

​其中messageSelector为消息选择器,noLocal标志默认为false,设置为true时,限制消费者只能接受和自己相同连接(connection)所发布的消息,此标志只适用于topic主题模式,不适用于queue队列模式;name标识订阅topic主题所对应的订阅名称,持久订阅时需要设置此参数。

举例:


    public final String SELECTOR = "JMS_TYPE='value'";

该选择器检查了传入消息的“JMS_TYPE”属性,并确定了这个属性的值是否等于“value”。如果相等,则消息被消费,如果不相等,那么消息会被忽略。

代码示例:

消息发送者:Sender.java


public class Sender {
    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private MessageProducer messageProducer;

    public Sender() {
        try{
            this.connectionFactory = new ActiveMQConnectionFactory("chen",
                                                "chen123",
                                                "tcp://10.0.31.144:61616");
            this.connection = this.connectionFactory.createConnection();
            this.connection.start();
            this.session = this.connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
            this.messageProducer=this.session.createProducer(null);
        }catch (JMSException e){
            e.printStackTrace();
        }
    }


    public void send() {
        try{
            Destination destination = this.session.createQueue("first");

            MapMessage msg1 = this.session.createMapMessage();
            msg1.setString("name","Jack");
            msg1.setString("address","Bei Jing");
            msg1.setIntProperty("age",23);
            msg1.setStringProperty("sex","m");


            MapMessage msg2 = this.session.createMapMessage();
            msg2.setString("name","rose");
            msg2.setString("address","Nan Jing");
            msg2.setIntProperty("age",22);
            msg2.setStringProperty("sex","f");

            MapMessage msg3 = this.session.createMapMessage();
            msg3.setString("name","Tom");
            msg3.setString("address","Tian Jin");
            msg3.setIntProperty("age",23);
            msg3.setStringProperty("sex","m");

            MapMessage msg4 = this.session.createMapMessage();
            msg4.setString("name","Lily");
            msg4.setString("address","Qing dao");
            msg4.setIntProperty("age",21);
            msg4.setStringProperty("sex","f");

            this.messageProducer.send(destination,msg1,DeliveryMode.NON_PERSISTENT,1,1000*60*60);
            this.messageProducer.send(destination,msg2,DeliveryMode.NON_PERSISTENT,3,1000*60*60);
            this.messageProducer.send(destination,msg3,DeliveryMode.NON_PERSISTENT,5,1000*60*60);
            this.messageProducer.send(destination,msg4,DeliveryMode.NON_PERSISTENT,7,1000*60*60);

            this.connection.close();
        }catch (JMSException e){
            e.printStackTrace();
        }
    }

  
    public static void main(String[] args) {
        Sender sender = new Sender();
        sender.send();
    }

}

运行send()方法向mq服务器发送4条数据;

消息接收者:Client.java

public class Client {
    //使用selector的属性,必须是由setXXXProperty()方法定义的属性.
    public final String SELECTOR_1 = "name LIKE 'T%'";//无效
    public final String SELECTOR_2 = "age >= 22";
    public final String SELECTOR_3 = "sex='f'";

    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private Destination destination;
    private MessageConsumer messageConsumer;


    public Client() {
        try{
            this.connectionFactory = new ActiveMQConnectionFactory("chen",
                    "chen123",
                    "tcp://10.0.31.144:61616");
            this.connection = this.connectionFactory.createConnection();
            this.connection.start();
            this.session = this.connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
            //定义destination
            this.destination=this.session.createQueue("first");
            //创建消费者的时候发生了变化
            this.messageConsumer=this.session.createConsumer(this.destination,SELECTOR_2);
        }catch (JMSException e){
            e.printStackTrace();
        }
    }

    public void receiver(){
        try{
            this.messageConsumer.setMessageListener(new Listener());
        }catch (JMSException e){
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Client c = new Client();
        c.receiver();
    }

}

其中Listener.java:

public class Listener implements MessageListener{

    public void onMessage(Message message) {
        try {

            if(message instanceof MapMessage){
                MapMessage msg = (MapMessage) message;
                System.out.println(msg.toString());
                System.out.println(msg.getString("name"));
                System.out.println(msg.getString("address"));
                System.out.println(msg.getInt("age"));
                System.out.println(msg.getString("sex"));

            }else{
                System.out.println("消息源类型错误!");
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

运行client.receive()方法,观察输出结果:


ActiveMQMapMessage {commandId = 5, responseRequired = false, messageId = ID:localhost-51630-1508748356821-1:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:localhost-51630-1508748356821-1:1:1:1, destination = queue://first, transactionId = null, expiration = 1508751957013, timestamp = 1508748357013, arrival = 0, brokerInTime = 1508748322576, brokerOutTime = 1508748334499, correlationId = null, replyTo = null, persistent = false, type = null, priority = 1, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@6fecb8f3, marshalledProperties = org.apache.activemq.util.ByteSequence@5a725e7, dataStructure = null, redeliveryCounter = 0, size = 0, properties = {age=23, sex=m}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {} }
Jack
Bei Jing
23
m
ActiveMQMapMessage {commandId = 6, responseRequired = false, messageId = ID:localhost-51630-1508748356821-1:1:1:1:2, originalDestination = null, originalTransactionId = null, producerId = ID:localhost-51630-1508748356821-1:1:1:1, destination = queue://first, transactionId = null, expiration = 1508751957014, timestamp = 1508748357014, arrival = 0, brokerInTime = 1508748322578, brokerOutTime = 1508748334505, correlationId = null, replyTo = null, persistent = false, type = null, priority = 3, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@2e6bf465, marshalledProperties = org.apache.activemq.util.ByteSequence@39220730, dataStructure = null, redeliveryCounter = 0, size = 0, properties = {age=22, sex=f}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {} }
rose
Nan Jing
22
f
ActiveMQMapMessage {commandId = 7, responseRequired = false, messageId = ID:localhost-51630-1508748356821-1:1:1:1:3, originalDestination = null, originalTransactionId = null, producerId = ID:localhost-51630-1508748356821-1:1:1:1, destination = queue://first, transactionId = null, expiration = 1508751957015, timestamp = 1508748357015, arrival = 0, brokerInTime = 1508748322578, brokerOutTime = 1508748334505, correlationId = null, replyTo = null, persistent = false, type = null, priority = 5, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@70f0263d, marshalledProperties = org.apache.activemq.util.ByteSequence@5bfb2303, dataStructure = null, redeliveryCounter = 0, size = 0, properties = {age=23, sex=m}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false} ActiveMQMapMessage{ theTable = {} }
Tom
Tian Jin
23
m

7 Pub/Sub模式

发布订阅模式有点类似于我们日常生活中订阅报纸。每年到年尾的时候,邮局就会发一本报纸集合让我们来选择订阅哪一个,在这个表里头列了所有出版发行的报纸,那么对于我们每一个订阅者来说,我们可以选择一份或者多份报纸。比如北京日报、潇湘晨报等。那么这些个我们订阅的报纸就相当于发布订阅模式里的topic。有很多个人订阅报纸,也有人可能订阅了和我相同的报纸。那么在这里相当于我们在同一个topic里面注册了。对于一份报纸发行来说,它和所有的订阅者就构成了一个1对多的关系,这种关系如下所示:

代码样例:

消息发布者Sender.java

public class Sender {
    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private MessageProducer messageProducer;

    public Sender() {
        try{
            this.connectionFactory = new ActiveMQConnectionFactory("chen",
                                                "chen123",
                                                "tcp://10.0.31.144:61616");
            this.connection = this.connectionFactory.createConnection();
            this.connection.start();
            this.session = this.connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
            this.messageProducer=this.session.createProducer(null);
        }catch (JMSException e){
            e.printStackTrace();
        }
    }


    public void sendMessage() {
        try{
            Destination destination = this.session.createTopic("topic");

            TextMessage msg1 = this.session.createTextMessage("消息1");
            TextMessage msg2 = this.session.createTextMessage("消息2");
            TextMessage msg3 = this.session.createTextMessage("消息3");
            this.messageProducer.send(destination,msg1);
            this.messageProducer.send(destination,msg2);
            this.messageProducer.send(destination,msg3);

            this.connection.close();
        }catch (JMSException e){
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Sender sender = new Sender();
        sender.sendMessage();
    }
}

运行main方法查看Mq服务器上的内容:

消息订阅者:(创建多个Client,同时运行)

public class Client {

    private ConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private Destination destination;
    private MessageConsumer messageConsumer;


    public Client() {
        try{
            this.connectionFactory = new ActiveMQConnectionFactory("chen",
                    "chen123",
                    "tcp://10.0.31.144:61616");
            this.connection = this.connectionFactory.createConnection();
            this.connection.start();
            this.session = this.connection.createSession(Boolean.FALSE,Session.AUTO_ACKNOWLEDGE);
            //定义destination
            this.destination=this.session.createTopic("topic");
            //创建消费者的时候发生了变化
            this.messageConsumer=this.session.createConsumer(this.destination);
        }catch (JMSException e){
            e.printStackTrace();
        }
    }

    public void receiver(){
        try{
            this.messageConsumer.setMessageListener(new Listener());
        }catch (JMSException e){
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        Client c = new Client();
        c.receiver();
    }
}
public class Listener implements MessageListener{

    public void onMessage(Message message) {
        try {

            if(message instanceof TextMessage){
                TextMessage msg = (TextMessage) message;
                System.out.println(msg.toString());
                System.out.println(msg.getText());
            }else{
                System.out.println("消息源类型错误!");
            }
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: qt activemq-cpp-library-3.9.5-src.zip是一个QT版本的ActiveMQ C++库的压缩包。ActiveMQ是一个流行的开源消息中间件,而C++库是用于在C++应用程序中使用ActiveMQ的工具。 该压缩包包含了使用QT框架开发的ActiveMQ C++库的源代码。使用这个库可以方便地在QT应用程序中发送和接收ActiveMQ消息。它提供了一套易于使用的API,使得开发人员可以快速地集成ActiveMQ功能到他们的应用程序中。 这个库的版本号是3.9.5,这意味着它是在3.9.5版本的ActiveMQ基础上进行开发和定制的。版本号的更新通常会带来新功能、改进和错误修复,因此使用较新版本的库可以提供更好的性能和功能。 要使用这个库,首先需要下载并解压压缩包。然后,可以将源代码导入到QT项目中,并在项目配置中添加必要的依赖项。开发人员可以使用库中提供的API来连接到ActiveMQ代理服务器,发送和接收消息。可以进行一些高级设置,如设置消息过滤器、持久性订阅等。 总结起来,qt activemq-cpp-library-3.9.5-src.zip是一个由QT框架开发的ActiveMQ C++库的源代码压缩包。它提供了便捷的方式在QT应用程序中使用ActiveMQ,并能够发送、接收消息。使用这个库可以提供更好的性能和功能,并且使用较新的版本可以获得更多的更新和改进。 ### 回答2: qt activemq-cpp-library-3.9.5-src.zip 是一个包含 Qt 平台下的 ActiveMQ-CPP 库源代码的压缩文件。ActiveMQ-CPP 是 Apache ActiveMQ 的 C++ 客户端库,为开发人员提供了在 C++ 环境中与 ActiveMQ 通信的能力。 这个库的版本是3.9.5,它是根据 Apache ActiveMQ 的版本定制的。ActiveMQ 是一个开源的消息代理,用于在分布式系统中进行异步通信和消息传递。ActiveMQ-CPP 库提供了在 C++ 应用程序中使用 ActiveMQ 的接口和功能,让开发人员能够使用 C++ 编程语言进行异步消息传递。 该压缩文件包含了 ActiveMQ-CPP 库的源代码,这意味着您可以查看和修改源代码以满足您的特定需求。Qt 是一个跨平台的应用程序开发框架,它可以方便地用于构建图形用户界面和可移植的应用程序。ActiveMQ-CPP 库结合了 ActiveMQ 和 Qt 的功能,为开发人员提供了一种使用 C++ 和 Qt 进行消息传递的快捷方式。 要使用这个库,您需要解压缩该压缩文件,并将源代码文件导入到您的 Qt 项目中。然后,您可以根据活动MQ-CPP 文档中提供的指南来配置和使用该库。 总之,qt activemq-cpp-library-3.9.5-src.zip 是一个包含 ActiveMQ-CPP 库源代码的压缩文件,它让使用 C++ 和 Qt 的开发人员能够在 Qt 平台上与 ActiveMQ 进行异步消息传递。 ### 回答3: qt activemq-cpp-library-3.9.5-src.zip 是一个压缩包,其中包含了 Qt 平台下的 ActiveMQ-CPP 库的源代码。 ActiveMQ-CPP 是一个 C++ 编写的 ActiveMQ 客户端库,用于实现与 ActiveMQ 消息代理服务器的连接和消息交互。它提供了一组用于发送、接收和处理消息的类和函数。使用 ActiveMQ-CPP,开发者可以在 Qt 平台上轻松地实现与 ActiveMQ 服务器的通信,用于实现消息传递的功能。 这个压缩包包含了库的源代码,可以方便地进行自定义和扩展。通过解压这个压缩包,开发者可以获取到库的源代码文件,其中包含了用于实现不同功能的类、函数和头文件。开发者可以根据自己的需要对源代码进行修改和定制,以满足项目的特定需求。 使用这个压缩包,开发者可以通过 Qt 平台来构建和编译 ActiveMQ-CPP 库,生成对应的库文件,然后将其链接到自己的项目中。这样,开发者就可以在自己的 Qt 项目中使用 ActiveMQ-CPP 库提供的功能,实现与 ActiveMQ 服务器的连接和消息交互。 总之,qt activemq-cpp-library-3.9.5-src.zip 是一个包含了 ActiveMQ-CPP 库源代码的压缩包,可以方便地在 Qt 平台上进行定制和扩展,并实现与 ActiveMQ 服务器的通信和消息处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值