activeMQ

MQ存在解决的问题:

 如果一个系统是客户提交一个请求,服务器端就立马要响应,这样是客户端和服务器端之间生命周期的强相关。

但是一般情况下客户端提交请求只要服务器端记得做就行,不一定非要严格地请求到来立马处理并应答。这种情形类似于去取快递,有时你在上班,希望快递人员把包裹放在一个代取点,等你有时间再去取。

还有的情形是强相关带来的不好的地方,如果客户提交的请求因为网络原因,服务器端的故障等延期或丢失,那么服务器端会重复或者丢失处理。这样就会带来问题。

为了解决上述问题,引入了消息中间件机制,也叫做消息队列。Message Queue

activeMQ 是消息队列的一种

消息队列大致有两种类型,1.点对点模式,2.订阅发布模式

点对点模式是只要一个消息被一个消费者消费掉,就会把这条消息从消息队列移出。

订阅发布模式是一条消息可以被多个消费者消费。

简单的点对点模式Demo:

Producer.java:

package com.anlysqx.producer;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.ServerSession;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {
	
	private static final String USERNAME = "admin";
	private static final String PASSWORD = "admin";
	private static final String BROKEURL = "tcp://127.0.0.1:61616";
	private static final String QUEUENAME = "myQueue";

	public static void start() throws JMSException, InterruptedException{
		//获取ActiveMQ会话工厂
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
		//获取连接
		Connection createConnection = activeMQConnectionFactory.createConnection();
		//启动连接
		createConnection.start();
		//不启用事务,jms 设置消息可靠性 自动签收
		Session createSession = createConnection.createSession(true, Session.AUTO_ACKNOWLEDGE);
		//创建队列
		Queue createQueue = createSession.createQueue(QUEUENAME);
		//创建一个生产者
		MessageProducer createProducer = createSession.createProducer(createQueue);
		
		//放置消息
		for (int i = 0; i < 5; i++) {
			//设置存放消息队列内容
			TextMessage createTextMessage = createSession.createTextMessage("hello liaoyuan this is your first mq i:"+i);
			createProducer.send(createTextMessage);
			System.out.println("消息队列存放消息成功... i"+i);
			createSession.commit();
			Thread.sleep(100);
		}
		createSession.close();
		createConnection.close();
		
	}
	
	public static void main(String[] args) throws JMSException, InterruptedException {
		start();
	}
	
}

consumer.java:

package com.anlysqx.consumer;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class Consumer {
	private static final String USERNAME = "admin";
	private static final String PASSWORD = "admin";
	private static final String BROKEURL = "tcp://127.0.0.1:61616";
	private static final String QUEUENAME = "myQueue";

	public static void start() throws JMSException{
		//获取ActiveMQ会话工厂
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
		//获取连接
		Connection createConnection = activeMQConnectionFactory.createConnection();
		//启动连接
		createConnection.start();
		//不启用事务,jms 设置消息可靠性 自动签收
		Session createSession = createConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
		//创建队列
		Destination destination = createSession.createQueue(QUEUENAME);
		//创建一个消费者
		MessageConsumer createConsumer = createSession.createConsumer(destination);
		
		while(true){
			//阻塞方式接收消息
			TextMessage textMessage = (TextMessage) createConsumer.receive();
			if(textMessage != null){
				//打印消息
				System.out.println("消费者消费消息,内容:"+textMessage.getText());
				textMessage.acknowledge();
			}else{
				break;
			}
		}
		
		createSession.close();
		createConnection.close();
		
	}
	
	public static void main(String[] args) throws JMSException {
		start();
	}
}

上面的代码流程,生产者和消费者大致相同。非常类似Mybatis的session创建过程

首先得到连接工厂由连接工厂生成连接对象,连接对象start,连接对象生成session对象,session对象生成消息队列,session对象根据消息队列生成一个生产者,创建消息,生产者发送消息。最后关闭session,关闭connection。

需要注意的地方,

1.如果 Session createSession = createConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

false 代表不使用事务, Session.CLIENT_ACKNOWLEDGE代表当消息消费完成向MQ手动发送确认消息。

为了保证消息幂等性:

1.开启事务和Session.AUTO_ACKNOWLEDGE自动确认,再发送消息或消费消息后手动session.commit,这样一个事务完成就会给MQ发送确认,如果没有消费成功就会回滚。

2.不使用事务,使用手动确认 Session.CLIENT_ACKNOWLEDGE,再消息消费完成后手动textMessage.acknowledge();

   

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值