ActiveMQ入门

首先咱们应该先了解J2EE中的一个重要规范:JMS(The Java Message Service)Java消息服务。而JMS的客户端之间能够经过JMS服务进行异步的消息传输。它主要有两种模型:点对点和发布订阅模型。java

点对点的模型特色:spring

  • 每一个消息只有一个消费者(Consumer)(即一旦被消费,消息就再也不在消息队列中)。
  • 发送者和接收者之间在时间上没有依赖性,也就是说当发送者发送了消息以后,无论接收者有没有正在运行,它不会影响到消息被发送到队列。
  • 接收者在成功接收消息以后需向队列应答成功。

发布订阅模型特色:apache

  • 每一个消息能够有多个消费者
  • 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须建立一个订阅者以后,才能消费发布者的消息,并且为了消费消息,订阅者必须保持运行的状态。
  • 为了缓和这样严格的时间相关性,JMS容许订阅者建立一个可持久化的订阅。这样,即便订阅者没有被激活(运行),它也能接收到发布者的消息。

JMS还定义了五种不一样的消息正文格式,以及调用的消息类型,容许你发送并接收以一些不一样形式的数据,提供现有消息格式的一些级别的兼容性。浏览器

  • StreamMessage -- Java原始值的数据流
  • MapMessage--一套名称-值对
  • TextMessage--一个字符串对象
  • ObjectMessage--一个序列化的 Java对象
  • BytesMessage--一个字节的数据流

其中咱们用的最多的就是TextMessage字符串对象服务器

消息中间件做为JMS的实现,在J2EE的企业应用中扮演着特殊的角色。ActiveMQ是一个易于使用的消息中间件。做为JMS的实现,消息中间件的使用步骤都大同小异,下面咱们以ActiveMQ为例来介绍一下其使用。session

2、ActiveMQ 概念

  • Broker,消息代理,表示消息队列服务器实体,接受客户端链接,提供消息通讯的核心服务。
  • Producer,消息生产者,业务的发起方,负责生产消息并传输给 Broker 。
  • Consumer,消息消费者,业务的处理方,负责从 Broker 获取消息并进行业务逻辑处理。
  • Topic,主题,发布订阅模式下的消息统一聚集地,不一样生产者向 Topic 发送消息,由 Broker 分发到不一样的订阅者,实现消息的广播。
  • Queue,队列,点对点模式下特定生产者向特定队列发送消息,消费者订阅特定队列接收消息并进行业务逻辑处理。
  • Message,消息体,根据不一样通讯协议定义的固定格式进行编码的数据包,来封装业务 数据,实现消息的传输。

2、ActiveMQ的基本使用

ActiveMQ的安装:
ActiveMQ安装很简单,只需从其官网下载,解压并进入bin目录app

把文件%activemq home%/conf/activemq.xml和%activemq home%/conf/jetty.xml文件里全部0.0.0.0替换成127.0.0.1异步

使用启动命令运行就行了。而后咱们打开浏览器进入管理后台http://localhost:8161/admin/
输入默认的帐号密码:admin。就能够看到管控台了。tcp


而后咱们使用java操做ActiveMQ,mq的使用基本都须要建立链接、session、Destination这么几步,咱们直接看代码吧。
点对点的模型:
生产者代码:ide

@Test
    public void testQueueProducer() throws Exception {
        //一、建立一个链接工厂对象,须要指定服务的ip及端口。
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //二、使用工厂对象建立一个Connection对象。
        Connection connection = connectionFactory.createConnection();
        //三、开启链接,调用Connection对象的start方法。
        connection.start();
        //四、建立一个Session对象。
        //第一个参数:是否开启事务。若是true开启事务,第二个参数无心义。通常不开启事务false。
        //第二个参数:应答模式。自动应答或者手动应答。通常自动应答。
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //五、使用Session对象建立一个Destination对象。两种形式queue、topic,如今应该使用queue
        Queue queue = session.createQueue("test-queue");
        //六、使用Session对象建立一个Producer对象。
        MessageProducer producer = session.createProducer(queue);
        //七、建立一个Message对象,可使用TextMessage。
        /*TextMessage textMessage = new ActiveMQTextMessage();
        textMessage.setText("hello Activemq");*/
        TextMessage textMessage = session.createTextMessage("hello activemq");
        //八、发送消息
        producer.send(textMessage);
        //九、关闭资源
        producer.close();
        session.close();
        connection.close();
    }

消费者代码:

@Test
    public void testQueueConsumer() throws Exception {
        //建立一个ConnectionFactory对象链接MQ服务器
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //建立一个链接对象
        Connection connection = connectionFactory.createConnection();
        //开启链接
        connection.start();
        //使用Connection对象建立一个Session对象
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //建立一个Destination对象。queue对象
        Queue queue = session.createQueue("spring-queue");
        //使用Session对象建立一个消费者对象。
        MessageConsumer consumer = session.createConsumer(queue);
        //接收消息
        consumer.setMessageListener(new MessageListener() {
            
            @Override
            public void onMessage(Message message) {
                //打印结果
                TextMessage textMessage = (TextMessage) message;
                String text;
                try {
                    text = textMessage.getText();
                    System.out.println(text);
                } catch (JMSException e) {
                    e.printStackTrace();
                }
                
            }
        });
        //等待接收消息
        System.in.read();
        //关闭资源
        consumer.close();
        session.close();
        connection.close();
    }


发布订阅的模型:
生产者代码:

@Test
    public void testTopicProducer() throws Exception {
        //一、建立一个链接工厂对象,须要指定服务的ip及端口。
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //二、使用工厂对象建立一个Connection对象。
        Connection connection = connectionFactory.createConnection();
        //三、开启链接,调用Connection对象的start方法。
        connection.start();
        //四、建立一个Session对象。
        //第一个参数:是否开启事务。若是true开启事务,第二个参数无心义。通常不开启事务false。
        //第二个参数:应答模式。自动应答或者手动应答。通常自动应答。
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //五、使用Session对象建立一个Destination对象。两种形式queue、topic,如今应该使用topic
        Topic topic = session.createTopic("test-topic");
        //六、使用Session对象建立一个Producer对象。
        MessageProducer producer = session.createProducer(topic);
        //七、建立一个Message对象,可使用TextMessage。
        /*TextMessage textMessage = new ActiveMQTextMessage();
        textMessage.setText("hello Activemq");*/
        TextMessage textMessage = session.createTextMessage("topic message");
        //八、发送消息
        producer.send(textMessage);
        //九、关闭资源
        producer.close();
        session.close();
        connection.close();
    }

消费者代码:

@Test
    public void testTopicConsumer() throws Exception {
        //建立一个ConnectionFactory对象链接MQ服务器
        ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //建立一个链接对象
        Connection connection = connectionFactory.createConnection();
        //开启链接
        connection.start();
        //使用Connection对象建立一个Session对象
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //建立一个Destination对象。topic对象
        Topic topic = session.createTopic("test-topic");
        //使用Session对象建立一个消费者对象。
        MessageConsumer consumer = session.createConsumer(topic);
        //接收消息
        consumer.setMessageListener(new MessageListener() {

            @Override
            public void onMessage(Message message) {
                //打印结果
                TextMessage textMessage = (TextMessage) message;
                String text;
                try {
                    text = textMessage.getText();
                    System.out.println(text);
                } catch (JMSException e) {
                    e.printStackTrace();
                }

            }
        });
        System.out.println("topic消费者3启动。。。。");
        //等待接收消息
        System.in.read();
        //关闭资源
        consumer.close();
        session.close();
        connection.close();
    }

发布订阅模型具备严格的时间相关性,若是没有订阅者的话,发布者发布的内容就被浪费掉了。

3、ActiveMQ与Spring整合

Spring提供了JMSTemplate,极大地便利了MQ的使用,咱们只须要提早在配置文件中配置相关的JMS配置,就可在代码中直接使用。
Spring配置文件:

<!-- 真正能够产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://127.0.0.1:61616" />
    </bean>
    <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <!-- 目标ConnectionFactory对应真实的能够产生JMS Connection的ConnectionFactory -->
        <property name="targetConnectionFactory" ref="targetConnectionFactory" />
    </bean>
    <!-- 配置生产者 -->
    <!-- Spring提供的JMS工具类,它能够进行消息发送、接收等 -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <!-- 这个connectionFactory对应的是咱们定义的Spring提供的那个ConnectionFactory对象 -->
        <property name="connectionFactory" ref="connectionFactory" />
    </bean>
    <!--这个是队列(Queue)目的地,点对点的 -->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg>
            <value>spring-queue</value>
        </constructor-arg>
    </bean>
    <!--这个是主题(Topic)目的地,一对多的 -->
    <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
        <constructor-arg value="itemAddTopic" />
    </bean>
    
    <!-- 接收消息配置 -->
    <!-- 配置监听器 -->
    <bean id="myMessageListener" class="cn.e3mall.search.listener.MyMessageListener" />
    <!-- 消息监听容器 -->
    <bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="queueDestination" />
        <property name="messageListener" ref="myMessageListener" />
    </bean>

配置好后可在代码中使用如下方法
生产者代码:

@Test
    public void testQueueProducer() throws Exception {
        // 第一步:初始化一个spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext-activemq.xml");
        // 第二步:从容器中得到JMSTemplate对象。
        JmsTemplate jmsTemplate = applicationContext.getBean(JmsTemplate.class);
        // 第三步:从容器中得到一个Destination对象
        Queue queue = (Queue) applicationContext.getBean("queueDestination");
        // 第四步:使用JMSTemplate对象发送消息,须要知道Destination
        jmsTemplate.send(queue, new MessageCreator() {
            
            @Override
            public Message createMessage(Session session) throws JMSException {
                TextMessage textMessage = session.createTextMessage("spring activemq test");
                return textMessage;
            }
        });
    }

消费者代码:

public class MyMessageListener implements MessageListener {
    //继承MessageListener接口并从新它的onMessage方法
    @Override
    public void onMessage(Message message) {
        
        try {
            TextMessage textMessage = (TextMessage) message;
            //取消息内容
            String text = textMessage.getText();
            System.out.println(text);
        } catch (JMSException e) {
            e.printStackTrace();
        }

消费者的使用是在Spring容器中注入一个监听器,因此咱们须要在配置文件中配置它,它随着Spring的启动而启动,而且实时监听。当有消息向它发送时,他会当即进行逻辑处理。

相关文章
相关标签/搜索