ActiveMQ

一. 认识JMS
1.概述

对于JMS,百度百科,是这样介绍的:JMS即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

简短来说,JMS是一种与厂商无关的 API,用来访问消息收发系统消息。它类似于JDBC(Java Database Connectivity),提供了应用程序之间异步通信的功能。

JMS1.0是jsr 194里规定的规范(关于jsr规范,请点击)。目前最新的规范是JSR 343,JMS2.0。

好了,说了这么多,其实只是在说,JMS只是sun公司为了统一厂商的接口规范,而定义出的一组api接口。
2. JMS体系结构

描述如下:

    JMS提供者(JMS的实现者,比如activemq jbossmq等)
    JMS客户(使用提供者发送消息的程序或对象,例如在12306中,负责发送一条购票消息到处理队列中,用来解决购票高峰问题,那么,发送消息到队列的程序和从队列获取消息的程序都叫做客户)
    JMS生产者,JMS消费者(生产者及负责创建并发送消息的客户,消费者是负责接收并处理消息的客户)
    JMS消息(在JMS客户之间传递数据的对象)
    JMS队列(一个容纳那些被发送的等待阅读的消息的区域)
    JMS主题(一种支持发送消息给多个订阅者的机制)

3. JMS对象模型

    连接工厂(connectionfactory)客户端使用JNDI查找连接工厂,然后利用连接工厂创建一个JMS连接。
    JMS连接 表示JMS客户端和服务器端之间的一个活动的连接,是由客户端通过调用连接工厂的方法建立的。
    JMS会话 session 标识JMS客户端和服务端的会话状态。会话建立在JMS连接上,标识客户与服务器之间的一个会话进程。
    JMS目的 Destinatio 又称为消息队列,是实际的消息源
    生产者和消费者
    消息类型,分为队列类型(优先先进先出)以及订阅类型

二. ActiveMQ
1. ActiveMQ的安装

    从官网下载安装包, http://activemq.apache.org/download.html
    赋予运行权限 chmod +x,windows可以忽略此步
    运行 ./active start | stop

启动后,activeMQ会占用两个端口,一个是负责接收发送消息的tcp端口:61616,一个是基于web负责用户界面化管理的端口:8161。这两个端口可以在conf下面的xml中找到。http服务器使用了jettry。这里有个问题是启动mq后,很长时间管理界面才可以显示出来。

==》启动MQ服务器:

根据操作系统不同,进入相应win64/win32位目录,双击activemq.bat启动MQ。控制台部分显示:

ActiveMQ默认启动时,启动了内置的jetty服务器,提供一个用于监控ActiveMQ的admin应用

进入ActionMQ服务监控地址:浏览器输入http://127.0.0.1:8161/admin

登录成功,页面显示:

重点关注菜单栏:

【1】Queues:队列

【2】Topics


一、引入依赖配置

   

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-pool</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
            <version>1.5.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>

二、application.properties配置

   

# ActiveMQ--------------------------------------------------------------------------------------------------------------
    # Specify if the default broker URL should be in memory. Ignored if an explicit broker has been specified.
    #spring.activemq.in-memory=false
    # URL of the ActiveMQ broker. Auto-generated by default. For instance `tcp://localhost:61616`
    spring.activemq.broker-url=tcp://127.0.0.1:61616
    # Login user of the broker.
    spring.activemq.user=admin
    # Login password of the broker.
    spring.activemq.password=admin
    # Trust all packages.
    #spring.activemq.packages.trust-all=false
    # Comma-separated list of specific packages to trust (when not trusting all packages).
    #spring.activemq.packages.trusted=
    # See PooledConnectionFactory.
    #spring.activemq.pool.configuration.*=
    # Whether a PooledConnectionFactory should be created instead of a regular ConnectionFactory.
    spring.activemq.pool.enabled=true
    # Maximum number of pooled connections.
    spring.activemq.pool.max-connections=50
    # Connection expiration timeout in milliseconds.
    spring.activemq.pool.expiry-timeout=10000
    # Connection idle timeout in milliseconds.
    spring.activemq.pool.idle-timeout=30000
    spring.jms.pub-sub-domain=false

三、新建消息生产者类

   

package com.rubberbox.activemq.activemq;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

import javax.jms.Destination;

/**
 * 报警消息Producer
 *
 * @author ko
 */
@Component
public class AlarmProducer {

    // 也可以注入JmsTemplate,JmsMessagingTemplate对JmsTemplate进行了封装
    @Autowired
    private JmsTemplate jmsTemplate;
//    private JmsMessagingTemplate jmsTemplate;

//    @Autowired
//    private Queue queue;

    //    @Scheduled(fixedDelay=5000) // 5s执行一次   只有无参的方法才能用该注解
    public void sendMessage(Destination destination, String message) {
        this.jmsTemplate.convertAndSend(destination, message);
    }

    // 双向队列
    // @JmsListener(destination="out.queue")
    //   public void consumerMessage(String text){
    //   System.out.println("从out.queue队列收到的回复报文为:"+text);
    // }
}
package ykf.mattress.sys.main.activemq;
     
    import javax.annotation.Resource;
    import javax.jms.Destination;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jms.core.JmsTemplate;
    import org.springframework.stereotype.Service;
     
    /**
     * 测试消息 生成者
     */
     
    @Service("messageProduce")
    public class MessageProduce {
     
        private Logger logger = LoggerFactory.getLogger(MessageProduce.class);
     
        @Resource
        private JmsTemplate jmsTemplate;
     
        /**
         * 发送消息
         *
         * @param destination
         *            发送到的队列
         * @param message
         *            待发送的消息
         */
        public void convertAndSend(Destination destination, final String message) {
            jmsTemplate.convertAndSend(destination, message);
            logger.info("消息发送成功!");
        }
    }

四、新建消息消费者one two   

package com.rubberbox.activemq.activemq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 * 围栏报警Consumer
 *
 * @author ko
 */
@Component
public class AlarmConsumer {
    private Logger logger = LoggerFactory.getLogger(AlarmConsumer.class);

    // 使用JmsListener配置消费者监听的队列,其中text是接收到的消息
    @JmsListener(destination = "active.queue")
    // @SendTo("out.queue") 为了实现双向队列
    public void receiveQueue(String text) {
        if (!StringUtils.isEmpty(text)) {
            logger.info("AlarmConsumer收到的报文为:" + text);
        }
    }
}
 package ykf.mattress.sys.main.activemq;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
     
    @Component
    public class MessageConsumeNone {
     
        private Logger logger = LoggerFactory.getLogger(MessageConsumeNone.class);
     
        /**
         * 使用JmsListener配置消费者监听的队列
         *
         * @param text
         *            接收到的消息
         */
        @JmsListener(destination = "suimh_queue")
        public void receiveQueue(String text) {
            logger.info("MessageConsumeNone : 收到的报文为:" + text);
        }
     
    }

    package ykf.mattress.sys.main.activemq;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.messaging.handler.annotation.SendTo;
    import org.springframework.stereotype.Component;
     
    @Component
    public class MessageConsumeNtwo {
     
        private Logger logger = LoggerFactory.getLogger(MessageConsumeNtwo.class);
     
        /**
         * 使用JmsListener配置消费者监听的队列
         *
         * @param text
         *            接收到的消息
         */
        @JmsListener(destination = "suimh_queue")
        @SendTo("out.queue")
        public String receiveQueue(String text) {
            logger.info("MessageConsumeNtwo : 收到的报文为:" + text);
            logger.info("MessageConsumeNtwo : 收到的报文为:返回数据到out.queue");
            return text;
        }
     
    }

五、新建返回报文接收类

    package ykf.mattress.sys.main.activemq;
     
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.jms.annotation.JmsListener;
    import org.springframework.stereotype.Component;
     
    /**
     * 接收消费者 返回数据
     */
    @Component
    public class RxCousResultProduce {
     
        private Logger logger = LoggerFactory.getLogger(RxCousResultProduce.class);
     
        /**
         * 使用JmsListener配置消费者监听的队列
         *
         * @param text
         *            接收到的消息
         */
        @JmsListener(destination = "out.queue")
        public void consumerMessage(String text) {
            logger.info("RxCousResultProduce : 从out.queue队列收到的回复报文为:" + text);
        }
    }

六、写控制层测试   

@Resource
        MessageProduce messageProduce;

        @GetMapping(value = "/activeMqSendMes")
        @ResponseBody
        public String activeMqSendMes() {
            int num = 10;
            try {
                //ActiveMQQueue 队列模式
                //ActiveMQTopic 订阅模式
                Destination destinationQueue = new ActiveMQQueue("suimh_queue");
                for (int i = 1; i <= num; i++) {
                    messageProduce.convertAndSend(destinationQueue, "这是queueProducer发送的第" + i + "个消息!");
                }
                return "activeMQ生产成功!";
            } catch (Exception e) {
                return "activeMQ生产失败!";
            }
        }
package com.rubberbox.activemq.config;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;

import javax.jms.ConnectionFactory;

@Configuration
public class ActiveMqConfig {
    @Value("${spring.activemq.broker-url}")
    private String brokerUrl;
    @Value("${spring.activemq.password}")
    private String password;
    @Value("${spring.activemq.user}")
    private String username;

    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL(brokerUrl);
        connectionFactory.setUserName(username);
        connectionFactory.setPassword(password);
        return connectionFactory;
    }

    @Bean
    public JmsTemplate genJmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory());
        jmsTemplate.setDefaultDestinationName("spttle.alert.queue");
        return jmsTemplate;

    }

    @Bean
    public JmsMessagingTemplate jmsMessageTemplate() {
        JmsMessagingTemplate jmsMessagingTemplate = new JmsMessagingTemplate(connectionFactory());
        jmsMessagingTemplate.setDefaultDestinationName("spttle.alert.queue");
        return jmsMessagingTemplate;
    }

    @Bean
    public MappingJackson2MessageConverter mappingJackson2MessageConverter() {
        return new MappingJackson2MessageConverter();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值