ActiveMQ(1)---初识ActiveMQ

消息中间件的初步认识

什么是消息中间件?

消息中间件是值利用高效可靠的消息传递机制进行平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,可以在分布式架构下扩展进程之间的通信。

消息中间件能做什么?

消息中间件主要解决的就是分布式系统之间消息传递的问题,它能够屏蔽各种平台以及协议之间的特性,实现应用程序之间的协同。举个非常简单的例子,就拿一个电商平台的注册功能来简单分析下,用户注册这一个服务,不单
单只是 insert 一条数据到数据库里面就完事了,还需要发送激活邮件、发送新人红包或者积分、发送营销短信等一系列操作。假如说这里面的每一个操作,都需要消耗 1s,那么整个注册过程就需要耗时 4s 才能响应给用户。

但是我们从注册这个服务可以看到,每一个子操作都是相对独立的,同时,基于领域划分以后,发送激活邮件、发送营销短信、赠送积分及红包都属于不同的子域。所以我们可以对这些子操作进行来实现异步化执行,类似于多线程并行处理的概念。
如何实现异步化呢?用多线程能实现吗?多线程当然可以实现,只是,消息的持久化、消息的重发这些条件,多线程并不能满足。所以需要借助一些开源中间件来解决。而分布式消息队列就是一个非常好的解决办法,引入分布式消
息队列以后,架构图就变成这样了(下图是异步消息队列的场景)。通过引入分布式队列,就能够大大提升程序的处理效率,并且还解决了各个模块之间的耦合问题
➢ 这个是分布式消息队列的第一个解决场景【异步处理】

通过分布式消息队列来实现流量整形,比如在电商平台的秒杀场景下,流量会非常大。通过消息队列的方式可以很好的缓解高流量的问题

用户提交过来的请求,先写入到消息队列。消息队列是有长度的,如果消息队列长度超过指定长度,直接抛弃
➢ 秒杀的具体核心处理业务,接收消息队列中消息进行处理,这里的消息处理能力取决于消费端本身的吞吐量当然,消息中间件还有更多应用场景,比如在弱一致性事务模型中,可以采用分布式消息队列的实现最大能力通知方式来实现数据的最终一致性等等。

ActiveMQ 简介

ActiveMQ 是完全基于 JMS 规范实现的一个消息中间件产品。是 Apache 开源基金会研发的消息中间件。ActiveMQ主要应用在分布式系统架构中,帮助构建高可用、高性能、可伸缩的企业级面向消息服务的系统ActiveMQ 特性

1. 多语言和协议编写客户端

  语言:java/C/C++/C#/Ruby/Perl/Python/PHP

  应用协议 :

  openwire/stomp/REST/ws/notification/XMPP/AMQP

2. 完全支持 jms1.1 和 J2ee1.4 规范

3. 对 spring 的支持,ActiveMQ 可以很容易内嵌到 spring模块中

ActiveMQ 安装

1. 登录到 http://activemq.apache.org/activemq-5150-release.html,找到 ActiveMQ 的下载地址

2. 直 接 copy 到 服 务 器 上 通 过 tar -zxvf apache-activeMQ.tar.gz
3. 启动运行
  a) 普通启动:到 bin 目录下, sh activemq start
  b) 启 动 并 指 定 日 志 文 件 sh activemq start > /tmp/activemqlog
4. 检查是否已启动
  ActiveMQ默认采用 61616 端口提供 JMS服务,使用 8161端口提供管理控制台服务,执行以下命令可以检查是否成功启动 ActiveMQ 服务
  netstat -an|grep 61616
5. 通过 http://192.168.11.156:8161 访问 activeMQ 管理页面 ,默认帐号密码 admin/admin
6. 关闭 ActiveMQ; sh activemq stop

  从 JMS 规范来了解 ActiveMQ
JMS 定义

  Java 消息服务(Java Message Service)是 java 平台中关于面向消息中间件的 API,用于在两个应用程序之间,或者分布式系统中发送消息,进行异步通信。
JMS 是一个与具体平台无关的 API,绝大多数( MOMMessage Oriented Middleware)(面向消息中间件)提供商都对 JMS 提供了支持。今天给大家讲的 ActiveMQ 就是其中一个实现

什么是 MOM  

MOM 是面向消息的中间件,使用消息传送提供者来协调消息传送操作。MOM 需要提供 API 和管理工具。客户端使用 api 调用,把消息发送到由提供者管理的目的地。在发送消息之后,客户端会继续执行其他工作,并且在接收
方收到这个消息确认之前,提供者一直保留该消息。

MOM 的特点
1. 消息异步接收,发送者不需要等待消息接受者响应
2. 消息可靠接收,确保消息在中间件可靠保存。只有接收方收到后才删除消息
Java 消息传送服务规范最初的开发目的是为了使 Java 应用程序能够访问现有 MOM 系统。引入该规范之后,它已被许多现有的 MOM 供应商采用并且已经凭借自身的功能实现为异步消息传送系统。
其他开源的 JMS 提供商JbossMQ(jboss4) 、 jboss messaging(jboss5)、 joram 、ubermq、mantamq、openjms…大部分基于的 JMS provider 开源的消息中间件都已经停止维护了,剩下的几个都抱到了大腿,比如 Jboss mq 和 jboss、joram 与 jonas(objectweb 组 织 ) 、 ActiveMQ 与Geronimo(apache 基金组织)。

JMS 的体系结构 

通过 JMS 规范结合 ActiveMQ 实现消息发送案例

创建生产者
package com.lf.activemq;

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

import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSQueueProducer {
	
	public static void main(String[] args) {
		
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.130:61616");
		Connection connection = null;
		try {
			connection = activeMQConnectionFactory.createConnection();
			connection.start();
			//创建session
			Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			//创建目的地
			Destination destination = session.createQueue("myQueue");
			//创建消息生产者
			MessageProducer producer = session.createProducer(destination);
			//创建消息
			TextMessage message = session.createTextMessage("Hello lf!");
			//发送消息
			producer.send(message);
			
			session.commit();
			session.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 

创建消息消费者
package com.lf.activemq;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
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 JMSQueueReceiveder {
	
	public static void main(String[] args) {
		
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.130:61616");
		Connection connection = null;
		try {
			connection = activeMQConnectionFactory.createConnection();
			connection.start();
			//创建session
			Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			//创建目的地
			Destination destination = session.createQueue("myQueue");
			//创建消息接收者
			MessageConsumer consumer = session.createConsumer(destination);
			TextMessage message = (TextMessage) consumer.receive();
			System.out.println(message.getText());
			session.commit();
			session.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

  

结果:Hello lf!
阻塞式

2.消息消费者采用监听器

  

package com.lf.activemq;

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

import org.apache.activemq.ActiveMQConnectionFactory;

public class JMSQueueListenerReceiveder {
	
	public static void main(String[] args) {
		
		ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory("tcp://192.168.25.130:61616");
		Connection connection = null;
		try {
			connection = activeMQConnectionFactory.createConnection();
			connection.start();
			//创建session
			Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
			//创建目的地
			Destination destination = session.createQueue("myQueue");
			//创建消息接收者
			MessageConsumer consumer = session.createConsumer(destination);
			//创建消息监听器
			MessageListener messageListener = new MessageListener() {
				
				@Override
				public void onMessage(Message message) {
					try {
						System.out.println(((TextMessage)message).getText());
						session.commit();
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
			};
			while(true){
				consumer.setMessageListener(messageListener);
			}
//			TextMessage message = (TextMessage) consumer.receive();
//			System.out.println(message.getText());
			//session.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			if(connection != null){
				try {
					connection.close();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

 这个案例的架构图如下:

 

细化 JMS 的基本功能
  通过前面的内容讲解以及案例演示,我们已经知道了 JMS规范以及他的基本功能是用于和面向消息中间件相互通信的应用程序的接口,那么 JMS 提供的具体标准有哪些呢?
我们来仔细去研究下消息传递域JMS 规范中定义了两种消息传递域:点对点(point-topoint )消息传递域 和发布 / 订 阅 消息传递域(publish/subscribe)
简单理解就是:有点类似于我们通过 qq 聊天的时候,在群里面发消息和给其中一个同学私聊消息。在群里发消息,所有群成员都能收到消息。私聊消息只能被私聊的学员能收到消息,点对点消息传递域
1. 每个消息只能有一个消费者
2. 消息的生产者和消费者之间没有时间上的相关性。无论消费者在生产者发送消息的时候是否处于运行状态,都可以提取消息

发布订阅消息传递域
1. 每个消息可以有多个消费者
2. 生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。JMS 规范允许客户创建持久订阅,这在一定程度上降低了时间上的相关性要求。持久订阅允许消费者消费它在未处于激活状态时发送的消息

消息结构组成
  JMS 消息由及部分组成:消息头、属性、消息体
消息头
  消息头(Header) - 消息头包含消息的识别信息和路由信息,消息头包含一些标准的属性如:
JMSDestination 消息发送的目的地,queue 或者 topic)
JMSDeliveryMode 传送模式。持久模式和非持久模式
JMSPriority 消息优先级(优先级分为 10 个级别,从 0(最低)到 9(最高). 如果不设定优先级,默认级别是 4。需要注意的是,JMS provider 并不一定保证按照优先级的顺序提交消息)
JMSMessageID 唯一识别每个消息的标识
属性
按类型可以分为应用设置的属性,标准属性和消息中间件
定义的属性
1. 应用程序设置和添加的属性,比如Message.setStringProperty(“key”,”value”);通过下面的代码可以获得自定义属性的,在接收端的代码中编写
在发送端,定义消息属性
message.setStringProperty("lf","Hello World");









猜你喜欢

转载自www.cnblogs.com/flgb/p/10652034.html
今日推荐