消息事务:
基本的事务 在一个JMS客户端,可以使用本地事务来组合消息的发送和接收。JMS Session接口提供了commit和rollback方法。事务提交意味着生产的所有消息被发送,消费的所有消息被确认;事务回滚意味着生产的所有消息被销毁,消费的所有消息被恢复并重新提交,除非它们已经过期。事务性的会话总是牵涉到事务处理中,commit或rollback方法一旦被调用,一个事务就结束了,而另一个事务被开始。关闭事务性会话将回滚其中的事务。 需要注意的是,如果使用请求/回复机制,即发送一个消息,同时希望在同一个事务中等待接收该消息的回复,那么程序将被挂起,因为直到事务提交,发送操作才会真正执行。需要注意的还有一个,消息的生产和消费不能包含在同一个事务中。
消息持久化:
所谓持久化就是将消息写入数据库或者文件中,在消息服务器宕机重启时可以将消息再读取回来,防止消息丢失
通信
activemq是jms一种消息服务器,可以实现消息的转发,一般有三种转发模式:发布订阅、点对点、应答
点对点:
点对点一般使用队列实现:
生产者:
public class Publisher {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("FirstQueue");
// 得到消息生成者【发送者】
MessageProducer producer = session.createProducer(destination);
// 设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("ActiveMq 发送的消息");
producer.send(message);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection) {
connection.close();
}
} catch (Throwable ignore) {
}
}
}
}
消费者:
public class Receiver {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("FirstQueue");
MessageConsumer consumer = session.createConsumer(destination);
// 异步接收消息
// consumer.setMessageListener(new MessageListener() {
// public void onMessage(Message paramMessage) {
// TextMessage message = (TextMessage) paramMessage;
// try {
// System.out.println("收到消息" + message.getText());
// } catch (JMSException e) {
// e.printStackTrace();
// }
// }
// });
// 同步接受消息,并设置超时时间
while (true) {
TextMessage message = (TextMessage) consumer.receive();
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
使用selector来区分消费者
selector 属性设置可以是字符串,也可以是整形,long,bollean,float,double等,通过类似以下方法设定
message.setStringProperty("receiver", "client2");//设置selector 属性
生产者
public class Publisher {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("FirstQueue");
// 得到消息生成者【发送者】
MessageProducer producer = session.createProducer(destination);
// 设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("ActiveMq 发送的消息");
message.setStringProperty("receiver", "client2");//设置selector 属性
producer.send(message);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection) {
connection.close();
}
} catch (Throwable ignore) {
}
}
}
}
消费者
public class Receiver {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("FirstQueue");
MessageConsumer consumer = session.createConsumer(destination,"receiver='client1'");//设置selector属性,因为是字符串,所以加单引号
// 同步接受消息,并设置超时时间
while (true) {
TextMessage message = (TextMessage) consumer.receive();
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
发布订阅
发布订阅一般使用topic实现:
生产者:
public class Publisher {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createTopic("FirstTopic");
// 得到消息生成者【发送者】
MessageProducer producer = session.createProducer(destination);
// 设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
TextMessage message = session.createTextMessage("ActiveMq 发送的消息");
producer.send(message);
session.commit();
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection) {
connection.close();
}
} catch (Throwable ignore) {
}
}
}
}
消费者:
public class Receiver {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
Destination destination = session.createTopic("FirstTopic");
MessageConsumer consumer = session.createConsumer(destination);
// 异步接收消息
// consumer.setMessageListener(new MessageListener() {
// public void onMessage(Message paramMessage) {
// TextMessage message = (TextMessage) paramMessage;
// try {
// System.out.println("收到消息" + message.getText());
// } catch (JMSException e) {
// e.printStackTrace();
// }
// }
// });
// 同步接受消息,并设置超时时间
while (true) {
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 != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
应答:
应答其实是两次点对点通信,不过第二次是通过临时队列完成,还是使用队列实现:
生产者:
public class Publisher {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
// 构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("FirstQueue");
// 得到消息生成者【发送者】
MessageProducer producer = session.createProducer(destination);
// 设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 为响应创建临时队列
Destination tempDest = session.createTemporaryQueue();
TextMessage request = session.createTextMessage("ActiveMq 发送的消息_请求");
request.setJMSReplyTo(tempDest);
// 为响应创建消息关联id 此id用来区分同一个生产者的不同消息,因为多线程情况下发送不同消息而返回通道时同一个临时队列的话有可能将结果弄错,所以需要correlationId来区分
String correlationId = "123658974";
request.setJMSCorrelationID(correlationId);
producer.send(request);
session.commit();
// 以临时队列创建一个接收消息的MessageConsumer
MessageConsumer responseConsumer = session.createConsumer(tempDest);
TextMessage response = (TextMessage) responseConsumer.receive();
System.out.println(response.getText());
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection) {
connection.close();
}
} catch (Throwable ignore) {
}
}
}
}
消费者:
public class Receiver {
// Connection :JMS 客户端到JMS Provider 的连接
private static Connection connection = null;
static {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD, "tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
} catch (JMSException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
// 获取操作连接
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
Destination destination = session.createQueue("FirstQueue");
MessageConsumer consumer = session.createConsumer(destination);
// 同步接受消息,并设置超时时间
TextMessage message = (TextMessage) consumer.receive();
System.out.println(message.getText());
// 创建返回消息
TextMessage response = session.createTextMessage("ActiveMq 发送的消息_响应");
// 设置消息关联id
response.setJMSCorrelationID(message.getJMSCorrelationID());
// 以返回的地点创建一个MessageProducer
MessageProducer replyProducer = session.createProducer(message.getJMSReplyTo());
replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
replyProducer.send(response);
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}