ActiveMQ初实践之【二】——持久化方式

以”如何将消息持久化到Mysql数据库中“为例

第一种:点到点类型

1、将mysql的驱动包放置到ActiveMQ的lib目录下
2、修改activeMQ的配置文件activemq.xml:

<persistenceAdapter>
    <jdbcPersistenceAdapter useDatabaseLock="false" dataDirectory="${activemq.base}/data" dataSource="#mysql-ds" createTablesOnStartup="true" />
</persistenceAdapter>

3、 在配置文件activemq.xml中的broker节点外增加:

<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
              <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://localhost:3306/activemq?relaxAutoCommit=true"/>
              <property name="username" value="root"/>
              <property name="password" value="root"/>
              <property name="maxActive" value="200"/>
              <property name="poolPreparedStatements" value="true"/>
</bean>

4、从配置中可以看出数据库的名称是activemq,需要手动在MySql中建立这个数据库。

5、重新启动activeMQ,会发现activemq多了三张表:

1:activemq_acks

2:activemq_lock

3:activemq_msgs

6、创建消息生产者和消费者类

Provider

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Provider {

    private static final int SEND_NUMBER = 2000;

    public static void main(String[] args) {

        // 连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // JMS客户端到JMS Provider的连接
        Connection connection = null;
        // 发送或接收消息的线程
        Session session = null;
        // 消息的目的地,消息发送给谁
        Destination destination;
        // 消息发送者
        MessageProducer producer = null;
        // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");

        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
            // 获取session,“FirstQueue”是一台服务器的queue
            destination = session.createQueue("FirstQueue");
            // 得到消息生产者
            producer = session.createProducer(destination);
            // 设置不持久化
            producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
            // 构造消息
            send(session, producer);
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (null != connection) {
                try {
                    producer.close();
                    session.commit();
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void send(Session session, MessageProducer producer)
            throws JMSException {
        for (int i = 0; i < SEND_NUMBER; i++) {
            // 创建消息
            TextMessage msg = session.createTextMessage("消息" + i);
            // 发送消息
            producer.send(msg);
            System.out.println("发送消息:消息" + i);
        }
    }
}

Customer

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Customer {

    public static void main(String[] args) {
        // 连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // JMS客户端到JMS Provider的连接
        Connection connection = null;
        // 发送或接收消息的线程
        Session session = null;
        // 消息的目的地,消息发送给谁
        Destination destination;
        // 消息发送者
        MessageConsumer consumer = null;
        // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
            // 创建queue
            destination = session.createQueue("FirstQueue");
            // 得到消息消费者
            consumer = session.createConsumer(destination);
            while (true) {
                // 设置消息接收者接收消息的时间,便于测试,设定100S
                TextMessage message = (TextMessage) consumer.receive(100000);
                if (null != message) {
                    System.out.println("收到消息:" + message.getText());
                } else {
                    break;
                }
            }
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != consumer) { consumer.close();}
                if (null != session) {  session.commit();}
                if (null != connection) {   connection.close(); }
            } catch (Throwable ignore) {
            }
        }
    }
}

7、测试

测试一:

    A、 先运行Sender类,待运行完毕后,运行Receiver类

    B、 在此过程中activemq数据库的activemq_msgs表中没有数据

    C、 再次运行Receiver,消费不到任何信息

测试二:

    A、  先运行Sender类

    B、 重启电脑

    C、 运行Receiver类,无任何信息被消费

测试三:

    A、   把Sender类中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改为producer.setDeliveryMode(DeliveryMode.PERSISTENT);

    B、   先运行Sender类,待运行完毕后,运行Receiver类

    C、   在此过程中activemq数据库的activemq_msgs表中有数据生成,运行完Receiver类后,数据清除

测试四:

    A、    把Sender类中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改为producer.setDeliveryMode(DeliveryMode.PERSISTENT);

    B、    运行Sender类

    C、    重启电脑

    D、    运行Receiver类,有消息被消费

结论:

    通过以上测试,可以发现,在P2P类型中当DeliveryMode设置为NON_PERSISTENCE时,消息被保存在内存中,而当DeliveryMode设置为PERSISTENCE时,消息保存在broker的相应的文件或者数据库中。而且P2P中消息一旦被Consumer消费就从broker中删除。

第二种:发布订阅类型

8、创建消息生产者和消费者类

Provider2

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Provider2 {

    private static final int SEND_NUMBER = 2000;

    public static void main(String[] args) {

        // 连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // JMS客户端到JMS Provider的连接
        Connection connection = null;
        // 发送或接收消息的线程
        Session session = null;
        // 消息发送者
        MessageProducer producer = null;
        // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");

        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
            //创建主题
            Topic topic = session.createTopic("TEST_MQ");
            // 得到消息生产者
            producer = session.createProducer(topic);
            // 设置持久化
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);
            // 构造消息
            send(session, producer);
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (null != connection) {
                try {
                    producer.close();
                    session.commit();
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void send(Session session, MessageProducer producer)
            throws JMSException {
        for (int i = 0; i < SEND_NUMBER; i++) {
            // 创建消息
            TextMessage msg = session.createTextMessage("消息" + i);
            // 发送消息
            producer.send(msg);
            System.out.println("发送消息:消息" + i);
        }
    }
}

Customer2

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Customer2 {

    public static void main(String[] args) {
        // 连接工厂,JMS用它创建连接
        ConnectionFactory connectionFactory;
        // JMS客户端到JMS Provider的连接
        Connection connection = null;
        // 发送或接收消息的线程
        Session session = null;
        // 消息发送者
        MessageConsumer consumer = null;
        // 构造ConnectionFactory实例对象,此处采用ActiveMq的实现
        connectionFactory = new ActiveMQConnectionFactory(
                ActiveMQConnection.DEFAULT_USER,
                ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
        try {
            // 构造从工厂得到连接对象
            connection = connectionFactory.createConnection();

            connection.setClientID("clientID007");
            // 启动
            connection.start();
            // 获取操作连接
            session = connection.createSession(Boolean.FALSE,
                    Session.AUTO_ACKNOWLEDGE);
            // 获取session
            Topic topic = session.createTopic("TEST_MQ");
            // 得到消息消费者
            consumer = session.createConsumer(topic);
            while (true) {
                // 设置消息接收者接收消息的时间,便于测试,设定100S
                TextMessage message = (TextMessage) consumer.receive(100000);
                if (null != message) {
                    System.out.println("收到消息:" + message.getText());
                } else {
                    break;
                }
            }
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != consumer) { consumer.close();}
                if (null != session) {  session.commit();}
                if (null != connection) {   connection.close(); }
            } catch (Throwable ignore) {
            }
        }
    }
}

9、测试

测试一:

    A、先启动Sender类

    B、再启动Receiver类

    C、结果无任何记录被订阅

测试二:

    A、先启动Receiver类,让Receiver在相关主题上进行订阅

    B、停止Receiver类,再启动Sender类

    C、待Sender类运行完成后,再启动Receiver类

    D、结果发现相应主题的信息被订阅

Reference


项目实例

猜你喜欢

转载自blog.csdn.net/haoyutc/article/details/60137780
今日推荐