JMS+activeMq+spring简单学习及模拟处理新闻日志场景

       在介绍JMS的知识之前,先说说我了解学习JMS的原因。

       公司有一个新闻项目,我们知道新闻网站都是面向所有用户群的,它不但要求新闻的实时性,还要求网页的响应时间必须很快,

你想啊,如果你在某个网站看新闻,如果网页响应比较慢,那谁愿意来你网站看新闻啊,所以新闻网站的网页都进行静态化、新闻

页所需数据都放在缓存系统(比如memcache之类)等等一些处理,也就是说用户请求访问某个页面时,服务器要尽可能快响应,这就

要求我们后台,不能像一些企业应用系统(比如人事管理系统之类)那样,每个请求所需的数据都从数据库查询,并且不止查询

一次。因为这些应用系统都是有特定的使用人群的,并发量不大,所以哪怕不停查询数据库,响应也够快,用户也能接受。新闻

这项目,现在有个需求,需要收集记录用户的访问日志,比如用户访问了哪些新闻频道列表,访问了哪些新闻详情等等,为统计

系统提供数据。这样问题来了,网页请求,连数据库查询都尽量避免,更别说执行日志写操作,要知道往数据库里面插数据,如

果表的数据量很大了,并且又有索引,那插入一条新数据所需的时间就很大的,如果并发量高时,还有可能阻塞,这就严重影响

网页请求的响应速度了。有些小伙伴就说了,那我新启动一个线程单独对日志写不就行了吗?对,这是一种方法,但是我们要注

意,如果请求非常多,那新创建的线程就会非常多,会严重影响服务器的性能的。看了下

项目代码,项目中采用的是利用JMS来做。


            一看上面的图,这不是生产者和消费者模式吗?是的,没错。看上面图,可以看出,新闻应用服务器、mq服务器、日志处理

服务器都是分开的,新闻应用服务器只需要把日志数据发送到mq服务器就行了,至于日志数据是怎样处理的,插入数据库的速度

如何,是否成功等,新闻应用服务器不必关心,这样一来就能尽可能快的提高用户的请求响应了。

        好了,接下来,我们学习了解一下关于JMS的一些基础知识。

下载安装运行activeMq

        网络上下载一个activeMq,然后运行它


可以看到,默认的连接地址和端口是tcp://127.0.0.1:61616,同时还可以通过浏览器访问http://localhost:8161/来查看activeMq里

面队列等一些基础数据信息。现在浏览器打开http://localhost:8161/



  我们选择Queue Views下的XML来看下


可以看到你队列名称,以及一些状态数据


 JMS基本概念

JMS(Java Message Service) 即Java消息服务。它提供标准的产生、发送、接收消息的接口简化企业应用的开发。它支持两种消息通信模型:

点到点(point-to-point)(P2P)模型和发布/订阅(Pub/Sub)模型。P2P 模型规定了一个消息只能有一个接收者;Pub/Sub 模型允许一个

消息可以有多个接收者。
    对于点到点模型,消息生产者产生一个消息后,把这个消息发送到一个Queue(队列)中,然后消息接收者再从这个Queue中读取,一旦

这个消息被一个接收者读取之后,它就在这个Queue中消失了,所以一个消息只能被一个接收者消费。
    与点到点模型不同,发布/订阅模型中,消息生产者产生一个消息后,把这个消息发送到一个Topic中,这个Topic可以同时有多个接收者

在监听,当一个消息到达这个Topic之后,所有消息接收者都会收到这个消息。

简单的讲,点到点模型和发布/订阅模型的区别就是前者是一对一,后者是一对多。

Queue的简单例子1

      现在我们来看个简单例子,用来模拟上面的新闻应用服务器、activeMq、日志处理服务器这三方过程.首先启

动activeMq服务,然后创建一个项目jms_produce用来生产数据,jms_consumer用来消费数据



    其中jms_produce的MessageSend.java的代码如下

package com.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class MessageSend {
    public static void main(String[] args) throws Exception {
    	//创建连接工厂
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //获取连接对象
        Connection connection = factory.createConnection();
        //开始连接
        connection.start();
       //创建队列,并且队列名称取名为"testQueue"
        Queue queue = new ActiveMQQueue("testQueue");
       //创建回话,具体的参数就不详细介绍说明了,可以看API
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建消息生产者
        MessageProducer producer = session.createProducer(queue);
       //向activeMq服务器发送7个数据,都位于队列testQueue中
        for(int i=0;i<7;i++){
        	 Message message = session.createTextMessage("Hello JMS "+i);//如果是对象传送,可用createObjectMessage(...)
             producer.send(message);
        }
        //关闭链接
        connection.close();
    }
}

    jms_consumer中的MessageRecieve.java代码如下

package com.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class MessageReceive {
    public static void main(String[] args) throws Exception {
    	//创建连接工厂
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //获取连接对象
        Connection connection = factory.createConnection();
        //开始连接
        connection.start();
       
      //创建队列,并且队列名称取名为"testQueue"
        Queue queue = new ActiveMQQueue("testQueue");
       //创建回话,具体的参数就不详细介绍说明了,可以看API
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
       //创建消息消费者,这个消费只能消费testQueue队列中的数据
        MessageConsumer comsumer = session.createConsumer(queue);
        while(true){
        	Message recvMessage = comsumer.receive();//这里会进行阻塞
        	System.out.println(((TextMessage)recvMessage).getText());
        }
    }
}

      可以看到生产者往队列testQueue中生产了7个数据。现在我们运行jms_produce,消费项目jms_consumer暂时不要启动,因为我们要看看,生产者往activeMq中发数

据时,testQueue的状态数据,然后启动jms_consumer消费这消费后,activeMq中的testQueue的状况。好了,现在我们运行jms_produce,然后浏览器中看到,

下面信息(不记得怎么用浏览器看activeMq中的信息的,请回头看看上面)


然后,我们再运行jms_consumer项目,把队列testQueue中的数据给消费掉

控制台



  

   size有多少个生产者正在生产,应为上面jms_produce生产了7个数据后,它就直接关闭了,所以

这里看到size=0,consumerCount表示正在有多少个消费者在连接这个队列,看上面代码我们知道jms_consumer

一直在等待,一直在连接activeMq,所以consumerCount=1,enqueueCount表示队列中有多少个数据,

dequueueCount表示有多少个数据被消费过。


Queue的简单例子2

消息的消费者接收消息可以采用两种方式:

  1、consumer.receive() 或 consumer.receive(int timeout);
  2、注册一个MessageListener。

  采用第一种方式,消息的接收者会一直等待下去,直到有消息到达,或者超时。后一种方式会注册一个监听器,当有消息到达的时候,

会回调它的onMessage()方法。下面举例说明:

    我们把上面的jms_consumer总的MessageRecive.java稍微修改下

package com.test;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class MessageSend {
    public static void main(String[] args) throws Exception {
    	//创建连接工厂
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //获取连接对象
        Connection connection = factory.createConnection();
        //开始连接
        connection.start();
       //创建队列,并且队列名称取名为"testQueue"
        Queue queue = new ActiveMQQueue("testQueue");
       //创建回话,具体的参数就不详细介绍说明了,可以看API
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        //创建消息生产者
        MessageProducer producer = session.createProducer(queue);
       //向activeMq服务器发送7个数据,都位于队列testQueue中
        for(int i=0;i<7;i++){
        	 Message message = session.createTextMessage("Hello JMS "+i);//如果是对象传送,可用createObjectMessage(...)
             producer.send(message);
        }
        //关闭链接
        connection.close();
    }
}

能达到同样的效果。

上面都是一个生产者,一个消费者,下面我们来看看一个生产者,多个消费者,消费结果是怎样的。

对jms_consumer中的MessageRecive.java修改下

package com.test;
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.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
public class MessageReceive {
    public static void main(String[] args) throws Exception {
    	//创建连接工厂
        ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        //获取连接对象
        Connection connection = factory.createConnection();
        //开始连接
        connection.start();
       
      //创建队列,并且队列名称取名为"testQueue"
        Queue queue = new ActiveMQQueue("testQueue");
       //创建回话,具体的参数就不详细介绍说明了,可以看API
        final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
       //创建消息消费者,这个消费只能消费testQueue队列中的数据
       //消费者1
        MessageConsumer comsumer1 = session.createConsumer(queue);
        //注册消费监听器
        comsumer1.setMessageListener(new MessageListener(){
                   @Override
                   public void onMessage(Message m) {
                       TextMessage textMsg = (TextMessage) m;
                       try {
                           System.out.println("消费者1"+textMsg.getText());
                       } catch (JMSException e) {
                           e.printStackTrace();
                       }
                   }
                  
               });
        
      //消费者2
        MessageConsumer comsumer2 = session.createConsumer(queue);
        //注册消费监听器
        comsumer2.setMessageListener(new MessageListener(){
                   @Override
                   public void onMessage(Message m) {
                       TextMessage textMsg = (TextMessage) m;
                       try {
                           System.out.println("消费者2:"+textMsg.getText());
                       } catch (JMSException e) {
                           e.printStackTrace();
                       }
                   }
                  
               });
    }
}

 先启动消费者jms_consumer,然后再启动生产者,可以看到消费者的打印结果


  发现,一个数据只能被消费一次,并且无法确定哪个数据被哪个消费者消费。


Topic的简单例子

    与Queue不同的是,Topic实现的是发布/订阅模型,也就是一个数据可以被多个消费者消费。

       将上面生产者和消费者中代码的

Queue queue = new ActiveMQQueue("testQueue");

修改为

Topic topic= new ActiveMQTopic("testTopic"); 

先启动消费者,再执行生产者,看到打印结果如下 ,每个数据都被所有消费者消费


JMS的一些深入知识

 一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload)。对于StreamMessage和MapMessage,

消息本身就有特定的结构,而对于TextMessage,ObjectMessage和BytesMessage是无结构的。一个消息可以包含一

些重要的数据或者仅仅是一个事件的通知。

    消息的Headers部分通常包含一些消息的描述信息,它们都是标准的描述信息。包含下面一些值:

  JMSDestination 
       消息的目的地,Topic或者是Queue。

  JMSDeliveryMode 
        消息的发送模式:persistent或nonpersistent。前者表示消息在被消费之前,如果JMS提供者DOWN了,重新启动后消

息仍然存在。后者在这种情况下表示消息会被丢失。可以通过下面的方式设置:
       Producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

       JMSTimestamp 
       当调用send()方法的时候,JMSTimestamp会被自动设置为当前事件。可以通过下面方式得到这个值:
       long timestamp = message.getJMSTimestamp();

  JMSExpiration 
       表示一个消息的有效期。只有在这个有效期内,消息消费者才可以消费这个消息。默认值为0,表示消息永不过期。

可以通过下面的方式设置:
       producer.setTimeToLive(3600000); //有效期1小时 (1000毫秒 * 60秒 * 60分)

  JMSPriority 
       消息的优先级。0-4为正常的优先级,5-9为高优先级。可以通过下面方式设置:
       producer.setPriority(9);

  JMSMessageID 
       一个字符串用来唯一标示一个消息。

  JMSReplyTo 
       有时消息生产者希望消费者回复一个消息,JMSReplyTo为一个Destination,表示需要回复的目的地。当然消费者可以不理会它。

  JMSCorrelationID 
       通常用来关联多个Message。例如需要回复一个消息,可以把JMSCorrelationID设置为所收到的消息的JMSMessageID。

  JMSType 
       表示消息体的结构,和JMS提供者有关。

  JMSRedelivered 
       如果这个值为true,表示消息是被重新发送了。因为有时消费者没有确认他已经收到消息或者JMS

提供者不确定消费者是否已经收到。

    除了Header,消息发送者可以添加一些属性(Properties)。这些属性可以是应用自定义的属性,JMS定义的属性

和JMS提供者定义的属性。我们通常只适用自定义的属性。

JMS+ActiveMq+Spring整合模拟处理新闻日志场景

     新建项目jms_spring_produce模拟新闻项目,项目jms_spring_consumer模拟日志处理项目,

为了便捷,项目都是用maven结构搭建的。

下面会贴部分源码,完整的项目请下载


生产者和消费者之间的数据交互,采用了自定义的类。由于生产者和消费者位于两个独立

的项目中,所以这些日志对象(如截图上的LoginLogDto.java/NewsVisitLogDto.java)都必

须序列号,并且生产者和消费之间这些对象都必须一模一样。如果觉得麻烦,那可以通过

json来进行交互,或者将这些日志对象抽出来作为一个独立的jar项目,maven管理很方便的。


由于代码较多,又有配置之类的,这里就不一一全部贴出来了,就贴部分.

LoginLogDto.java

package com.fei.dto;

import java.io.Serializable;
import java.util.Date;
/**
 * 模拟用户登录日志
 * @author weijianfei
 *
 */
public class LoginLogDto implements Serializable{

	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private String userName;
	private Date loginTime;
	private String ip;
	
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public Date getLoginTime() {
		return loginTime;
	}
	public void setLoginTime(Date loginTime) {
		this.loginTime = loginTime;
	}
	public String getIp() {
		return ip;
	}
	public void setIp(String ip) {
		this.ip = ip;
	}
	
}

UserLoginLogProducer.java

package com.fei.service.jmsproducer;

import java.util.List;




import javax.jms.Destination;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

import com.fei.dto.LoginLogDto;

@Service
public class UserLoginLogProducer {
	private static Logger logger = LoggerFactory.getLogger(UserLoginLogProducer.class);
	/**
	 * JMS模板
	 */
	@Autowired
	private JmsTemplate jmsTemplate;
	/**
	 * 用户行为队列
	 */
	@Autowired
	@Qualifier("userLoginQueue")
	private Destination userLoginQueue;

	
	public void sendMessage(LoginLogDto loginLog) {
		try{
			jmsTemplate.convertAndSend(this.userLoginQueue, loginLog);
		}catch(Exception e){
			logger.error("发送用户登录记录消息出错:"+loginLog,e);
		}
	}

	public void setJmsTemplate(JmsTemplate jmsTemplate) {
		this.jmsTemplate = jmsTemplate;
	}
	public void setNotifyQueue(Destination notifyQueue) {
		this.userLoginQueue = notifyQueue;
	}
}

LogSenderServiceImpl.java

package com.fei.service.log;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import com.fei.dto.LoginLogDto;
import com.fei.dto.NewsVisitLogDto;
import com.fei.service.jmsproducer.NewsVisitLogProducer;
import com.fei.service.jmsproducer.UserLoginLogProducer;

@Service
public class LogSenderServiceImpl implements LogSenderService{

	@Autowired
	private UserLoginLogProducer userLoginLogProducer;
	
	@Autowired
	private NewsVisitLogProducer newsVisitLogProducer;
	
	public void send(LoginLogDto loginLogDto) {
		userLoginLogProducer.sendMessage(loginLogDto);
	}

	public void send(NewsVisitLogDto newsVisitLogDto) {
		newsVisitLogProducer.sendMessage(newsVisitLogDto);
	}

}

生产者项目中的测试例子

TestUserLoginLogProducer.java

package com.fei.service.jmsproducer;

import java.util.Date;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.fei.dto.LoginLogDto;
import com.fei.dto.NewsVisitLogDto;
import com.fei.service.log.LogSenderService;

public class TestUserLoginLogProducer {

	private ClassPathXmlApplicationContext context ;
	
	@Before
	public void before(){
		context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
		context.start();
	}
	@After
	public void after(){
		context.stop();
	}
	@Test
	public void testSendMessage(){
		LoginLogDto u1 = new LoginLogDto();
		u1.setUserName("tom06");
		u1.setIp("192.168.6.95");
		u1.setLoginTime(new Date());
		
		LoginLogDto u2 = new LoginLogDto();
		u2.setUserName("jack06");
		u2.setIp("192.168.6.98");
		u2.setLoginTime(new Date());
		
		LogSenderService service = (LogSenderService)context.getBean("logSenderServiceImpl");
		service.send(u1);
		service.send(u2);
	}
	@Test
	public void testSendMessage2(){
		NewsVisitLogDto d1 = new NewsVisitLogDto();
		d1.setIp("192.168.22.33");
		d1.setNewsId("112244");
		d1.setVisitDate(new Date());
		
		LogSenderService service = (LogSenderService)context.getBean("logSenderServiceImpl");
		service.send(d1);
	}
}

执行testSendMessage(),这样就把数据发送到ActiveMq了。

再来看看消费者的监听类

UserLoginLogListener.java

package com.fei.jmsconsumer;

import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.fei.dto.LoginLogDto;

@Service
public class UserLoginLogListener  implements MessageListener{

	private static Logger logger = LoggerFactory.getLogger(UserLoginLogListener.class);
	
	public void onMessage(Message message) {
		try {
			ObjectMessage objectMessage = ((ObjectMessage) message);
			LoginLogDto loginLogDto = (LoginLogDto)objectMessage.getObject();
			//调用其它service进行数据处理,这里直接打印下
			logger.info("用户登录:"+loginLogDto.getUserName() +"   "+loginLogDto.getIp()+"   "+loginLogDto.getLoginTime());
			System.out.println("用户登录:"+loginLogDto.getUserName() +"   "+loginLogDto.getIp()+"   "+loginLogDto.getLoginTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}

}

把jms_spring_consumer部署到tomcat,启动,就可以看到打印日志了


注意事项,必须要有日志配置,比如logback.xml,同时web.xml中必须配有listener

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring/applicationContext*.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>
            org.springframework.web.util.IntrospectorCleanupListener
        </listener-class>
  </listener>
</web-app>

这里再贴下jms_spring_produce中的jms_applicationContext.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<!-- 此处地址需要与启动的jms服务中的配置文件中activemq.xml中的 <transportConnector name="openwire" 
			uri="tcp://127.0.0.1:61616"中的端口指定一致/>配置 -->
		<property name="brokerURL" value="tcp://127.0.0.1:61616" />

 <!-- <property name="userName" value="system" /> <property name="password" value="manager"/> -->
		<!-- 对PERSISTENT的消息进行同步发送(NON_PERSISTENT消息默认异步发送) -->
	       <property name="useAsyncSend" value="true" /> 
	</bean>

	<bean id="cachingConnectionFactory"
		class="org.springframework.jms.connection.CachingConnectionFactory">
		<property name="targetConnectionFactory" ref="connectionFactory" />
		<property name="sessionCacheSize" value="10" />
	</bean>
	<!-- Spring JMS Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="cachingConnectionFactory" />
		<property name="deliveryPersistent" value="false" /> 
		<property name="priority" value="9" />
	</bean>
    <!-- 用户登录 -->
	<bean id="userLoginQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="queue.user.login" />
	</bean>
    <!-- 新闻点击 -->
     <bean id="newsVisitQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="queue.news.visit" />
	</bean>
</beans>

消费者jms_spring_consumer中的jms_applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

	<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<!-- 此处地址需要与启动的jms服务中的配置文件中activemq.xml中的 <transportConnector name="openwire" 
			uri="tcp://127.0.0.1:61616"中的端口指定一致/>配置 -->
		<property name="brokerURL" value="tcp://127.0.0.1:61616" />

 <!-- <property name="userName" value="system" /> <property name="password" value="manager"/> -->
		<!-- 对PERSISTENT的消息进行同步发送(NON_PERSISTENT消息默认异步发送) -->
	       <property name="useAsyncSend" value="true" /> 
	</bean>

	<bean id="cachingConnectionFactory"
		class="org.springframework.jms.connection.CachingConnectionFactory">
		<property name="targetConnectionFactory" ref="connectionFactory" />
		<property name="sessionCacheSize" value="10" />
	</bean>
	<!-- Spring JMS Template -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="cachingConnectionFactory" />
		<property name="deliveryPersistent" value="false" /> 
		<property name="priority" value="9" />
	</bean>
    <!-- 用户登录 -->
	<bean id="userLoginQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="queue.user.login" />
	</bean>
	<bean id="userLoginQueueContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="cachingConnectionFactory" />
		<property name="destination" ref="userLoginQueue" />
		<property name="messageListener" ref="userLoginLogListener" />
		<property name="concurrentConsumers" value="5" />
		<property name="maxConcurrentConsumers" value="10" />
	</bean>
    <!-- 新闻点击 -->
     <bean id="newsVisitQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg value="queue.news.visit" />
	</bean>
    <bean id="newsVisitQueueContainer"
		class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="cachingConnectionFactory" />
		<property name="destination" ref="newsVisitQueue" />
		<property name="messageListener" ref="newsVisitLogListener" />
		<property name="concurrentConsumers" value="5" />
		<property name="maxConcurrentConsumers" value="10" />
	</bean>
	
</beans>

   spring的配置,有很多参数,也有很多负责的功能,这里就不一一介绍了。

上面总共给出了4个项目jms_produce、jms_consumer、jms_spring_produce、jms_spring_consumer,这里打包上传了,大家可以下载看看

点我下载源码




 
 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值