以”如何将消息持久化到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、结果发现相应主题的信息被订阅