【ActiveMQ】- 点对点模式

MQ:Message Queue 消息队列

作用: MQ可理解为现实生活中的邮局,当A给物品给B时,A无需直接去找B当面去将物品交给B,A可以通过邮局寄送,然后B通过查询快递信息(监听),知道物品达到邮局,然后B自己去邮局取即可,MQ主要用于实现系统之间的解耦。

工作模式

point-to-point:点对点

特点:点对点并不是只A发送的消息只能指定B接收,而是只A发送的任意一条消息只能由一个人接收处理,也就是每条消息只能被消费一次,类似手机通话。

publish/subscribe

特点:A发送的消息可以被所有监听A的对象的接收,就好比学校的广播,所有的学生都可以收听校园广播信息。


常见MQ产品:ActiveMQ、RabbitMQ、IBMMQ、RocketMQ


ActiveMQ安装

apache官网下载解压,双击运行bin目录下的activemq.bat脚本,默认登陆用户名/密码:admin/admin


ActiveMQ p2p模式: 消息生产者:

package com.zhiwei.advanced.mq.activemq.ptp;

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

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

/**
 * 点对点消息模型
 * 
 * @author Zhiwei Yang
 *
 */
public class JMSProducer {

	private final static String user = ActiveMQConnection.DEFAULT_USER; // 默认用户名
	private final static String password = ActiveMQConnection.DEFAULT_PASSWORD; // 默认密码
	private final static String brokeURL = ActiveMQConnection.DEFAULT_BROKER_URL; // 链接地址

	public static void main(String[] args) throws Exception {

		ConnectionFactory factory = new ActiveMQConnectionFactory(JMSProducer.user, JMSProducer.password,
				JMSProducer.brokeURL); // 链接工厂
		Connection connection = factory.createConnection(); // 连接
		connection.start(); // 启动连接

		/**
		 * 参数1:是否支持事务 参数2:消息确认的方式:如果支持事务则忽略
		 * 
		 * Session.AUTO_ACKNOWLEDGE:当客户成功的从receive方法返回的时候或者从MessageListener.onMessage()
		 * 方法成功返回时,会话自动确认客户收到的消息
		 * 
		 * Session.CLIENT_ACKNOWLEDGE:客户通过消息的acknowledge方法确认消息,需要注意这种情况会话
		 * ,确认是会话层上进行,确认一个被消费的消息将自动确认所有已被会话消费的消息
		 *
		 * Session.DUPS_OK_ACKNOWLEDGE:该选择只是会话延迟 确认消息的提交,如果JMS Provider失败
		 * 可能会导致重复的消息,如果是重复的消息,那么JMS Provider必须把消息头的JMSRedelivered字段 设置为true
		 */
		Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);// 接受或发送消息的线程
		Destination destination = session.createQueue("FirstQueue"); // 创建消息队列:Destination子类:Queue/Topic

		MessageProducer messageProducer = session.createProducer(destination); // 创建消息生产者

		// 发送文本消息
		for (int i = 0; i < 10; i++) {
			TextMessage message = session.createTextMessage("JMS Provider发送消息:" + i);
			System.out.println("JMS Provider发送消息:" + i);
			messageProducer.send(message);
		}

		session.commit(); // 启用事务时session需要提交
		session.close();
		connection.close();
	}

}

消息消费者1

package com.zhiwei.advanced.mq.activemq.ptp;

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

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

/**
 * 点对点消息模型
 * 
 * @author Zhiwei Yang
 *
 */
public class JMSConsumer1 {

	private final static String user = ActiveMQConnection.DEFAULT_USER; // 默认用户名
	private final static String password = ActiveMQConnection.DEFAULT_PASSWORD; // 默认密码
	private final static String brokeURL = ActiveMQConnection.DEFAULT_BROKER_URL; // 链接地址

	public static void main(String[] args) throws Exception {

		ConnectionFactory factory = new ActiveMQConnectionFactory(user, password,brokeURL); // 链接工厂
		Connection connection = factory.createConnection(); // 连接
		connection.start(); // 启动连接
		
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 接受或发送消息的线程:消费不需事务
		
		Destination destination = session.createQueue("FirstQueue"); // 创建连接消息队列:Destination子类:Queue/Topic

		MessageConsumer messageConsumer = session.createConsumer(destination); // 创建消息生产者

        //不间断的接受消息
		while(true){
	     
		 TextMessage message = (TextMessage) messageConsumer.receive(10000);  //间隔1000ms接受消息
		
		 if(message != null){
			 System.out.println("收到消息" + message.getText());
		 }else{
			 System.out.println("消息队列无消息.......");
			 break;
		 }
		}
		session.close();
		connection.close();
	}

}

消息消费者2:使用监听器方式监听消息队列

package com.zhiwei.advanced.mq.activemq.ptp;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 * 点对点消息模型
 * 
 * 监听器监听:推荐
 */
public class JMSConsumer2 {

	private final static String user = ActiveMQConnection.DEFAULT_USER; // 默认用户名
	private final static String password = ActiveMQConnection.DEFAULT_PASSWORD; // 默认密码
	private final static String brokeURL = ActiveMQConnection.DEFAULT_BROKER_URL; // 链接地址

	public static void main(String[] args) throws Exception {

		ConnectionFactory factory = new ActiveMQConnectionFactory(JMSConsumer2.user, JMSConsumer2.password,JMSConsumer2.brokeURL); // 链接工厂
		Connection connection = factory.createConnection(); // 连接
		connection.start(); // 启动连接
		
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);// 接受或发送消息的线程:消费不需事务
		Destination destination = session.createQueue("FirstQueue"); // 创建连接消息队列:Destination子类:Queue/Topic

		MessageConsumer messageConsumer = session.createConsumer(destination); // 创建消息生产者
     
		messageConsumer.setMessageListener(new JMSListener());   //注册消息监听 :阻塞监听    
	}

}

消费者2监听器

package com.zhiwei.advanced.mq.activemq.ptp;

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

public class JMSListener implements MessageListener{

	@Override
	public void onMessage(Message message) {
		
		if(message instanceof TextMessage){
			try {
				System.out.println(((TextMessage) message).getText());
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
		
	}
}


测试:

  1. 先运行provider,ActiveMQ管理员页面显示消息队列FirstQueue,并且收到10条消息

  1. 运行2个consumer消费消息:10条消息被消费

控制台日志:

结果说明:2个消费者各消费5条信息

注意:activemq中显示的消费者数量是指活跃的消费者,因为其中一个消费者消费完后线程推出,导致WEBUI只显示1个消费者

转载于:https://my.oschina.net/yangzhiwei256/blog/3014210

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值