ActiveMQ入门和实例

来源:互联网 发布:欧洲中世纪知乎 编辑:程序博客网 时间:2024/06/07 08:17

简介

为了适应当前分布式系统的发展,系统与系统之间的通信尤为重要。而JMS就是为了将系统之间解耦,以消息中间件的形式连接系统。以下是ActiveMQ的简单介绍和入门实例

下载安装ActiveMQ

  • 进入下载地址,下载适应版本。
  • 解压后进入bin目录点击activemq.bat(windows下)启动即可。
  • 启动失败请依次检查jdk版本和端口61616是否被占用。

通信方式

  • 点对点/P2P
  • 发布者&订阅者

以上两种通信方式就是最基础的消息通信方式,还可以根据它们衍生出消息回执的通信方式

点对点通信

点对点通信

点对点通信就像通话一样,一个生产者发出的消息只有一个消费者接收到并进行处理。

package com.paditang.activemq.p2p;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;public class Producer {    private ConnectionFactory factory;    private Connection connection;    private Session session;    private MessageProducer producer;    private Destination destination;    public Producer(String queueName) throws JMSException{        factory = new ActiveMQConnectionFactory();        connection = factory.createConnection();        connection.start();        try{            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        } catch(JMSException e){            connection.close();            throw e;        }        destination = session.createQueue(queueName);        producer = session.createProducer(destination);    }    public void sendMsg(String content) throws JMSException{        TextMessage msg = session.createTextMessage(content);        producer.send(msg);    }    public void close() throws JMSException{        connection.close();    }    public static void main(String []args) throws JMSException{        Producer p = new Producer("test_queue");        p.sendMsg("listener msg");        p.close();    }}
package com.paditang.activemq.p2p;import java.util.concurrent.Executor;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.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnectionFactory;import com.paditang.activemq.base.MsgListener;public class Consumer {    private ConnectionFactory factory;    private Connection connection;    private Session session;    private Destination destination;    private MessageConsumer consumer;    public Consumer(String queueName) throws JMSException{        factory = new ActiveMQConnectionFactory();        connection = factory.createConnection();        connection.start();        try{            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        } catch(JMSException e){            connection.close();            throw e;        }        destination = session.createQueue(queueName);        consumer = session.createConsumer(destination);    }    //通过receive方法接收消息    public void receiveMessage() throws JMSException{        while(true){            Message msg = consumer.receive();            if(msg instanceof TextMessage){                String str = ((TextMessage)msg).getText();                System.out.println(str);            }        }    }    //通过设置监听器收消息    public void receiveByListener() throws JMSException{        consumer.setMessageListener(new MsgListener());    }    public void close() throws JMSException{        connection.close();    }    public static void main(String []args) throws JMSException{        Runnable r = new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                try{                    Consumer consumer = new Consumer("test_queue");                    //consumer.receiveMessage();                    consumer.receiveByListener();                    //consumer.close();                }catch(JMSException e){                    e.printStackTrace();                }            }        };        Executor e = Executors.newFixedThreadPool(10);        for(int i =0; i < 10; i++){            e.execute(r);        }    }}
package com.paditang.activemq.base;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;public class MsgListener implements MessageListener{    @Override    public void onMessage(Message message) {        if(message instanceof TextMessage){            try{                System.out.println("get msg:"+((TextMessage)message).getText());            } catch(JMSException e){                e.printStackTrace();            }        }       }}
console: INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616get msg:listener msg

如上一个生产者生产消息,十个消费者消费消息的模型下。当发出一条消息,只有一个消费者接收到消息。可以证明点对点通信方式的通信逻辑。

发布者&订阅者

发布者&订阅者模式更类似于订阅报纸。每当报社有新报纸发布后,都将通知并配送到订阅人手里。而这种模式类似,当发布者发布消息到Topic上,会将消息发送到到活跃的订阅者中。

发布者&订阅者

package com.paditang.activemq.topic;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageProducer;import javax.jms.Session;import org.apache.activemq.ActiveMQConnectionFactory;public class Publisher {    private ConnectionFactory connectionFactory;    private Connection connection;    private Session session;    private MessageProducer producer;    private Destination destination;    public Publisher(String topicName) throws JMSException{        connectionFactory = new ActiveMQConnectionFactory();        connection = connectionFactory.createConnection();        try{            connection.start();        }catch(JMSException e){            connection.close();            throw e;        }        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        destination = session.createTopic(topicName);        producer = session.createProducer(destination);    }    public void sendMessage(String message) throws JMSException{        Message msg = session.createTextMessage(message);        producer.send(msg);    }    public void close() throws JMSException{        if(connection != null){            connection.close();        }    }    public static void main(String []args) throws JMSException{        Publisher p = new Publisher("test_topic");        p.sendMessage("first msg");        p.close();    }}
package com.paditang.activemq.topic;import java.util.concurrent.Executor;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.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnectionFactory;public class Listener {    private ConnectionFactory factory;    private Connection connection;    private Session session;    private Destination destination;    private MessageConsumer consumer;    public Listener(String topicName) throws JMSException{        factory = new ActiveMQConnectionFactory();        connection = factory.createConnection();        connection.start();        try{            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        } catch(JMSException e){            connection.close();            throw e;        }        destination = session.createTopic(topicName);        consumer = session.createConsumer(destination);    }    public void receiveMessage() throws JMSException{        while(true){            Message msg = consumer.receive();            if(msg instanceof TextMessage){                String str = ((TextMessage)msg).getText();                System.out.println(str);            }        }    }    public void close() throws JMSException{        connection.close();    }    public static void main(String []args) throws JMSException{        Runnable r = new Runnable() {            @Override            public void run() {                // TODO Auto-generated method stub                try{                    Listener consumer = new Listener("test_topic");                    consumer.receiveMessage();                    consumer.close();                }catch(JMSException e){                    e.printStackTrace();                }            }        };        Executor e = Executors.newFixedThreadPool(10);        for(int i =0; i < 10; i++){            e.execute(r);        }    }}
listener-console: INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616 INFO | Successfully connected to tcp://localhost:61616first msgfirst msgfirst msgfirst msgfirst msgfirst msgfirst msgfirst msgfirst msgfirst msg

从输出上来看,当生成十个订阅者订阅目标topic时,当发布者发布一条消息,所有订阅者都能收到这条消息。

这就是和P2P的不同之处。

收到消息回复模式

可以通过一些方式使得生产者得到消费者收到消息后的回执,这就是这种模式的意义

reply

package com.paditang.activemq.reply;import javax.jms.Connection;import javax.jms.ConnectionFactory;import javax.jms.Destination;import javax.jms.JMSException;import javax.jms.MessageConsumer;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnectionFactory;import com.paditang.activemq.base.MsgListener;public class Client {    private static String USER_NAME = ActiveMQConnectionFactory.DEFAULT_USER;    private static String PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD;    private static String BROKE_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL;    private ConnectionFactory factory;    private Connection connection;    private Session session;    private Destination destination;    private MessageProducer producer;    public Client(String queueName) throws JMSException{        factory = new ActiveMQConnectionFactory(USER_NAME, PASSWORD, BROKE_URL);        connection = factory.createConnection();        try{            connection.start();        } catch(JMSException e){            connection.close();            throw e;        }        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        destination = session.createQueue(queueName);        producer = session.createProducer(destination);    }    public void sendMessage(String content) throws JMSException{        Destination tmpDestination = session.createTemporaryQueue();        MessageConsumer retConsumer = session.createConsumer(tmpDestination);        retConsumer.setMessageListener(new MsgListener());        TextMessage msg = session.createTextMessage(content);        msg.setJMSReplyTo(tmpDestination);        String uuid = generateRandomTag();        msg.setJMSCorrelationID(uuid);        producer.send(msg);        System.out.println("send msg:"+msg);    }    public String generateRandomTag(){        return String.valueOf(System.currentTimeMillis());    }    public static void main(String []args) throws JMSException{        Client client = new Client("server_queue");        client.sendMessage("info");    }}
package com.paditang.activemq.reply;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.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnectionFactory;public class Server {    private static String USER_NAME = ActiveMQConnectionFactory.DEFAULT_USER;    private static String PASSWORD = ActiveMQConnectionFactory.DEFAULT_PASSWORD;    private static String BROKE_URL = ActiveMQConnectionFactory.DEFAULT_BROKER_URL;    private ConnectionFactory factory;    private Connection connection;    private Session session;    private Destination destination;    private MessageConsumer consumer;    public Server(String queueName) throws JMSException{        factory = new ActiveMQConnectionFactory(USER_NAME, PASSWORD, BROKE_URL);        connection = factory.createConnection();        try{            connection.start();        } catch(JMSException e){            connection.close();            throw e;        }        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);        destination = session.createQueue(queueName);        consumer = session.createConsumer(destination);    }    public void receiveMessage() throws JMSException{        while(true){            Message msg = consumer.receive();            String retStr = "initial ret";            if(msg instanceof TextMessage){                System.out.println("get msg:"+((TextMessage)msg).getText());                retStr = ((TextMessage)msg).getText();            }            MessageProducer retProducer = session.createProducer(null);            TextMessage retMsg = session.createTextMessage(retStr);            retMsg.setJMSCorrelationID(msg.getJMSCorrelationID());            retProducer.send(msg.getJMSReplyTo(),retMsg);            System.out.println("ret msg:"+retStr);        }    }    public static void main(String []args) throws JMSException{        Server server = new Server("server_queue");        server.receiveMessage();    }}