ActiveMQ订阅模式持久化实现

我的诉求是,建一个订阅通道,然后多个客户端监听,当某个客户端掉线后,再上线的时候可以收到它没有接收到的消息。


本文主要参考了《使用Spring配置ActiveMQ的发布订阅模式》(http://nettm.iteye.com/blog/1828268),将他们复制粘贴过来,基本上就ok了。
在找到这篇文章前,《如何实现ActiveMq的Topic的持久订阅》(http://www.mytju.com/classcode/news_readNews.asp?newsID=486)给了我提示。要设置clientID啊~


我根据参考的文章编写了工程,测试后发现是ok的。并且发现了一个细节。
比如,有一个clientID=ID_1,有个通道是topic_channel。往topic_channel中发送一批消息(A批)后,首次启动ID_1的监听,ID_1没有收到。关掉ID_1的监听,再往topic_channel中发送一批消息(B批)后,再次启动ID_1的监听,收到了B批消息。这个现象说明了什么呢?说明你不仅要有自己唯一的ID(clientID)还要事先跟这个通道报告一声,说你要监听它,订阅的消息来了之后给它留一份,等着它来拿。在你报告之前产生的消息,你是拿不到的,因为没有你的份。


为了体现我真的动了脑筋,思考了。所以我发表的工程,是做了一些修改的,比如,通道名啊,ID名啊,文件名啊,还调整了一下文件结构,哈哈哈~
当然我还做了一个质的突破,我在一个工程里面做了两个接收者,监听同一个订阅通道。


实现步骤:
1、配置发送xml,applicationContext-send.xml
  
  
  
  
  
      
      
          
          
          
              
                  
                  
                   
                  
              
          
      
  
      
      
          
          
      
  
      
      
          
          
          
          
          
      
 


2、编写发送java,ActiveMQsender.java

package com.by.activeMQ;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class ActiveMQsender {
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"ApplicationContext/applicationContext-send.xml");

		JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");

		jmsTemplate.send(new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				TextMessage msg = session.createTextMessage();
				// 设置消息属性
				msg.setStringProperty("mood", "happy");
				// 设置消息内容
				msg.setText("Hello World!");
				return msg;
			}
		});

		System.out.println("send end");
	}
}


3、配置接收xml,applicationContext-receive.xml
  
  
  
  
  
  
      
      
          
          
          
          
          
              
                  
                  
              
          
      
  
      
      
          
          
      
  
      
      
  
      
      
          
          
          
          
          
      
  
      
      
          
          
          
          
          
          
          
          
          
          
          
      
    
      
  
  
           
      
          
          
          
          
          
              
                  
                  
              
          
      
  
      
      
          
          
      
  
      
      
  
      
      
          
          
          
          
          
      
  
      
      
          
          
          
          
          
          
          
          
          
          
          
     
  
  


4、编写接收java,ActiveMQreceiver.java
package com.by.activeMQ;

import javax.jms.JMSException;
import javax.jms.TextMessage;

import org.springframework.jms.JmsException;

public class ActiveMQreceiver {
	public void receive(TextMessage message) throws JmsException, JMSException { 
		String info = "this is receiver, "
				+ " mood is " + message.getStringProperty("mood") + ","
				+ "say " + message.getText();
        System.out.println(info);
    } 
}



5、编写另一个接收java,ActiveMQreceiver.java
package com.by.activeMQ;

import javax.jms.JMSException;
import javax.jms.TextMessage;

import org.springframework.jms.JmsException;

public class ActiveMQreceiver2 {
	public void receive(TextMessage message) throws JmsException, JMSException { 
		String info = "this is receiver2,"
				+ " mood is " + message.getStringProperty("mood") + ","
				+ "say " + message.getText();
        System.out.println(info);
    } 
}



6、编写一个main,开启接收监听,openReceive.java
package com.by.activeMQ;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class openReceive {

	public static void main(String[] args) {
		@SuppressWarnings({ "unused", "resource" })
		ApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext/applicationContext-receive.xml");  
        while(true) {  
        } 
	}

}



7、编写一个配置文件,jms.properties

#send
send.name=Topic_Mood

#receive
topic.name=Topic_Mood
topic.clientId=client_LiLei

topic2.name=Topic_Mood
topic2.clientId=client_HanMei

#url
brokerUrl=failover:(tcp://10.0.0.232:61616)?initialReconnectDelay=1000

8、pom里面添加activeMQ的依赖


	org.apache.activemq
	activemq-pool
	5.11.1


	org.apache.commons
	commons-pool2
	2.3


	org.springframework
	spring-jms
	4.0.0.RELEASE



	org.apache.activemq
	activemq-all
	5.11.1



耶,运行就ok了。
发送消息的输出是这样的:
2016-08-05 11:27:19 [ main:0 ] - [ INFO ] Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@16011db4: startup date [Fri Aug 05 11:27:19 CST 2016]; root of context hierarchy
2016-08-05 11:27:19 [ main:31 ] - [ INFO ] Loading XML bean definitions from class path resource [ApplicationContext/applicationContext-send.xml]
2016-08-05 11:27:19 [ main:187 ] - [ INFO ] Loading properties file from class path resource [properties/jms.properties]
2016-08-05 11:27:19 [ main:392 ] - [ INFO ] Established shared JMS Connection: ActiveMQConnection {id=ID:MDG42V9PSU28IKA-60542-1470367639797-1:1,clientId=null,started=false}
2016-08-05 11:27:19 [ ActiveMQ Task-1:467 ] - [ INFO ] Successfully connected to tcp://10.0.0.232:61616
send end


接收消息的输出是这样的:
2016-08-05 11:28:04 [ ActiveMQ Task-1:490 ] - [ INFO ] Successfully connected to tcp://10.0.0.232:61616
2016-08-05 11:28:04 [ main:498 ] - [ INFO ] Established shared JMS Connection: ActiveMQConnection {id=ID:MDG42V9PSU28IKA-60544-1470367684739-1:1,clientId=client_LiLei,started=false}
2016-08-05 11:28:04 [ ActiveMQ Task-1:504 ] - [ INFO ] Successfully connected to tcp://10.0.0.232:61616
2016-08-05 11:28:04 [ main:509 ] - [ INFO ] Established shared JMS Connection: ActiveMQConnection {id=ID:MDG42V9PSU28IKA-60544-1470367684739-3:1,clientId=client_HanMei,started=false}
this is receiver2, mood is happy,say Hello World!
this is receiver,  mood is happy,say Hello World!


啦啦啦,不知道大家注意了没有,配置另一个接收者就是,把第一个接收者的配置复制,然后添加个2,再把接收类复制,添加个2,就搞定了。哈哈哈~这种方式也适用于mongodb啊这种配置。在一个工程里面操作两个mongodb数据库。


注:我将代码上传到了csdn。



你可能感兴趣的:(java)