ActiveMQ消息队列demo

前言

什么是消息队列?
消息是指在两个独立的系统间传递的数据,这两个系统可以是两台计算机,也可以是两个进程。
消息可以非常简单,可以是简单的字符串,也可以是保存了数据持久化的各种类型的文档集合。
队列是在消息的传输过程中的通道,是保存消息的容器,根据不同的情形,可以有先进先出,优先级队列等区别 。

为什么要使用消息队列?
我个人的理解是主要对业务的解耦,操作异步处理,还有流量削锋等等问题,最终实现高性能,高可用,可伸缩和最终一致性。大家可参考这篇博客:https://blog.csdn.net/seven__________7/article/details/70225830

开始

整合准备工作: 先去官网http://activemq.apache.org/activemq-5154-release.html 下载开发包,我下载的是windows版本的,得到apache-activemq-5.15.4-bin.zip这样一个压缩文件,解压后,打开bin目录下的win32或者win64文件夹(根据自己windows版本),运行activemq.bat(请确保java环境变量无误,否则将闪退 ),保持运行窗口,打开浏览器访问http://127.0.0.1:8161/admin,输入用户名密码(默认均为admin),得到下面的消息队列控制台页面,即完成准备工作。
这里写图片描述

下面开始代码工作:
新建一个java工程,将开发包中的activemq-all-5.15.4.jar引入项目后即可开始。

(1)使用点对点模式,不可重复消费
创建消息发布者JMSProducer

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 消息发布者
 * @author zxy
 *
 */
public class JMSProducer {
	
	private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
	
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
	
	private static final String BROKERURL = ActiveMQConnection.DEFAULT_BROKER_URL;
	
	private static final int SENDNUM = 10;
	
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = null; //连接工厂
		Connection connection = null; //连接
		Session session = null; //会话接收或者发送消息的线程
		Destination destination = null; //消息的目的地
		MessageProducer messageProducer = null; //消息生产者
		
		//实例化连接工厂
		connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKERURL);
		
		try {
			//通过连接工厂获取连接
			connection = connectionFactory.createConnection();
			
			connection.start();
			
			//Boolean.TRUE表示开启事务
			session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			
			//创建消息队列
			destination = session.createQueue("FirstQueue1");
			
			//创建消息生产者
			messageProducer = session.createProducer(destination);
			
			//发送消息 
			sendMessage(session, messageProducer);
			
			//事务提交
			session.commit();
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void sendMessage(Session session, MessageProducer messageProducer){
		for(int i=0;i<SENDNUM;i++){
			try {
				TextMessage textMessage = session.createTextMessage("ActiveMQ 发送的消息" + i);
				System.out.println("发送消息:ActiveMQ发送的消息" + i);
				messageProducer.send(textMessage);
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

创建消息消费者JMSConsumer,两种消费方式:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 消息消费者一
 * 不断从队列出口获取消息
 * @author zxy
 *
 */
public class JMSConsumer {
	
private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
	
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
	
	private static final String BROKERURL = ActiveMQConnection.DEFAULT_BROKER_URL;
	
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = null; //连接工厂
		Connection connection = null; //连接
		Session session = null; //会话接收或者发送消息的线程
		Destination destination = null; //消息的目的地
		MessageConsumer messageConsumer = null; //消息消费者
		
		//实例化连接工厂
		connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKERURL);
		try {
			//通过连接工厂获取连接
			connection = connectionFactory.createConnection();
			connection.start();
			session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
			
			//创建消息队列
			destination = session.createQueue("FirstQueue1");
			
			//创建消息生产者
			messageConsumer = session.createConsumer(destination);
			
			while(true){
				TextMessage message = (TextMessage)messageConsumer.receive(100000);
				if(message != null){
					System.out.println("收到的消息:" + message.getText());
				}else{
					break;
				}
			}
			
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 消息消费者二
 * 通过消息监听获取消息
 * @author Administrator
 *
 */
public class JMSConsumer2 {

	private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
	
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
	
	private static final String BROKERURL = ActiveMQConnection.DEFAULT_BROKER_URL;
	
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = null; //连接工厂
		Connection connection = null; //连接
		Session session = null; //会话接收或者发送消息的线程
		Destination destination = null; //消息的目的地
		MessageConsumer messageConsumer = null; //消息消费者
		
		// 实例化连接工厂
		connectionFactory=new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKERURL);
				
		try {
			//通过连接工厂获取连接
			connection = connectionFactory.createConnection();
			connection.start();
			session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
			
			//创建消息队列
			destination = session.createQueue("FirstQueue1");
			
			// 创建消息消费者
			messageConsumer=session.createConsumer(destination); 
			
			// 注册消息监听
			messageConsumer.setMessageListener(new Listener()); 
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

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

/**
 * 消费者二自定义消息监听器
 * @author Administrator
 *
 */
public class Listener implements MessageListener{

	@Override
	public void onMessage(Message message) {
		// TODO Auto-generated method stub
		try {
			System.out.println("收到的消息:"+((TextMessage)message).getText());
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

消费方式一:
先开启JMSProducer,再开启JMSConsumer,消费结果如下:
这里写图片描述

消费方式二:
将JMSConsumer2复制一份重命名为JMSConsumer3,将两个先开启,监听消息发布,然后再开启JMSProducer,消费结果如下:
JMSConsumer2:
这里写图片描述
JMSConsumer3:
这里写图片描述

浏览器控制台Queues菜单项下可以找到如下结果,消息发布数量与消息消费数量始终保持一致:
这里写图片描述

(2)使用发布/订阅模式,可重复消费
创建消息发布者JMSProducer,与上述消息发布者其他代码全部一致,将创建消息队列的代码改动即可

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSProducer {
	
	private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
	
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
	
	private static final String BROKERURL = ActiveMQConnection.DEFAULT_BROKER_URL;
	
	private static final int SENDNUM = 10;
	
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = null; //连接工厂
		Connection connection = null; //连接
		Session session = null; //会话接收或者发送消息的线程
		Destination destination = null; //消息的目的地
		MessageProducer messageProducer = null; //消息生产者
		
		//实例化连接工厂
		connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKERURL);
		
		try {
			//通过连接工厂获取连接
			connection = connectionFactory.createConnection();
			connection.start();
			session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			
			//创建消息队列
			destination = session.createTopic("FirstTopic1");
			//创建消息生产者
			messageProducer = session.createProducer(destination);
			
			//发送消息 
			sendMessage(session, messageProducer);
			
			session.commit();
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	public static void sendMessage(Session session, MessageProducer messageProducer){
		for(int i=0;i<SENDNUM;i++){
			try {
				TextMessage textMessage = session.createTextMessage("ActiveMQ 发送的消息" + i);
				System.out.println("发送消息:ActiveMQ发布的消息" + i);
				messageProducer.send(textMessage);
			} catch (JMSException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

创建消息消费者JMSConsumer,与消息发布者代码改动一致:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 消息消费者
 * @author Administrator
 *
 */
public class JMSConsumer {

	private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
	
	private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
	
	private static final String BROKERURL = ActiveMQConnection.DEFAULT_BROKER_URL;
	
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = null; //连接工厂
		Connection connection = null; //连接
		Session session = null; //会话接收或者发送消息的线程
		Destination destination = null; //消息的目的地
		MessageConsumer messageConsumer = null; //消息消费者
		
		// 实例化连接工厂
		connectionFactory=new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKERURL);
				
		try {
			//通过连接工厂获取连接
			connection = connectionFactory.createConnection();
			connection.start();
			session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
			
			//创建消息队列
			destination = session.createTopic("FirstTopic1");
			
			// 创建消息消费者
			messageConsumer=session.createConsumer(destination); 
			
			// 注册消息监听
			messageConsumer.setMessageListener(new Listener()); 
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
}

将JMSConsumer复制一份重命名为JMSConsumer2,将两个先开启,监听消息发布,然后再开启JMSProducer,消费结果如下:
两者均为一个结果:
这里写图片描述
浏览器控制台Topics菜单项下可以找到如下结果,消息发布了10条,却消费了20次,即两个消费者重复消费了消息:
这里写图片描述

总结:以上即为所有过程,完成了ActiveMQ两种模式小demo 的整合,如有不足,欢迎指正。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值