JMS(ActiveMQ) PTP和PUB/SUB模式实例

深入浅出JMS(一)——JMS简介 :[url]http://blog.youkuaiyun.com/aking21alinjuju/article/details/6051421[/url]
深入浅出JMS(二)——JMS的组成 :[url]http://blog.youkuaiyun.com/aking21alinjuju/article/details/6071123[/url]
JMS消息详解 :[url]http://blog.youkuaiyun.com/buoymp/article/details/784696[/url]
深入掌握JMS(一):JSM基础 :[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034713[/url]
深入掌握JMS(二):一个JMS例子:[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034775[/url]
深入掌握JMS(三):MessageListener:[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034788[/url]
深入掌握JMS(四):实战Queue:[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034801[/url]
深入掌握JMS(五):实战Topic :[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034811[/url]
深入掌握JMS(六):消息头 :[url]http://blog.youkuaiyun.com/zhangxs_3/article/details[/url]/4034834
深入掌握JMS(七):DeliveryMode例子:[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034837[/url]
深入掌握JMS(八):JMSReplyTo :[url]http://blog.youkuaiyun.com/zhangxs_3/article/details/4034847[/url]
JMS应用示例教程:[url]http://qidaoxp.iteye.com/blog/480047[/url]
JMS与MQ详解:[url]http://www.fx114.net/qa-48-91234.aspx[/url]
JMS(ActiveMQ) PTP和PUB/SUB模式实例:[url]http://donald-draper.iteye.com/blog/2347445[/url]
ActiveMQ连接工厂、连接详解:[url]http://donald-draper.iteye.com/blog/2348070[/url]
ActiveMQ会话初始化:[url]http://donald-draper.iteye.com/blog/2348341[/url]
ActiveMQ生产者:[url]http://donald-draper.iteye.com/blog/2348381[/url]
ActiveMQ消费者:[url]http://donald-draper.iteye.com/blog/2348389[/url]
ActiveMQ启动过程详解[url]:http://donald-draper.iteye.com/blog/2348399[/url]
ActiveMQ Broker发送消息给消费者过程详解:[url]http://donald-draper.iteye.com/blog/2348440[/url]
Spring与ActiveMQ的集成:[url]http://donald-draper.iteye.com/blog/2347638[/url]
Spring与ActiveMQ的集成详解一:[url]http://donald-draper.iteye.com/blog/2348449[/url]
Spring与ActiveMQ的集成详解二:[url]http://donald-draper.iteye.com/blog/2348461[/url]
在做下面的测试之前要先安装ActiveMQ,下载apache-activemq-5.12.1-bin.tar.gz包,解压后
目录如下:
[code="java"]# ls
activemq-all-5.12.1.jar bin conf data docs examples lib LICENSE NOTICE README.txt tmp webapps webapps-demo
# cd bin[/code]

启动ActiveMQ
[code="java"]# ./activemq start
INFO: Loading '/acivemq/apache-activemq-5.12.1//bin/env'
INFO: Using java '/bin/java'
INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : '/acivemq/apache-activemq-5.12.1//data/activemq.pid' (pid ' 4047')[/code]
查看ActiveMQ状态
[code="java"]# ./activemq status
INFO: Loading '/acivemq/apache-activemq-5.12.1//bin/env'
INFO: Using java '/bin/java'
ActiveMQ is running (pid '4047')
# [/code]
ActiveMQ相关进程8161控制台用户admin,密码admin(http://192.168.126.128:8161),
ActiveMq 监听端口61616
[code="java"]# netstat -ntlp | grep 4047
tcp6 0 0 :::5672 :::* LISTEN 4047/java
tcp6 0 0 :::61613 :::* LISTEN 4047/java
tcp6 0 0 :::61614 :::* LISTEN 4047/java
tcp6 0 0 :::61616 :::* LISTEN 4047/java
tcp6 0 0 :::42614 :::* LISTEN 4047/java
tcp6 0 0 :::1883 :::* LISTEN 4047/java
tcp6 0 0 :::8161 :::* LISTEN 4047/java [/code]
关闭ActiveMq,原ActiveMq配置,这个命令会报错
[code="java"]# ./activemq stop[/code]
修改conf/activemq.xml文件的如下配置即可:
  <!--   
The managementContext is used to configure how ActiveMQ is exposed in
JMX. By default, ActiveMQ uses the MBean server that is started by
the JVM. For more information, see:

http://activemq.apache.org/jmx.html
-->
<managementContext>
<managementContext createConnector="false"/>
</managementContext>

修改 [color=red]createConnector="true" [/color] 然后重新启动activemq,即可


需要引入的jar包如下:

[img]http://dl2.iteye.com/upload/attachment/0122/2119/63589b1f-99ae-3fd4-af93-260c204cac0c.png[/img]


PTP生产者

package mq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

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

/**
* Queue(点对点)方式 生存者Producer
* @author donald
*
*/
public class QueueProducer {
private static String user = ActiveMQConnection.DEFAULT_USER;
private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
private static String url = "tcp://192.168.126.128:61616";
private static String qname = "testQueue";

public static void main(String[] args)throws Exception {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
// Connection 启动
connection.start();
System.out.println("Connection is start...");
//创建一个session
//第一个参数:是否支持事务,如果为true,则会忽略第二个参数,被jms服务器设置为SESSION_TRANSACTED
//第二个参数为false时,paramB的值可为Session.AUTO_ACKNOWLEDGE,Session.CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE其中一个。
//Session.AUTO_ACKNOWLEDGE为自动确认,客户端发送和接收消息不需要做额外的工作。哪怕是接收端发生异常,也会被当作正常发送成功。
//Session.CLIENT_ACKNOWLEDGE为客户端确认。客户端接收到消息后,必须调用javax.jms.Message的acknowledge方法。jms服务器才会当作发送成功,并删除消息。
//DUPS_OK_ACKNOWLEDGE允许副本的确认模式。一旦接收方应用程序的方法调用从处理消息处返回,会话对象就会确认消息的接收;而且允许重复确认。

Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
// Queue :消息的目的地;消息发送给谁.
Queue destination = session.createQueue(qname);
// MessageProducer:消息发送者
MessageProducer producer = session.createProducer(destination);
//设置生产者的模式,有两种可选
//DeliveryMode.PERSISTENT 当activemq关闭的时候,队列数据将会被保存
//DeliveryMode.NON_PERSISTENT 当activemq关闭的时候,队列里面的数据将会被清空
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
// 构造消息,此处写死,项目就是参数,或者方法获取
sendMessage(session, producer);
session.commit();

connection.close();
System.out.println("send text ok.");
}

public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
for (int i = 1; i <= 5; i++) {//有限制,达到1000就不行
TextMessage message = session.createTextMessage("向ActiveMq发送的Queue消息" + i);
// 发送消息到目的地方
System.out.println("发送消息:" + "ActiveMq 发送的Queue消息" + i);
producer.send(message);
}
}
}

PTP消费者1:
package mq;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

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

/**
* Queue(点对点)方式 消费这Consumer
* @author donald
*
*/
public class QueueConsumer {
private static String user = ActiveMQConnection.DEFAULT_USER;
private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
private static String url = "tcp://192.168.126.128:61616";
private static String qname = "testQueue";
public static void main(String[] args) throws Exception{
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
connection.start();
// Session: 一个发送或接收消息的线程
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// Destination :消息的目的地;消息发送给谁.
Queue destination=session.createQueue(qname);
// 消费者,消息接收者
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener(){//有事务限制
@Override
public void onMessage(Message message) {
try {
TextMessage textMessage=(TextMessage)message;
System.out.println("消费消息:"+textMessage.getText());
} catch (JMSException e1) {
e1.printStackTrace();
}
try {
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
});

/* 另外一种接受方式
* while (true) {
//设置接收者接收消息的时间,为了便于测试,这里谁定为100s
TextMessage message = (TextMessage) consumer.receive(100000);
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}*/
}
}

PTP消费者2:


public class QueueConsumer2 {
.... 除了下面这一句,其他与QueueConsumer相同
System.out.println("2消费消息:"+textMessage.getText());
....
}


控制台输出

PTP生产者:
Connection is start...
发送消息:ActiveMq 发送的Queue消息1
发送消息:ActiveMq 发送的Queue消息2
发送消息:ActiveMq 发送的Queue消息3
发送消息:ActiveMq 发送的Queue消息4
发送消息:ActiveMq 发送的Queue消息5
send text ok.

PTP消费者1:

消费消息:向ActiveMq发送的Queue消息1
消费消息:向ActiveMq发送的Queue消息3
消费消息:向ActiveMq发送的Queue消息5

PTP消费者2:
2消费消息:向ActiveMq发送的Queue消息2
2消费消息:向ActiveMq发送的Queue消息4

从上面可以看出,Queue的消息,只要被消费者,消费一次


PUB/SUB生产者
package mq;

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

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

import mq.enity.Order;
import mq.enity.User;

/**
* Topic(发布/订阅)方式 发布者Publisher
* @author donald
*
*/
public class TopicPublisher {
private static String user = ActiveMQConnection.DEFAULT_USER;
private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
private static String url = "tcp://192.168.126.128:61616";
private static String tname = "testTopic";
public static void main(String[] args)throws Exception {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
// Connection 启动
connection.start();
System.out.println("Connection is start...");
// Session: 一个发送或接收消息的线程
Session session = connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
// Topicr :消息的目的地;消息发送给谁.
Topic destination = session.createTopic(tname);
// MessageProducer:消息发送者
MessageProducer producer = session.createProducer(destination);
// 设置持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
// 构造消息,此处写死,项目就是参数,或者方法获取
sendMessage(session, producer);
session.commit();

connection.close();
System.out.println("send Order ok.");
}
/**
*
* @param session
* @param producer
* @throws Exception
*/
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
Order order = new Order();
order.setId(1);
order.setAmount(150.62);
order.setGoodsId(15);
order.setGoodsAmount(2);
order.setShopId(5656);
//我们也可以将Object转换为Json String,作为TextMessage来传送,在消费再反Json String 为Obejct
ObjectMessage orderMess = session.createObjectMessage(order);
System.out.println("向ActiveMq:"+tname+"发送订单信息:" + "ActiveMq 发送的Topic消息");
producer.send(orderMess);
}

}

PUB/SUB 订阅者1
package mq;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

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

import mq.enity.Order;
import mq.enity.User;

/**
* Topic(发布/订阅)方式 订阅者TopicSubscriber
* @author donald
*
*/
public class TopicSubscriber {
private static String user = ActiveMQConnection.DEFAULT_USER;
private static String password =ActiveMQConnection.DEFAULT_PASSWORD;
private static String url = "tcp://192.168.126.128:61616";
private static String tname = "testTopic";
public static void main(String[] args) throws Exception{
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
connection.start();
// Session: 一个发送或接收消息的线程
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// Destination :消息的目的地;消息发送给谁.
Topic destination=session.createTopic(tname);
// 消费者,消息接收者
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener(){//有事务限制
@Override
public void onMessage(Message message) {
try {
ObjectMessage objMessage=(ObjectMessage)message;
Order order = (Order)objMessage.getObject();
System.out.println("消费订单信息:"+order.toString());

} catch (JMSException e1) {
e1.printStackTrace();
}
try {
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
});

/* 另外一种接受方式
* while (true) {
//设置接收者接收消息的时间,为了便于测试,这里谁定为100s
TextMessage message = (TextMessage) consumer.receive(100000);
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}*/
}
}


PUB/SUB 订阅者2

package mq;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

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

import mq.enity.Order;
import mq.enity.User;

/**
* Topic(发布/订阅)方式 订阅者TopicSubscriber
* @author donald
*
*/
public class TopicSubscriber2 {
...其他与TopicSubscriber相同
System.out.println("2消费订单信息:"+order.toString());
...

}


订单信息类:
package mq.enity;

import java.io.Serializable;

public class Order implements Serializable{

/**
*
*/
private static final long serialVersionUID = -343247274477730446L;
private Integer id;//订单id
private Double amount;
private Integer goodsId;//商品id
private Integer goodsAmount;//商品数量
private Integer shopId;//店铺名
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public Integer getGoodsId() {
return goodsId;
}
public void setGoodsId(Integer goodsId) {
this.goodsId = goodsId;
}
public Integer getGoodsAmount() {
return goodsAmount;
}
public void setGoodsAmount(Integer goodsAmount) {
this.goodsAmount = goodsAmount;
}
public Integer getShopId() {
return shopId;
}
public void setShopId(Integer shopId) {
this.shopId = shopId;
}
public String toString(){
return "订单id:"+this.id+","+"金额(元):"+this.amount+","+"商品id:"+
this.shopId+","+"商品数量:"+this.goodsAmount+","+"店铺id:"+this.shopId;
}

}


控制台输出:

PUB/SUB生产者:

Connection is start...
向ActiveMq:testTopic发送订单信息:ActiveMq 发送的Topic消息
send Order ok.


PUB/SUB 订阅者1:

消费订单信息:订单id:1,金额(元):150.62,商品id:5656,商品数量:2,店铺id:5656

PUB/SUB 订阅者2:
2消费订单信息:订单id:1,金额(元):150.62,商品id:5656,商品数量:2,店铺id:5656
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值