一.JMC 简介
全称:Java Message Service ,java消息服务。是java的一套API标准,最初的目的是为了使应用程序能够访问现有的MOM系统,后来被许多现有的MOM供应商采用,并实现为MOM系统。
1、MOM系统:指的是利用高效可靠的消息传递机制进行平台无光的数据交流,并给予数据通信来进行分布式系统的集成。
2、消息:是在两台计算机间传送的数据单位。消息可以非常简单,例如只包含文本字符串,也可以很复杂,包含嵌入对象。消息被发送到队列中。
3、“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到她的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
4、消息队列的作用:主要特点是异步处理,主要目的是减少请求响应时间和解耦。主要使用的场景就是将比较耗时而且不需要即时返回结果的操作作为消息放入消息队列。同时由于使用了消息队列,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方影响,即解耦和。
二.ActiveMQ 简介
1、多种语言和协议编写客户端。多种语言:java,c,c++,Ruby,Perl,Python等等。应用协议:Open Wire,Stomp REST,WS Notification,XMPP,AMQP,完全支持JMS1.1和J2EE1.4规范
2、对spring的支持,ACtiveMQ 可以很容易内嵌到使用spring的系统里面去。
3、名词解释:
(1)Destination
目的地,JMS Provider(消息中间件)负责维护,用于对Message进行管理的对象。MessageProduver需要制定Destination才能发送消息,MessageConsumer需要指定Destination才能接收消息。
(2)Producer
消息生产者(客户端、生产消息),负责发送Message到目的地。应用接口为MessageProducer。在JMS规范中,所有的标准定义都在javax.jms包中。
(3)Consumer
消息消费者(处理消息),负责从目的地中消费Message。应用接口为MessageConsumer.应用接口为MessageConsumer.
(4)Message
消息(message)封装一次通信的内容。常见类型有:StreamMessage,BytesMessage,TextMessage,ObjectMessage,MapMessage。
(5)ConnectionFactory
链接工厂,用于创建链接的工厂类型。注意,不能和JDBC中的ConnectionFactory混淆。
(6)Connection
链接,用于建立访问ActiveMQ 连接的类型,由链接工厂创建,注意不要和JDBC中的Connection混淆。
(7)Session
会话,一次持久有效有状态的访问。由链接创建,是具体操作消息的基础支撑。
(8)Queue&Topic
Queue是队列目的地,Topic是主题目的地。都是Destination的子接口。
Queue特点:对列中的消息,默认只能由唯一的一个消费者处理。一旦处理消息删除。
Topic特点:主题中的消息,会发送给所有的消费者同时处理。只有在消息可以重复处理的业务场景中可使用。
三.AcitveMQ 的安装
1.下载ActiveMQ的压缩包:;
2.linux环境需要安装jdk;
3.将tar.gz包上传到/usr/local/software目录下;
4.解压:tar -zxf apache-activemq-5.9.0-bin.tar.gz;
5.进入解压目录,即可看到activeMQ 的目录结构 :
6.移动目录: cp -r apache-activemq-5.9.0 /usr/local/activemq/
7.启动MQ:
/usr/local/activemq/bin/activemq start
8.验证是否启动成功:
ps -aux|grep activemq;
http://ip:8161/admin
用户名: admin
密码: admin
打开成功,即启动成功。(防火墙要关闭)
9.重启MQ:
/usr/local/activemq/bin/activemq restart
10.关闭MQ;
/usr/local/activemq/bin/activemq stop
四.ActiveMQ 的应用
1、PTP 处理模式(Queue)
消息生产者生产消息发送到 queue 中,然后消息消费者从 queue 中取出并且消费消息。消息被消费以后,queue 中不再有存储,所以消息消费者不可能消费到已经被消费的消
息。Queue 支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费、其它的则不能消费此消息了。当消费者不存在时,消息会一直保存,直到有消费者消费。
支持多个生产者,多个消费者,但是对于一个消息,只能由一个消费者进行消费。
具体代码实现:maven项目,简单的jar项目;
总体架构:
1.TextProducer.java代码
package com.sxt.first;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TextProducer {
public void sendTextMessage(String datas){
ConnectionFactory factory=null;
Connection connection=null;
Destination destination=null;
Session session=null;
MessageProducer producer=null;
Message message=null;
try {
factory=new ActiveMQConnectionFactory("guest","guest",
"tcp://192.168.120.140:61616");
connection=factory.createConnection();
connection.start(); session=connection.createSession(false,Session.CLIENT_ACKNOWLEDGE);
destination=session.createQueue("first-mq");
producer=session.createProducer(destination);
message=session.createTextMessage(datas);
producer.send(message);
System.out.println("消息已发送");
} catch (JMSException e) {
e.printStackTrace();
}finally {
if(producer !=null){
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
public static void main(String [] ars){
TextProducer textProducer=new TextProducer();
textProducer.sendTextMessage("测试ActiveMQ");
}
}
登录页面查询,http://192.168.120.140:8161/admin
numbers of pending Messages:等待被取走的消息个数;
Numbers of Consumers: 消费者个数;
Messages Enqueued: 进入过消息队列的消息数;
Messages Dequeued :被移除队列的消息数;
2.TextConsumer.java代码
package com.sxt.first;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TextConsumer {
public String receiveTextMessage(){
String resultCode="";
ConnectionFactory factory=null;
Connection connection=null;
Session session=null;
Destination destination=null;
MessageConsumer consumer=null;
Message message=null;
try {
factory=new ActiveMQConnectionFactory("admin","admin",
"tcp://192.168.120.140:61616");
connection=factory.createConnection();
connection.start();
session=connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
destination=session.createQueue("first-mq");
consumer=session.createConsumer(destination);
message=consumer.receive();
resultCode=((TextMessage)message).getText();
} catch (JMSException e) {
e.printStackTrace();
}finally {
if (connection!=null){
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
return resultCode;
}
public static void main(String [] args){
TextConsumer textConsumer=new TextConsumer();
String messageString=textConsumer.receiveTextMessage();
System.out.println("消息内容是:"+messageString);
}
}