tomcat+JNDI+ActiveMQ简单实例

上一篇写了消费者生产者模式,地址http://blog.csdn.net/kuang_wu/article/details/53260185

使用active之前,先看看java消息模式的基础:http://www.cnblogs.com/chenpi/p/5559349.html

实现点对点消息传输:http://www.cnblogs.com/chenpi/p/5565618.html

实现发布/订阅消息:直接上代码


1、下载activeMq:

官网地址,我下的apache-activemq-5.14.1-bin 地址:http://activemq.apache.org/download.html

运行activeMq: 我的是64位系统 所以进入bin/64/文件夹下运行

运行后输入:http://localhost:8161/admin 进入如下页面。表示运行成功



2、tomcat配置

修改conf/context.xml文件加入如下代码
<Resource auth="Container" brokerName="localhost" brokerURL="failover:(tcp://localhost:61616)?initialReconnectDelay=100&maxReconnectAttempts=5" description="JMS Connection Factory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" name="jms/FailoverConnectionFactory" type="org.apache.activemq.ActiveMQConnectionFactory" useEmbeddedBroker="false"/> 
    <Resource auth="Container" brokerName="localhost" brokerURL="tcp://localhost:61616" description="JMS Connection Factory" factory="org.apache.activemq.jndi.JNDIReferenceFactory" name="jms/NormalConnectionFactory" type="org.apache.activemq.ActiveMQConnectionFactory" useEmbeddedBroker="false"/> 
    <Resource auth="Container" factory="org.apache.activemq.jndi.JNDIReferenceFactory" name="jms/topic/MyTopic" physicalName="MY.TEST.FOO" type="org.apache.activemq.command.ActiveMQTopic"/> 
    <Resource auth="Container" factory="org.apache.activemq.jndi.JNDIReferenceFactory" name="jms/queue/MyQueue" physicalName="MY.TEST.FOO.QUEUE" type="org.apache.activemq.command.ActiveMQQueue"/> 

然后activeMq包下的 jar包放入在tomcat/lib包下

3、java代码

新建JMSListener类
package com.flvcd.servlet;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.TopicSubscriber;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 
 * 
 * @version V1.0
 */
public class JMSListener extends HttpServlet implements MessageListener{

	public void init(ServletConfig config) throws ServletException{
		try {
			InitialContext initCtx = new InitialContext();//
			Context envContext = (Context) initCtx.lookup("java:comp/env");
			ConnectionFactory connectionFactory = (ConnectionFactory) envContext.lookup("jms/FailoverConnectionFactory");
			Connection connection = connectionFactory.createConnection();
			connection.setClientID("MyClient");
			Session jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			// 普通消息订阅者,无法接收持久消息 //MessageConsumer consumer =
            // jmsSession.createConsumer((Destination)
            // envContext.lookup("jms/topic/MyTopic"));
            // //基于Topic创建持久的消息订阅者,前提:Connection必须指定一个唯一的clientId,当前为MyClient
			TopicSubscriber consumer = jmsSession.createDurableSubscriber((Topic)envContext.lookup("jms/topic/MyTopic"), "MySub");
			consumer.setMessageListener(this);
			connection.start();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	/**
	 * 接收消息,做对应处理
	 */
	@Override
	public void onMessage(Message message) {
		// TODO Auto-generated method stub
		if(checkText(message,"RefreshArticleId")!=null){
			String articleId = checkText(message,"RefreshArticleId");
			System.out.println("接收刷新文章消息,开始刷新文章ID="+articleId);
		}else if(checkText(message,"RefreshThreadId")!=null){
			String threadId = checkText(message,"RefreshThreadId");
			System.out.println("接收刷新论坛帖子消息,开始刷新帖子ID="+threadId);
		}else{
			System.out.println("接收普通消息,不做任何处理!");
		}
	}
	
	/**
	 * 
	 * @Title: checkText 
	 * @return String
	 * @author zyj
	 * @throws
	 */
	private static String checkText(Message m, String s){
		try {
			return m.getStringProperty(s);
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

}
新建MyPublish类
package com.flvcd.servlet;


import java.io.IOException;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyPublish extends HttpServlet implements MessageListener{

	private InitialContext initCtx;
	private Context envContext;
	private ConnectionFactory connectionFactory;
	private Connection connection;
	private Session session;
	private MessageProducer producer;
	
	@Override
	public void onMessage(Message arg0) {
		// TODO Auto-generated method stub
	}
	
	public MyPublish() { 
        super(); 
    } 
	
	public void destroy() { 
        super.destroy(); // Just puts "destroy" string in log 
        // Put your code here 
    } 
	
	public void init() throws ServletException { 
		try {
			initCtx = new InitialContext();
			envContext = (Context) initCtx.lookup("java:comp/env");
			connectionFactory = (ConnectionFactory) envContext.lookup("jms/NormalConnectionFactory");
			connection = connectionFactory.createConnection();
			connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
			session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
			producer = session.createProducer((Destination) envContext.lookup("jms/topic/MyTopic"));
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException { 
		String content = request.getParameter("content");
		
		try {
			producer.setDeliveryMode(DeliveryMode.PERSISTENT);
			Message testMessage = session.createMessage();
			// 发布刷新文章消息
			testMessage.setStringProperty("RefreshArticleId",content);
			producer.send(testMessage);
			// 发布刷新帖子消息
			testMessage.clearProperties();
			testMessage.setStringProperty("RefreshThreadId", content); 
	        producer.send(testMessage); 
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
	}

}

web.xml加入以下配置
  </welcome-file-list>
  <servlet>
  	<servlet-name>sssss</servlet-name>
  	<servlet-class>com.flvcd.servlet.MyPublish</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>sssss</servlet-name>
  	<url-pattern>/myPublish.do</url-pattern>
  </servlet-mapping>
  
  <servlet>
    <servlet-name>jms-listener</servlet-name>
    <servlet-class>
       com.flvcd.servlet.JMSListener
    </servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  

index.html
	<form action="myPublish.do" method="post">
		<input type="text" name="content"/>
		<input type="submit" value="提交"/>
	</form>

4、运行后打印日志

接收刷新文章消息,开始刷新文章ID=asd
接收刷新论坛帖子消息,开始刷新帖子ID=asd

5、activieMq对比



Number Of Consumers  消费者 这个是消费者端的消费者数量 

Number Of Pending Messages 等待消费的消息 这个是当前未出队列的数量。可以理解为总接收数-总出队列数 
Messages Enqueued 进入队列的消息  进入队列的总数量,包括出队列的。 这个数量只增不减 
Messages Dequeued 出了队列的消息  可以理解为是消费这消费掉的数量 
这个要分两种情况理解 
在queues里它和进入队列的总数量相等(因为一个消息只会被成功消费一次),如果暂时不等是因为消费者还没来得及消费。 
在 topics里 它因为多消费者从而导致数量会比入队列数高。 
简单的理解上面的意思就是 
当有一个消息进入这个队列时,等待消费的消息是1,进入队列的消息是1。 
当消息消费后,等待消费的消息是0,进入队列的消息是1,出队列的消息是1. 
在来一条消息时,等待消费的消息是1,进入队列的消息就是2. 


没有消费者时  Pending Messages   和 入队列数量一样 
有消费者消费的时候 Pedding会减少 出队列会增加 
到最后 就是 入队列和出队列的数量一样多 
以此类推,进入队列的消息和出队列的消息是池子,等待消费的消息是水流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值