整合ActiveMQ

来源:互联网 发布:linux下安装jira 编辑:程序博客网 时间:2024/06/03 21:17

简单介绍一下ActiveMQ  自己的看法 有这方面的需求的还是去看看官方解释或者别的博客

ActiveMQ是基于JMS的一个消息队列,也是纯java编写的。基本所有的消息中间件都是为了异步和将不重要的业务从自己的本来的业务中解耦。消息中间件都有生产者和消费者,双方都可以是多个,基于队列传输消息。

如何安装开始我就不多介绍了,直接开始代码

从最基本的原生开始:这个只有队列模式 没有发布订阅模式

jar包 用的是activemq-all-5.2.0

生产者:

package demo1;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;/** * 生产者生消息 并发送 * * @Author : WenBao * Date : 8:58 2017/12/5 */public class JMSProducer {    /**     * 默认连接用户名     */    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;    /**     * 默认连接密码     */    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;    /**     * 默认连接地址     */    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;    /**     * 发送消息的数量     */    public static final int SENDNUM = 10;    public static void main(String[] args) {        //连接工厂        ConnectionFactory connectionFactory;        //连接        Connection connection = null;        //会话 接受或者发送消息的线程        Session session;        //消息的目的地 也就是队列的名字        Destination destination;        //消息生产者        MessageProducer messageProducer;        //实例化连接工厂        connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);        //通过连接工厂获取连接        try {            connection = connectionFactory.createConnection();            //启动连接            connection.start();            /**             * 创建session             * true 为开启事务 默认为事务确认 忽略第二个参数   一般情况下不开启事务,开启事务会导致性能的严重降低同时会导致生产者会有同步效果             *Session.AUTO_ACKNOWLEDGE 自动确认 值为1             */            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);            //创建一个名称为HelloWorld的消息队列 destination就是队列            destination = session.createQueue("helloWorld");            //创建消息的生产者            messageProducer = session.createProducer(destination);            //发送消息            JMSProducer.sendMessage(session, messageProducer);            session.commit();        } catch (Exception e) {        } finally {            if (null != connection) {                try {                    connection.close();                } catch (JMSException e) {                }            }        }    }    /**     * 发送消息     *     * @param session     * @param messageProducer 消息生产者     */    public static void sendMessage(Session session, MessageProducer messageProducer) throws Exception {        for (int i = 0; i < JMSProducer.SENDNUM; i++) {            //创建一条文本            TextMessage message = session.createTextMessage("ActiveMQ 发送消息" + i);            System.out.println("发送消息:Activemq 发送消息" + i);            //通过生产者发送消息            messageProducer.send(message);        }    }}

消费者:

package demo1;import org.apache.activemq.ActiveMQConnection;import org.apache.activemq.ActiveMQConnectionFactory;import javax.jms.*;public class JMSConsumer {    private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;//默认连接用户名    private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;//默认连接密码    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址    public static void main(String[] args) {        ConnectionFactory connectionFactory;//连接工厂        Connection connection = null;//连接        Session session;//会话 接受或者发送消息的线程        Destination destination;//消息的目的地    也就是生产者中所声明的队列        MessageConsumer messageConsumer;//消息的消费者         //实例化连接工厂        connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);        try {            //通过连接工厂获取连接            connection = connectionFactory.createConnection();            //启动连接            connection.start();            //创建session false 非事务            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);            //创建一个连接HelloWorld的消息队列  与生产者端队列名一致            destination = session.createQueue("helloWorld");            //创建消息消费者            messageConsumer = session.createConsumer(destination);            while (true) {                /**                 * receive = 0                 * receive()方法将会首先发送一个PULL指令并阻塞,直到broker端返回消息为止,这也意味着消息只能逐个获取                 *  receive > 0                 *  “broker端将会批量push给client 一定数量的消息(<= prefetch),client端会把这些消息(unconsumedMessage)                 *  放入到本地的队列中,只要此队列有消息,那么receive方法将会立即返回,                 *  当一定量的消息ACK之后,broker端会继续批量push消息给client端                 */                TextMessage textMessage = (TextMessage) messageConsumer.receive(10000);                if (null != textMessage) {                    System.out.print("收到的消息:" + textMessage.getText());                } else {                    break;                }            }        } catch (Exception e) {            e.printStackTrace();        } finally {            if (null != connection) {                try {                    connection.close();                } catch (JMSException e) {                }            }        }    }}

spring整合active:队列和发布订阅模式

pom.xml 文件:

<properties>    <!-- Generic properties -->    <java.version>1.6</java.version>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>    <!-- Spring -->    <spring-framework.version>3.2.3.RELEASE</spring-framework.version>    <!-- Test -->    <junit.version>4.11</junit.version></properties><dependencies>    <dependency>        <groupId>org.apache.activemq</groupId>        <artifactId>activemq-all</artifactId>        <version>5.9.0</version>    </dependency>    <dependency>        <groupId>org.apache.activemq</groupId>        <artifactId>activemq-pool</artifactId>        <version>5.9.0</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-jms</artifactId>        <version>${spring-framework.version}</version>    </dependency>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>RELEASE</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-test</artifactId>        <version>3.2.4.RELEASE</version>        <scope>provided</scope>    </dependency>    <dependency>        <groupId>org.apache.xbean</groupId>        <artifactId>xbean-spring</artifactId>        <version>4.4</version>    </dependency></dependencies>
application.xml文件:

<beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:amq="http://activemq.apache.org/schema/core"       xmlns:jms="http://www.springframework.org/schema/jms"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd        http://activemq.apache.org/schema/core        http://activemq.apache.org/schema/core/activemq-core.xsd        http://www.springframework.org/schema/jms        http://www.springframework.org/schema/jms/spring-jms.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">    <!--ActiveMQ 连接工厂-->    <!--真正可以产生Connection的ConnectionFactory,由对应的JMS服务厂商提供-->    <!--如果连接网络:tcp://ip:61616;未连接网络:tcp://localhost:61616 以及用户名,密码-->    <amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://localhost:61616" userName="admin"                           password="admin">    </amq:connectionFactory>    <!--Spring Caching连接工厂-->    <!--连接工厂有两种 一种是SingleConnectionFactory 单个 CachingConnectionFactory缓存 继承于单例-->    <!--Spring用于管理真正的ConnectionFactory的ConnectionFactory-->    <bean id="connectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">        <!--目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory-->        <property name="targetConnectionFactory" ref="amqConnectionFactory"></property>        <!--也可以通过构造方法的形式注入        <constructor-arg ref="amqConnectionFactory"></constructor-arg>-->        <!--Session缓存的数量-->        <property name="sessionCacheSize" value="100"></property>    </bean>    <!--Spring JmsTemplate的消息生产者 start-->    <!--定义JmsTemplate的Queue类型-->    <bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">        <!--将连接工厂注入模板中-->        <constructor-arg ref="connectionFactory"></constructor-arg>        <property name="receiveTimeout" value="100"></property>        <!--非pub/sub模式(发布/订阅),即队列模式-->        <property name="pubSubDomain" value="false"></property>    </bean>    <!--订阅JmsTemplate的Topic类型-->    <bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">        <!--同上-->        <constructor-arg ref="connectionFactory"></constructor-arg>        <property name="pubSubDomain" value="true"></property>    </bean>    <!--Spring JmsTemplate 的消息生产者 end-->    <!--消息消费者start-->    <!--定义Queue监听器-->    <jms:listener-container destination-type="queue" container-type="default" connection-factory="connectionFactory"                            acknowledge="auto">        <!--消费者监听队列名字-->        <jms:listener destination="test.queue" ref="queueReceiver1"></jms:listener>        <jms:listener destination="test.queue" ref="queueReceiver2"></jms:listener>    </jms:listener-container>    <!-- 定义Topic监听器 -->    <jms:listener-container destination-type="topic" container-type="default" connection-factory="connectionFactory"                            acknowledge="auto">        <!--订阅名字-->        <jms:listener destination="test.topic" ref="topicReceiver1"/>        <jms:listener destination="test.topic" ref="topicReceiver2"/>    </jms:listener-container>    <!-- 消息消费者 end -->    <context:component-scan base-package="com.yjp.activemq"></context:component-scan></beans>

队列生产者;

package com.yjp.activemq;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.jms.core.JmsTemplate;import org.springframework.jms.core.MessageCreator;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.Session;/** * 队列模式 * * @Author :  * Date : 14:28 2017/12/11 */@Componentpublic class QueueSender1 {    @Autowired    @Qualifier("jmsQueueTemplate")    private JmsTemplate jmsTemplate;    /**     * 发送消息到指定的队列(目标)     *     * @param queueName 队列名称     * @param message   消息内容     */    public void send(String queueName, final String message) {        //匿名内部类拿到session        jmsTemplate.send(queueName, new MessageCreator() {            public Message createMessage(Session session) throws JMSException {                return session.createTextMessage(message);            }        });    }}
队列消费者:

package com.yjp.activemq;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;/** * 消息队列监听器 * 消费者 * * @Author :  * Date : 14:33 2017/12/11 */@Componentpublic class queueReceiver1 implements MessageListener {    public void onMessage(Message message) {        try {            System.out.println("QueueReceiver1接收到消息:" + ((TextMessage) message).getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}
package com.yjp.activemq;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;@Componentpublic class queueReceiver2 implements MessageListener {    public void onMessage(Message message) {        try {            System.out.println("QueueReceiver2接收到消息:" + ((TextMessage) message).getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}
发布/订阅生产者:

package com.yjp.activemq;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.jms.core.JmsTemplate;import org.springframework.jms.core.MessageCreator;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.Session;/** * ActiveMQ的topic/sub模式 * Topic生产者发送消息到Topic * * @Author : * Date : 14:31 2017/12/11 */@Componentpublic class TopicSender1 {    @Autowired    @Qualifier("jmsTopicTemplate")    private JmsTemplate jmsTemplate;    /**     * 发送一条消息到指定的队列(目标)     *     * @param topicName 队列名称     * @param message   消息内容     */    public void send(String topicName, final String message) {        jmsTemplate.send(topicName, new MessageCreator() {            public Message createMessage(Session session) throws JMSException {                return session.createTextMessage(message);            }        });    }}
发布/订阅消费者

package com.yjp.activemq;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;@Componentpublic class topicReceiver1 implements MessageListener {    public void onMessage(Message message) {        try {            System.out.println("TopicReceiver1接收到消息:" + ((TextMessage) message).getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}
package com.yjp.activemq;import org.springframework.stereotype.Component;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;@Componentpublic class topicReceiver2 implements MessageListener {    public void onMessage(Message message) {        try {            System.out.println("TopicReceiver2接收到消息:" + ((TextMessage) message).getText());        } catch (JMSException e) {            e.printStackTrace();        }    }}
与xml中约定的名字一致

测试类:

package com.yjp.activemq;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:application.xml"})public class ActiveMQTest {    @Autowired    private QueueSender1 queueSender1;    @Autowired    private TopicSender1 topicSender1;    @Test    public void test1() {        queueSender1.send("test.queue", "你好");        topicSender1.send("test.topic", "你好?????");    }}
测试结果:


从测试结果可以看出:

有两个队列消费者同时监听了同一个队列,但是只会有一个消费者可以接受到消息,这就是队列模式,一个消息只会有一个消费者去消费

发布/订阅模式:

同样是两个消费者监听同一个队列,但是两个消费者都可以接受到消息,去消费消息,这就是发布/订阅模式,一个消息可以有多个消费者去消费。

springboot整合activemq

pom.xml:

<!--加入activemq队列--><dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-activemq</artifactId></dependency>

application.properties:

#配置activemqspring.activemq.broker-url=tcp://localhost;61616
代码:

package com.yjp.activemq;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jms.annotation.JmsListener;import org.springframework.jms.core.JmsTemplate;import org.springframework.stereotype.Component;import javax.jms.Destination;/** * 生产者 * * @Author :  * Date : 11:18 2017/12/13 */@Componentpublic class SmsProcessor {    private static final Logger LOGGER = LoggerFactory.getLogger(SmsProcessor.class);    @Autowired    private JmsTemplate jmsTemplate;    /**     * 发送消息的方法     *     * @param destination 队列名字     * @param message     发送的消息     */    public void sendSmsToQueue(Destination destination, String message) {        jmsTemplate.convertAndSend(destination, message);    }    /**     * @param message 监听队列名为 active_queue     */    @JmsListener(destination = "active_queue")    public void doSendSmsMessage(String message) {        System.out.print(message);    }}

测试:

package springboot;import com.yjp.activemq.SmsProcessor;import com.yjp.rabbitmq.HelloSender;import com.yjp.rabbitmq.LoginApplication;import org.apache.activemq.command.ActiveMQQueue;import org.apache.activemq.command.ActiveMQTopic;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import javax.jms.Destination;@RunWith(SpringRunner.class)/** * webEnvironment需要MVC的支持 * SpringBootTest.WebEnvironment.RANDOM_PORT 启动Servlet环境 端口号随机 */@SpringBootTest(classes = LoginApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)public class LoginApplicationTests {    @Autowired    private HelloSender helloSender;    @Autowired    private SmsProcessor smsProcessor;    @Test    public void contextLoads() {        Destination destination = new ActiveMQQueue("active_queue");        Destination destination1 = new ActiveMQTopic("active_topic");        smsProcessor.sendSmsToQueue(destination, "你好");    }}


整合到此结束,有问题欢迎指出。

原创粉丝点击