ActiveMq NON_PERSISTENT与PERSISTENT以及 durable subscription(持久订阅)的理解

标签: activemq non persistent | 发表时间:2014-09-04 19:29 | 作者:quentinXXZ
出处:http://www.iteye.com

 

http://quentinXXZ.iteye.com/blog/2113458

 

实验一:

public class Producer {
	public static void main(String[] args) {
	    String user = ActiveMQConnection.DEFAULT_USER;
	    String password = ActiveMQConnection.DEFAULT_PASSWORD;
	    String url = ActiveMQConnection.DEFAULT_BROKER_URL;
	    String subject = "TOOL.DEFAULT";
	    System.out.println(user +" "+ password+" "+url+" "+subject+" ");
	    
		ConnectionFactory contectionFactory = new ActiveMQConnectionFactory(user,password,url);
		try {
			Connection connection = contectionFactory.createConnection();
			connection.start();
			Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			Destination destination = session.createQueue(subject);
			MessageProducer producer = session.createProducer(destination);
			for(int i = 0;i<=20;i++){
				MapMessage message = session.createMapMessage();
				message.setLong("date", new Date().getTime());
				Thread.sleep(5000);
				producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
				producer.send(message);
				
				System.out.println("—SendMessge:"+new Date());
			}
			session.commit();
			session.close();
			connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 注意:producer.setDeliveryMode(DeliveryMode. NON_PERSISTENT);

 此处显式指明DeliveryMode为NON_PERSISENT

 

public class Consumer {

	public static void main(String[] args) {
		String user = ActiveMQConnection.DEFAULT_USER;
	    String password = ActiveMQConnection.DEFAULT_PASSWORD;
	    String url = ActiveMQConnection.DEFAULT_BROKER_URL;
	    String subject = "TOOL.DEFAULT";
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user,password,url);
		Connection connection;
		try {
			connection = connectionFactory.createConnection();
			connection.start();
			final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			Destination destination = session.createQueue(subject);
			MessageConsumer message = session.createConsumer(destination);
			message.setMessageListener(new MessageListener(){

				public void onMessage(Message msg) {
					MapMessage message = (MapMessage)msg;
					try {
						System.out.println("--Receive:"+new Date(message.getLong("date")));
						session.commit();
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
			});
			Thread.sleep(30000);
			session.close();
			connection.close();
		} catch (JMSException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

}

 ActiveMq Broker的配置都为默认。

先启动Broker,再启动Producer,等待Producer的20条Message发送完毕,Prducer程序运行结束,之后再启动Consumer,20条Message正常接收。

可见PERSISTENT与NON_PERSISTENT,并不是指Broker会不会在Consumer未连接的情况为其存储Message

 

实验二:

先启动Broker,再启动Producer,等待Producer的20条Message发送完毕,Prducer程序运行结束。关闭ActiveMq  Broker服务,然后重启。之后再启动Consumer。

Consumer没有接收到任何消息。

 

实验三:

producer.setDeliveryMode(DeliveryMode. PERSISTENT);

在Producer中显式指明DeliveryMode为PERSISENT

实验步骤与实验二相同,但是此次Consumer收到了来自Producer的消息。

 

 

总结:

Persistent 用来指定JMS Provider对消息进行持久化操作,以免Provider fail的时候,丢失Message.

NON_Persistent 方式下的JMS Provider不会对消进宪持久化,但上述实验一可知,Consumer还是会收到Message,可见JMS Provider会将相应的消息存在内存中,当Consumer连接上时,再发送过去,但在Provider fail的时候,Message会丢失。

事实上ActiveMq提供了多种消息持久化方式,包括AMQ、KahaDB、JDBC、LevelDB。从5.4版本之后KahaDB做为默认的持久化方式。

 

 

以下网上摘的:

 

消息订阅分为非持久订阅(non-durable subscription)和持久订阅(durablesubscription),非持久订阅只有当客户端处于激活状态,也就是和JMS Provider保持连接状态才能收到发送到某个主题的消息,而当客户端处于离线状态,这个时间段发到主题的消息将会丢失,永远不会收到。持久订阅时,客户端向JMS注册一个识别自己身份的ID,当这个客户端处于离线时,JMS Provider 会为这个ID 保存所有发送到主题的消息,当客户再次连接到JMS Provider时,会根据自己的ID得到所有当自己处于离线时发送到主题的消息。

Topic 主题由JMS Provider 管理,主题由主题名识别,客户端可以通过JNDI接口用主题名得到一个主题对象。

 

 

消息发送端

消息接收端

可靠性及因素

PERSISTENT

queue receiver/durable subscriber

消费一次且仅消费一次。可靠性最好,但是占用服务器资源比较多。

PERSISTENT

non-durable subscriber

最多消费一次。这是由于non-durable subscriber决定的,如果消费端宕机或其他问题导致与JMS服务器断开连接,等下次再联上JMS服务器时的一系列消息,不为之保留。

NON_PERSISTENT

queue receiver/durable subscriber

最多消费一次。这是由于服务器的宕机会造成消息丢失

NON_PERSISTENT

non-durable subscriber

最多消费一次。这是由于服务器的宕机造成消息丢失,也可能是由于non-durable subscriber的性质所决定

 

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [activemq non persistent] 推荐:

ActiveMq NON_PERSISTENT与PERSISTENT以及 durable subscription(持久订阅)的理解

- - 开源软件 - ITeye博客
 注意:producer.setDeliveryMode(DeliveryMode.  此处显式指明DeliveryMode为NON_PERSISENT.  ActiveMq Broker的配置都为默认. 先启动Broker,再启动Producer,等待Producer的20条Message发送完毕,Prducer程序运行结束,之后再启动Consumer,20条Message正常接收.

【ActiveMQ Tuning】Prefetch Limit

- - 博客园_首页
   摘要:ActiveMQ优化 客户端优化 预取限制. 原文: http://fusesource.com/docs/broker/5.4/tuning/GenTuning-Consumer-Prefetch.html. Overview:图列4.1阐明了Broker在等待之前发送给客户端消息的反馈的行为.

【ActiveMQ Tuning】Serializing to Disk

- - 博客园_首页
     翻译自: http://fusesource.com/docs/broker/5.4/tuning/PersTuning-SerialToDisk.html.      KahaDB message store:KahaDB 是ActiveMQ Broker 为了高性能而推荐使用的消息存储机制.

ActiveMQ 桥接

- - CSDN博客互联网推荐文章
使用目的:将本地产生的消息转发到远程,通过远程服务器来处理消息,处理完成后,再启动消费者处理本地服务器消息(验证消息是否被转走,本地无消息可处理为正常). 消息在下面的地址被消费,无需任何特别配置,采用默认的配置即可. 生产消息地址为localhost:7001,需要做如下配置. 注意: 表示只有这个队列的会进行桥接转发.

ActiveMQ学习小结

- - CSDN博客架构设计推荐文章
   Activemq是众多开源消息中间件的一种,支持集群,同等网络,自动检测,TCP,SSL,广播,持久化,和J2EE1.4容器无缝结合. 它是apache基金会的一个项目,而且经过多年发展,有了很高的稳定性. 目前被很多知名项目使用,比如Apache serviceMix、FuseESB.  消息中间件一般被用在异步消息通信、整合多个系统的场景,比如你注册CSDN论坛,你填写完注册信息点提交时,它会发一份验证邮箱的验证邮件给到你,这封邮件就可以通过消息中间异步发送给你.

ActiveMQ与Spring整合

- - 博客园_首页
ActiveMQ 是Apache出品, 是最流行​​和最强大的开源消息总线. 同时完全支持 JMS 1.1和J2EE 1.4规范. 支持多种编程语言和协议编写客户端. 在JMS客户端和消息代理完全支持企业集成模式. 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务). 对Spring的支持, ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性.

ActiveMQ高级特性

- - zzm
消息生产者使用持久(persistent)传递模式发送消息的时候,Producer.send() 方法会被阻塞,直到 broker 发送一个确认消息给生产者,这个确认消息暗示生产者 broker 已经成功地将它发送的消息路由到目标目的并把消息保存到二级存储中. 但有一个例外,当发送方法在一个事物上下文中时,被阻塞的是commit 方法而不是 send 方法.

Non-blocking JavaScript 的問題 - IE 的 window.onload 事件

- Kejun - 這樣做就對了!
很讚的 Non-blocking JavaScript. 前陣子將網站的所有 JavaScript 採用 Non-blocking 的方式做載入,整個介面 rendering 的時間減少很多,是我們想要的效果:. 但是今天在 IE 發現了一個蠻嚴重的問題:「假設用 Non-blocking 的方式在 head 載入某 JavaScript ,而此 JavaScript 有指定 window 的 load 的事件處理函式,會發現它常常沒有被觸發.

Jmeter以non-gui模式进行分布式测试 - qianyiliushang

- - 博客园_首页
由于Jmeter是一个纯JAVA的应用,用GUI模式运行压力测试时,对客户端的资源消耗是相当惊人的,所以在进行正式的压测时一定要使用non-gui模式运行,如果并发数很高或者客户端的硬件资源比较一般的话,还可以以server模式用多个client进行分布式测试. 一直有朋友问我这个分布式测试要怎么用,我就结合官方文档和自己的实际经验来谈一谈.

ActiveMQ持久化方式

- - CSDN博客架构设计推荐文章
消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重新启动后仍然可以将消息发送出去,如果把这种持久化和ReliableMessaging结合起来应该是很好的保证了消息的可靠传送. 消息持久性的原理很简单,就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件、内存数据库或者远程数据库等,然后试图将消息发送给接收者,发送成功则将消息从存储中删除,失败则继续尝试.