ActiveMQ消息队列

消息中间件 ActiveMQ

ActiveMQ 是 Apache 出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持 JMS1.1 和 J2EE 1.4 规范的 JMS Provider 实现,尽管 JMS 规范出台已经是很久的事情了,但是 JMS 在当今的 J2EE 应用中间仍然扮演着特殊的地位。

JMS 介绍

JMS 的全称是 Java Message Service,即 Java 消息服务。用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息。把它应用到实际的业务需求中的话我们可以在特定的时候利用生产者生成一消息,并进行发送,对应的消费者在接收到对应的消息后去完成对应的业务逻辑。
对于消息的传递有两种类型:
一种是点对点的,即一个生产者和一个消费者一一对应;
另一种是发布/订阅模式,即一个生产者产生消息并进行发送后,可以由多个消费者进行接收。
JMS 定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。
· StreamMessage – Java 原始值的数据流
· MapMessage–一套名称-值对
· TextMessage–一个字符串对象
· ObjectMessage–一个序列化的 Java 对象
· BytesMessage–一个字节的数据流
总结:ActiveMQ 就是服务,是一个项目。接受发送数据,消息消费者也可以获取数据。

ActiveMQ主要特点

⒈ 多种语言和协议编写客户端。语言: Java,C,C++,C#,Ruby,Perl,Python,PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
⒉ 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
⒊ 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
⒋ 通过了常见J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
⒌ 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
⒍ 支持通过JDBC和journal提供高速的消息持久化
⒎ 从设计上保证了高性能的集群,客户端-服务器,点对点
⒏ 支持Ajax
⒐ 支持与Axis的整合
⒑ 可以很容易的调用内嵌JMS provider,进行测试。

安装 MQ

1) 导入 ActiveMQ 安装包
a) 直接使用 rz 命令把 ActiveMQ 安装包导入 hadoop 目录下
2) 解压 mq
a) tar -zxvf apache-activemq-5.12.0-bin.tar.gz
3) 重命名
a) mv apache-activemq-5.12.0 activeMQ
4) 启动 ActiveMQ 服务
a) ./activemq start
5) 停止 ActiveMQ 服务
a) ./activemq stop
6) 登录 ActiveMQ
a) 用户名:admin
b) 密码:admin
c) 端口:8161

PTP(point to point)【点对点】

消息发送流程:
1) 客户机发送消息到 JMS 消息中间件
2) 服务端负责监听 JMS 消息目的地。
3) 发现 JMS 里面有消息产生,服务就可以接受消息。
点对点消息发送服务:
1) 消息只能被一个服务接受
2) 多个服务同时监听消息服务器,遵循先来后到原则。
3) 消息一旦被接受,消息自动消失。
4) 如果消息一直没有被接受,消息会等待被接受,直到被接受为止。

发送消息

代码步骤:
1) 创建消息工厂,ActiveMQConnectionFactory,需要传递参数:协议,地址,端口。
2) 从工厂中获取连接
3) 开启连接
4) 从连接中获取 Session
5) 从 Session 中获取消息目的地
6) 创建消息发生者
7) 发送消息
8) 关闭资源

        // 发送消息
        @Test
        public void oneSendMessage() throws Exception {
            // 1) 创建消息工厂,ActiveMQConnectionFactory,需要传递参数:协议,地址,端口。
            ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://192.168.66.66:61616");
            // 2) 从工厂中获取连接
            Connection connection = connectionFactory.createConnection();
            // 3) 开启连接
            connection.start();
            // 4) 从连接中获取Session
            //第一个参数:消息事务,如果第一个参数是true,第二个参数将会被忽略
            //第二个参数:消息应答模式,自动应答模式
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            // 5) 从Session中获取消息目的地
            //创建一个消息目的地,给消息目的起一个名称:myqueue
            //相当域在ActiveMQ服务中开辟了名称为myqueue一块空间,消息发送myqueue这块空间中。
            //消息有两种模式:点对点(queue),发布定阅模式:(Topic)
            Queue queue = session.createQueue("myqueue");
            // 6) 创建消息发生者
            MessageProducer producer = session.createProducer(queue);
            // 7) 发送消息
            TextMessage message = new ActiveMQTextMessage();
            message.setText("我们都是中国人");
            producer.send(message);
            // 8) 关闭资源
            producer.close();
            session.close();
            connection.close();
        }

接收信息

1) 同步模式接受消息:发送即接受。
2) 异步模式:服务负责监听,一旦监听到消息,就接受。

        //异步模式接受消息
        @Test
        public void receiveMessageSycr() throws Exception{
            // 1) 创建消息工厂,ActiveMQConnectionFactory,需要传递参数:
            协议,地址,端口。
            ConnectionFactory connectionFactory = new
            ActiveMQConnectionFactory(
            "tcp://192.168.66.66:61616");
            // 2) 从工厂中获取连接
            Connection connection = 
            connectionFactory.createConnection();
            // 3) 开启连接
            connection.start();
            // 4) 从连接中获取Session
            //第一个参数:消息事务,如果第一个参数是true,第二个参数将会被
            忽略
            //第二个参数:消息应答模式,自动应答模式
            Session session = connection.createSession(false, 
            Session.AUTO_ACKNOWLEDGE);
            // 5) 从Session中获取消息目的地
            //创建一个消息目的地,给消息目的起一个名称:myqueue
            //相当域在ActiveMQ服务中开辟了名称为myqueue一块空间,消息发送
            myqueue这块空间中。
            //消息有两种模式:点对点(queue),发布定阅模式:(Topic)
            Queue queue = session.createQueue("myqueue");
            //6)创建消息接受者
            MessageConsumer consumer = session.createConsumer(queue);
            //异步模式接受使用监听器接受消息
            consumer.setMessageListener(new MessageListener(){
                @Override
                public void onMessage(Message message) {
                    if(message instanceof TextMessage){
                        TextMessage tm = (TextMessage) message;
                        try {
                            //打印消息
                            System.out.println(tm.getText());
                        } catch (JMSException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        }
                    }
                });
            }

发布订阅模式-activeMQ

发布订阅模式流程:
1) 客户机发送消息到 JMS 消息中间件
2) 服务端负责监听 JMS 消息目的地。
3) 发现 JMS 里面有消息产生,服务就可以订阅。
特点:
1) 消息可以被多个服务共享
2) 消息直到被所有消费后,消息消失。

发布订阅

点对点模式:发布数据模型:对列 queue
发布模式:发布数据模型:Topic
发布订阅模式使用监听异步接受消息。

发送消息

        //发布订阅模式,发送消息
        @Test
        public void oneSendMessageTopic() throws Exception {
            // 1) 创建消息工厂,ActiveMQConnectionFactory,需要传递参数:
            协议,地址,端口。
            ConnectionFactory connectionFactory = new
            ActiveMQConnectionFactory(
            "tcp://192.168.66.66:61616");
            // 2) 从工厂中获取连接
            Connection connection = connectionFactory.createConnection();
            // 3) 开启连接
            connection.start();
            // 4) 从连接中获取Session
            //第一个参数:消息事务,如果第一个参数是true,第二个参数将会被忽略
            //第二个参数:消息应答模式,自动应答模式
            Session session = connection.createSession(false,
            Session.AUTO_ACKNOWLEDGE);
            // 5) 从Session中获取消息目的地
            //创建一个消息目的地,给消息目的起一个名称:mytopic
            //相当在ActiveMQ服务中开辟了名称为mytopic一块空间,消息发送
            mytopic这块空间中。
            //消息有两种模式:发布定阅模式:(Topic),点对点(queue)
            Topic topic = session.createTopic("mytopic");
            // 6) 创建消息发生者
            MessageProducer producer = session.createProducer(topic);
            // 7) 发送消息
            TextMessage message = new ActiveMQTextMessage();
            message.setText("我们都是中国人");
            producer.send(message);
            // 8) 关闭资源
            producer.close();
            session.close();
            connection.close();
        }

接受消息

        //异步模式接受Topic消息
        @Test
        public void receiveMessageSycrTopic() throws Exception{
            // 1) 创建消息工厂,ActiveMQConnectionFactory,需要传递参数:协议,地址,端口。
            ConnectionFactory connectionFactory = new
            ActiveMQConnectionFactory(
            "tcp://192.168.66.66:61616");
            // 2) 从工厂中获取连接
            Connection connection = 
            connectionFactory.createConnection();
            // 3) 开启连接
            connection.start();
            // 4) 从连接中获取Session
            //第一个参数:消息事务,如果第一个参数是true,第二个参数将会被忽略
            //第二个参数:消息应答模式,自动应答模式
            Session session = connection.createSession(false, 
            Session.AUTO_ACKNOWLEDGE);
            // 5) 从Session中获取消息目的地
            //创建一个消息目的地,给消息目的起一个名称:myqueue
            //相当域在ActiveMQ服务中开辟了名称为myqueue一块空间,消息发送myqueue这块空间中。
            //消息有两种模式:点对点(queue),发布定阅模式:(Topic)
            Topic topic = session.createTopic("mytopic");
            //6)创建消息接受者
            MessageConsumer consumer = session.createConsumer(topic);
            //异步模式接受使用监听器接受消息
            consumer.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message message) {
                    if(message instanceof TextMessage){
                    TextMessage tm = (TextMessage) message;
                    try {
                    //打印消息
                    System.out.println(tm.getText());
                    } catch (JMSException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    }
                }
            }
            });
            System.in.read();
        }

ActiveMQ 和 spring

把 ActiveMQ 交给 spring 管理

    <!-- 真正可以产生Connection的ConnectionFactory,由对应的 JMS服务厂商提供 -->
    <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://192.168.66.66:61616" />
    </bean>
     <!-- spring提供管理工厂工具类 -->
    <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
        <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>
    <!--这个是队列目的地,点对点的 -->
    <bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <constructor-arg>
            <value>one-queue</value>
        </constructor-arg>
    </bean>
    <!--这个是主题目的地,一对多的 -->
    <bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
        <constructor-arg value="one-topic" />
    </bean>
    <!-- 配置监听器 -->
    <bean id="myMessageListener" class="cn.e3mall.search.mq.MyMessageListener" />
    <!-- 消息监听容器 -->
    <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="queueDestination" />
        <property name="messageListener" ref="myMessageListener" />
    </bean>
展开阅读全文

没有更多推荐了,返回首页