JMS编程例子

初试在队列上发布/接收消息
/**
* JMS操作基类,用于统一获取连接,关闭连接
*
* @author sunjun
*/
public class JMSBase {

private final static String URL = "tcp://localhost:61616";
private final static String JNDI_NAME_CONNECTIONFACTORY = "connectionFactory";
private final static String JNDI_NAME_QUEUE_CONNECTIONFACTORY = "queueConnectionFactory";
private final static String JNDI_NAME_TOPIC_CONNECTIONFACTORY = "topicConnectionFactry";

protected final static String QUEUE_NAME = "test.queue1";

/**
* 创建ConnectionFactory
*
* @param useJNDI
* true:通过 JNDI创建<br>
* false:直接通过brokerUrl创建
* @return
* @throws NamingException
*/
private ConnectionFactory getConnectionFactory(boolean useJNDI)
throws NamingException {
if (useJNDI) {
InitialContext context = new InitialContext();
return (ConnectionFactory) context
.lookup(JNDI_NAME_CONNECTIONFACTORY);
}
return new ActiveMQConnectionFactory(URL);
}

/**
* 创建Connection
*
* @return
* @throws Exception
*/
protected Connection getConnection() throws Exception {
return getConnectionFactory(true).createConnection();
}

/**
* 关闭Session,Connection
*
* @param session
* @param connection
* @throws JMSException
*/
protected void close(Session session, Connection connection)
throws JMSException {
if (session != null)
session.close();
if (connection != null)
connection.close();
}
}

/**
* 发送JMS消息,PTP,发送一个持久的文本消息到队列test.queue1上,即使activemq重启,消息也不会丢失
*
* @author sunjun
*/
public class Publisher extends JMSBase {

@Test
public void testPublish() throws Exception {
// 创建得connection
Connection connection = getConnection();
// connection.start();

// 创建session
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);

// 创建queue
Queue queue = session.createQueue(QUEUE_NAME);

// 创建producer
MessageProducer producer = session.createProducer(queue);
// 发送的消息进行持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

// 创建一个文本消息
Message message = session.createTextMessage("text message content.");
message.setStringProperty("property1", "value1");

// 发送消息
producer.send(message);

// 关闭session,connection
close(session, connection);

System.out.println("publish text message success.");
}
}

/**
* 接收JMS消息,PTP,接收队列test.queue1上的所有消息<br>
* 接收有两种方式:主动去receive,通过见听器异步接收
*
* @author sunjun
*/
public class Receiver extends JMSBase implements MessageListener {

@Test
public void testRecieve() throws Exception {
// 创建connection
Connection connection = getConnection();
// 开始
connection.start(); // 只有开始了才能接收消息

// 创建session
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);

// 创建queue
Queue queue = session.createQueue(QUEUE_NAME);

// 创建consumer
MessageConsumer consumer = session.createConsumer(queue);

receiveMessage(false, consumer);
}

/**
* 接收所有消息
*
* @param sync
* @param consumer
* @throws JMSException
*/
private void receiveMessage(boolean sync, MessageConsumer consumer)
throws JMSException {
if (sync) {
// 主动接收,同步接收
int i = 0;
while (true) {
i++;
Message receive = consumer.receive();
if (receive != null) {
System.out.println("receive message:"
+ ((TextMessage) receive).getText() + " with i="
+ i + " at time " + new Date().toLocaleString());
}
}
} else {
// 被动接收,异步接收
consumer.setMessageListener(this);
while (true) {
}
}
}

@Override
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
System.out.print("receive a text message:");
System.out.print(((TextMessage) message).getText());
System.out.println(" at time " + new Date().toLocaleString());
}
} catch (JMSException e) {
e.printStackTrace();
}
}

}

运行发送和接收,接收端收到消息如下:
receive a text message:text message content. at time 2010-11-1 22:40:16
receive a text message:text message content. at time 2010-11-1 22:40:16

一个queue上多个consumer

/**
* 测试一个队列上有多人在发送消息,和多人同时接收消息的情况
*
* @author sunjun
*/
public class QueueTest extends JMSBase {

private static final String QUEUE_NAME = "my.queue2";

public static void main(String[] args) {
QueueTest test = new QueueTest();

// 接收消息
for (int i = 1; i <= 2; i++) {
new Thread(test.new Receiver("consumer" + i)).start();
}
// 发送消息
for (int i = 0; i < 4; i++)
new Thread(test.new Sender()).start();
}

class Sender extends JMSBase implements Runnable {

@Override
public void run() {
try {
Connection con = getConnection();

Session session = con.createSession(false,
Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue(QUEUE_NAME);
MessageProducer producer = session.createProducer(queue);

for (int i = 0; i < 5; i++) {
Thread.sleep(2000);
TextMessage message = session
.createTextMessage("text message width thread-"
+ Thread.currentThread() + " index-" + i);
producer.send(message);
}

close(session, con);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Receiver extends JMSBase implements Runnable {

private String name;

public Receiver(String name) {
this.name = name;
}

@Override
public void run() {
Connection con;
try {
con = getConnection();
con.start();

Session session = con.createSession(false,
Session.AUTO_ACKNOWLEDGE);

Queue queue = session.createQueue(QUEUE_NAME);
MessageConsumer consumer = session.createConsumer(queue);
//也可以修改为MessageListener
while (true) {
Message message = consumer.receive();
if (message != null) {
System.out.println(name + " message:"
+ ((TextMessage) message).getText());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结论:
1,一个队列上如果有多个消费者,那么每个消息仅会被一个消费者取到并处理。
2,一个队列上如果有多个消息,多个消费者,每个消息到底由哪个消息者接收是不可知的,有随机性,但是经过测试发现虽然有随机性,但是也有简单的类似于均匀分配的机制
2个接收者,4个发送者,输出结果
consumer1 message:text message width thread-Thread[Thread-2,5,main] index-0
consumer1 message:text message width thread-Thread[Thread-3,5,main] index-0
consumer2 message:text message width thread-Thread[Thread-4,5,main] index-0
consumer2 message:text message width thread-Thread[Thread-5,5,main] index-0
consumer1 message:text message width thread-Thread[Thread-4,5,main] index-1
consumer2 message:text message width thread-Thread[Thread-5,5,main] index-1
consumer1 message:text message width thread-Thread[Thread-2,5,main] index-1
consumer2 message:text message width thread-Thread[Thread-3,5,main] index-1
consumer1 message:text message width thread-Thread[Thread-5,5,main] index-2
consumer2 message:text message width thread-Thread[Thread-4,5,main] index-2
consumer1 message:text message width thread-Thread[Thread-3,5,main] index-2
consumer2 message:text message width thread-Thread[Thread-2,5,main] index-2
consumer1 message:text message width thread-Thread[Thread-4,5,main] index-3
consumer2 message:text message width thread-Thread[Thread-5,5,main] index-3
consumer1 message:text message width thread-Thread[Thread-2,5,main] index-3
consumer2 message:text message width thread-Thread[Thread-3,5,main] index-3
consumer1 message:text message width thread-Thread[Thread-5,5,main] index-4
consumer2 message:text message width thread-Thread[Thread-4,5,main] index-4
consumer1 message:text message width thread-Thread[Thread-3,5,main] index-4
consumer2 message:text message width thread-Thread[Thread-2,5,main] index-4

一个topic上多个consumer
**
* 测试一个topic上有多人在发送消息,和多人同时接收消息的情况
*
* @author sunjun
*/
public class TopicTest1 extends JMSBase {

public static void main(String[] args) throws InterruptedException {
TopicTest1 topic = new TopicTest1();
// 接收消息
for (int i = 1; i <= 2; i++)
new Thread(topic.new Receiver("consumer" + i)).start();
// 发送消息
for (int i = 0; i < 2; i++)
new Thread(topic.new Sender()).start();
}

private Destination getDestination(Session session) throws JMSException {
return session.createTopic("my.topic");
}

class Sender extends JMSBase implements Runnable {

@Override
public void run() {
try {
Connection con = getConnection();

Session session = con.createSession(false,
Session.AUTO_ACKNOWLEDGE);

Destination destination = getDestination(session);

MessageProducer producer = session.createProducer(destination);
// 发送的消息进行持久化
producer.setDeliveryMode(DeliveryMode.PERSISTENT);

for (int i = 0; i < 5; i++) {
Thread.sleep(2000);
TextMessage message = session
.createTextMessage("text message with thread-"
+ Thread.currentThread() + " index-" + i);
producer.send(message);
}

close(session, con);
} catch (Exception e) {
e.printStackTrace();
}
}

}

class Receiver extends JMSBase implements Runnable {

private String name;

public Receiver(String name) {
this.name = name;
}

@Override
public void run() {
Connection con;
try {
con = getConnection();
con.start();

Session session = con.createSession(false,
Session.AUTO_ACKNOWLEDGE);

Destination destination = getDestination(session);
MessageConsumer consumer = session.createConsumer(destination);

while (true) {
Message message = consumer.receive();
if (message != null) {
System.out.println(name + " message:"
+ ((TextMessage) message).getText());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结论:
1,对于topic,consumer只能接收到它注册到topic上以后别人发送到topic的消息
2,每个consumer都会收到topic上的每个消息
测试输出:
consumer2 message:text message with thread-Thread[Thread-1,5,main] index-0
consumer1 message:text message with thread-Thread[Thread-1,5,main] index-0
consumer1 message:text message with thread-Thread[Thread-0,5,main] index-0
consumer2 message:text message with thread-Thread[Thread-0,5,main] index-0
consumer1 message:text message with thread-Thread[Thread-1,5,main] index-1
consumer1 message:text message with thread-Thread[Thread-0,5,main] index-1
consumer2 message:text message with thread-Thread[Thread-1,5,main] index-1
consumer2 message:text message with thread-Thread[Thread-0,5,main] index-1
consumer2 message:text message with thread-Thread[Thread-1,5,main] index-2
consumer1 message:text message with thread-Thread[Thread-1,5,main] index-2
consumer2 message:text message with thread-Thread[Thread-0,5,main] index-2
consumer1 message:text message with thread-Thread[Thread-0,5,main] index-2
consumer1 message:text message with thread-Thread[Thread-1,5,main] index-3
consumer2 message:text message with thread-Thread[Thread-1,5,main] index-3
consumer2 message:text message with thread-Thread[Thread-0,5,main] index-3
consumer1 message:text message with thread-Thread[Thread-0,5,main] index-3
consumer1 message:text message with thread-Thread[Thread-1,5,main] index-4
consumer2 message:text message with thread-Thread[Thread-1,5,main] index-4
consumer1 message:text message with thread-Thread[Thread-0,5,main] index-4
consumer2 message:text message with thread-Thread[Thread-0,5,main] index-4
测试Message的JMSReplyTo属性
/**
* 测试Message.JMSReplyTo属性
*
* @author sunjun
*/
public class ReplyTest extends JMSBase {

/**
* 发送消息
*
* @throws Exception
*/
public void testSend() throws Exception {
Connection con = getConnection();
con.start();

Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue_1");

MessageProducer producer = session.createProducer(queue);
// 设置回复地址
Queue replyQueue = session.createQueue("queue_1_reply");
TextMessage msg = session.createTextMessage("hello");
msg.setJMSReplyTo(replyQueue);
producer.send(msg);

MessageConsumer consumer = session.createConsumer(replyQueue);
// 接收回复消息
consumer.setMessageListener(new MessageListener() {

@Override
public void onMessage(Message message) {
try {
if (message != null && message instanceof TextMessage) {
System.out.println("reply msg:"
+ ((TextMessage) message).getText());
}
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}

/**
* 接收消息
*
* @throws Exception
*/
public void testReceive() throws Exception {
final Connection con = getConnection();
con.start();
Session session = con.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue("queue_1");
MessageConsumer consumer = session.createConsumer(queue);
// 接收消息
consumer.setMessageListener(new MessageListener() {

@Override
public void onMessage(Message message) {
try {
if (message != null && message instanceof TextMessage) {
System.out.println("msg:"
+ ((TextMessage) message).getText());

// 发送回复消息
Destination replyQueue = message.getJMSReplyTo();
Session session = con.createSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session
.createProducer(replyQueue);
TextMessage msg = session.createTextMessage("thanks");
producer.send(msg);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}

/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
ReplyTest test = new ReplyTest();
test.testReceive();
test.testSend();
}

}
通过使用这个replyTo,我们可以通过JMS来实现远程接口调用的功能,就象以前的RabbitMQ一样,只不过它们遵从的协议不一样,
内部构造及其设计也有些区别,但都是消息中间件,发送接收消息的基本功能都是一样的,有空写个试试看。

posted @ 2014-06-16 22:59  princessd8251  阅读(330)  评论(0)    收藏  举报