ActiveMQ入门示例
ActiveMQ有两种模式,点对点和发布/订阅模式,点对点中消息只能被一个消费者消费,而发布订阅中,消息可以被一群消费者消费,很好理解。下面的例子是点对点的
安装ActiveMQ很简单就不说了,客户端使用API只需添加以下依赖:
- <dependency>
- <groupId>org.apache.activemq</groupId>
- <artifactId>activemq-all</artifactId>
- <version>5.9.1</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
代码:
Sender.java:
- package cc.lixiaohui.test.jms.activemq.p2p;
- import java.util.UUID;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import javax.jms.Connection;
- import javax.jms.ConnectionFactory;
- import javax.jms.Destination;
- import javax.jms.JMSException;
- import javax.jms.MessageProducer;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.apache.log4j.Logger;
- import cc.lixiaohui.test.jms.activemq.Constants;
- public class Sender {
- //发送间隔
- private long interval = 1 * 1000;
- private ConnectionFactory factory;
- private Connection conn;
- private Destination dest;
- private Session session;
- private MessageProducer producer;
- // 单线程池负责发送
- private ExecutorService worker = Executors.newSingleThreadExecutor();
- private volatile boolean stop = false;
- private static final Logger logger = Logger.getLogger(Sender.class);
- public Sender(String brokenURL, String user, String passwd,
- String queueName) throws JMSException {
- factory = new ActiveMQConnectionFactory(user, passwd, brokenURL);
- conn = factory.createConnection();
- conn.start();
- session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
- dest = session.createQueue(queueName);
- producer = session.createProducer(dest);
- }
- public void setInterval(long l) {
- interval = l;
- }
- public void start() {
- worker.submit(new SendTask());
- }
- public synchronized void stop() {
- stop = true;
- worker.shutdown();
- }
- private TextMessage randomMsg() {
- String uuid = UUID.randomUUID().toString();
- TextMessage msg = null;
- try {
- msg = session.createTextMessage(uuid);//把uuid作为消息
- msg.setJMSCorrelationID(uuid);
- } catch (JMSException e) {
- e.printStackTrace();
- }
- return msg;
- }
- private class SendTask implements Runnable {
- public void run() {
- logger.info("Send task begin...");
- while (!stop) {
- try {
- // 发送
- TextMessage msg = randomMsg();
- producer.send(msg);
- session.commit(); // commit后消息才会发送到服务端
- logger.info("Send text message : " + msg.getText());
- // 间隔
- Thread.sleep(interval);
- } catch (Exception e) {
- e.printStackTrace();
- break;
- }
- }
- logger.info("Send task finished...");
- }
- }
- public static void main(String[] args) throws JMSException {
- Sender sender = new Sender(Constants.URL, Constants.USER, Constants.PASSWD, Constants.DEFAULT_QUEUE);
- sender.start();
- }
- }
Reciever.java:
- package cc.lixiaohui.test.jms.activemq.p2p;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import javax.jms.Connection;
- import javax.jms.ConnectionFactory;
- import javax.jms.Destination;
- import javax.jms.JMSException;
- import javax.jms.Message;
- import javax.jms.MessageConsumer;
- import javax.jms.MessageListener;
- import javax.jms.Session;
- import javax.jms.TextMessage;
- import org.apache.activemq.ActiveMQConnectionFactory;
- import org.apache.log4j.Logger;
- import cc.lixiaohui.test.jms.activemq.Constants;
- public class Reciever {
- public static final int RECIEVE_MODE_SYNC = 0;
- public static final int RECIEVE_MODE_ASYNC = 1;
- private ConnectionFactory factory;
- private Connection conn;
- private Destination dest;
- private Session session;
- private MessageConsumer consumer;
- private ExecutorService worker = Executors.newSingleThreadExecutor();
- private volatile boolean stop = false;
- private long interval = 3 * 1000;
- private static final Logger logger = Logger.getLogger(Reciever.class);
- // 同步/异步接收模式,默认同步
- private int mode = RECIEVE_MODE_SYNC;
- public Reciever(String brokenURL, String user, String passwd,
- String queueName) throws JMSException {
- factory = new ActiveMQConnectionFactory(user, passwd, brokenURL);
- conn = factory.createConnection();
- conn.start();
- session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
- dest = session.createQueue(queueName);
- consumer = session.createConsumer(dest);
- }
- public void setInterval(long l) {
- interval = l;
- }
- public void setMode(int mode) {
- this.mode = mode;
- }
- public void start() throws JMSException {
- if (mode == RECIEVE_MODE_ASYNC) {// 异步
- logger.info("Recieved task begin in async mode...");
- // 由activemq组件回调
- consumer.setMessageListener(new MessageListener() {
- public void onMessage(Message message) {
- handleRecievedMessage(message);
- try {
- session.commit();
- } catch (JMSException e) {
- e.printStackTrace();
- stop = true;
- }
- }
- });
- } else if (mode == RECIEVE_MODE_SYNC) {// 同步, 由于另起线程, 这里也不阻塞
- worker.submit(new RecieveTask());
- }
- }
- private void handleRecievedMessage(Message recievedMsg) {
- if (recievedMsg instanceof TextMessage) {
- TextMessage msg = (TextMessage) recievedMsg;
- try {
- logger.info("Recieved message : " + msg.getText());
- } catch (JMSException e) {
- e.printStackTrace();
- }
- }
- }
- public void stop() {
- stop = true;
- }
- private class RecieveTask implements Runnable {
- public void run() {
- logger.info("Recieved task begin in sync mode...");
- while (!stop) {
- try {
- Message msg = consumer.receive();
- handleRecievedMessage(msg);
- session.commit();
- Thread.sleep(interval);
- } catch (Exception e) {
- e.printStackTrace();
- break;
- }
- }
- logger.info("Recieve task finished...");
- }
- }
- public static void main(String[] args) throws JMSException {
- Reciever reciever = new Reciever(Constants.URL, Constants.USER,
- Constants.PASSWD, Constants.DEFAULT_QUEUE);
- reciever.setMode(RECIEVE_MODE_ASYNC);
- reciever.start();
- }
- }
测试结果:
1.Reciever在ASYNC模式,注意看日志时间,可以看到Sender一旦了消息,Reciever就会接受到消息(忽略网络)
2.Reciever在ASYNC模式下,Sender每秒发一个消息,而接收者每3秒接收一个消息:可以看到Reciever接受的时间是和Sender发送的时间是无联系的。