ActiveMQ介绍
ActiveMQ是一种开源的基于JMS(Java Message Servie)规范的一种消息中间件的实现,(常用的几种信息交互技术(httpClient、hessian、dubbo、jms、webservice 五种)),消息的发送应该是异步的、非阻塞的。也就是说消息的发送者发送完消息后就直接返回了,不需要等待接收者返回后才能返回,发送者和接收者可以说是互不影响。所以这种规范(标准)能够减轻或消除系统瓶颈,实现系统之间去除耦合,提高系统的整体可伸缩性和灵活性。
JMS只是Java EE中定义的一组标准API,它自身并不是一个消息服务系统,它是消息传送服务的一个抽象,也就是说它定义了消息传送的接口而并没有具体实现,而ActiveMQ就是JMS规范的具体实现;它是Apache下的一个项目,采用Java语言开发;是一款非常流行的开源消息服务器,ActiveMQ的设计目标是提供标准的,面向消息的,能够跨越多语言和多系统的应用集成消息通信中间件JMS只是定义了一组有关消息传送的规范和标准,并没有真正实现,也就说JMS只是定义了一组接口而已,Apache ActiveMQ才是一个消息服务系统,而JMS不是
Java消息队列JMS整体设计结构
JMS两种消息传送模式
a.点对点(Point-to-Point):专门用于使用队列Queue传送消息;基于队列Queue的点对点消息只能被一个消费者消费,如多个消费者都注册到同一个消息队列上,当生产者发送一条消息后,而只有其中一个消费者会接收到该消息,而不是所有消费者都能接收到该消息。
b.发布/订阅(Publish/Subscribe):专门用于使用主题Topic传送消息。基于主题的发布与订阅消息能被多个消费者消费,生产者发送的消息,所有订阅了该topic的消费者都能接收到
ActiveMQ 环境搭建
1.下载:apache-activemq-5.15.12-bin.tar.gz
http://activemq.apache.org/components/classic/download/
2.安装activemq
2.1 apache-activemq-5.15.12-bin.tar.gz文件拷贝到/usr/local/activemq目录
2.2 解压启动 tar -zxvf apache-activemq-5.15.12-bin.tar.gz
2.3 cd apache-activemq-5.15.12/bin
./activemq start/stop
./activemq status 检查activemq启动状态,
如果ActiveMQ is running代表启动成功
netstat -anp|grep 61616
2.4 关闭window和linux防火墙 service iptables stop
3.Activemq 界面控制台:
访问界面 http://192.168.46.128:8161/ 初始用户名密码admin/admin
如果遇到进程起不来可以用 ./activemq console 可以查看启动报错日志
代码编写
生产者代码编写
package com.sxz.activemqprovider;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class HelloMQProvider {
public static final String MQ_URL = "tcp://192.168.46.128:61616";
public static void main(String[] args) throws JMSException {
//1、创建工厂连接对象,需要制定ip和端口号
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(MQ_URL);
//2、使用连接工厂创建一个连接对象
Connection connection = connectionFactory.createConnection();
//3、开启连接
connection.start();
//4、使用连接对象创建会话(session)对象
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5、使用会话对象创建目标对象,包含queue和topic(一对一和一对多)
Queue queue = session.createQueue("first-queue");
//6、使用会话对象创建生产者对象
MessageProducer producer = session.createProducer(queue);
//7、使用会话对象创建一个消息对象
for (int i = 1; i <=10; i++) {
TextMessage textMessage = session.createTextMessage("hello!first-queue_" + i);
textMessage.setJMSDeliveryMode(DeliveryMode.NON_PERSISTENT);
textMessage.setStringProperty("JMSXGroupID","group-001");
textMessage.setStringProperty("songxinzhi" , "VIP" );
//8、发送消息
producer.send(textMessage);
}
//9、关闭资源
producer.close();
//10、关闭会话
session.close();
//11、关闭连接
connection.close();
}
}
消费者代码
package com.sxz.activemqconsumer;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
import java.io.IOException;
/**
* @author song.xinzhi
* @Destination: TODO
* @date: 2020/4/11
*/
public class HelloMQConsumer {
public static final String MQ_URL = "tcp://192.168.46.128:61616";
public static void main(String[] args) throws JMSException, IOException {
//1. 创建一个工程连接类,需要指定IP和端口号
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(MQ_URL);
//2. 创建连接
Connection connection = connectionFactory.createConnection();
//3. 开启连接
connection.start();
//4. 使用连接对象创建会话(session)对象, 其中:Boolean.FALSE表示本次会话不开启事务管理,
//假如需要开启事务管理,将其改为Boolean.TRUE即可,同时需要在发送消息后添加session.commit(),否则,消息是不会被提交的.
//Session.AUTO_ACKNOWLEDGE表示消息确认机制 ,AUTO_ACKNOWLEDGE:自动确认,CLIENT_ACKNOWLEDGE:客户端确认
//SESSION_TRANSACTED:事务确认,如果使用事务推荐使用该确认机制
// AUTO_ACKNOWLEDGE:懒散式确认,消息偶尔不会被确认,也就是消息可能会被重复发送.但发生的概率很小
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//5. 使用会话对象创建目标对象,包含queue和topic(一对一和一对多)
Queue queue = session.createQueue("first-queue");
//6. 使用会话对象创建生产者对象
MessageConsumer consumer = session.createConsumer(queue);
//7. 向consumer对象中设置一个messageListener对象,用来接收消息
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if(message instanceof TextMessage){
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("--------------2______" +textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
//8、程序等待接收用户消息
System.in.read();
//9、关闭资源
consumer.close();
session.close();
connection.close();
}
}
测试结果,在MQ控制台上可以看到队列的信息
JMS Message 介绍
一个Message对象有3个部分:消息头、消息属性,最后就是消息数据内容,它称为负载或消息体
1. 消息头
每条JMS消息都有一组标准的消息头。每个消息头都由一组取值函数和赋值函数所标识。这些方法名称紧随在术语setJMS**(),getJMS**()方法之后
自动分配的消息头
开发者分配的消息头
2. 消息属性
消息属性就像可以分配一条消息的附加消息头一样。它们允许开发者添加有关消息的不透明附加消息。它们还用于暴露消息选择器在消息过滤时使用的数据。message接口为读取和写入属性提供了若干个取值函数和赋值函数方法,消息属性有3中基本类型:应用程序特定的属性、JMS定义的属性和提供者特定的属性
JMSXUserID:发送消息的用户识别,发送时提供商设置
JMSXappID:发送消息的应用标识,发送时提供商设置
JMSXdeliveryCount:转发消息重试次数:从1开始,发送方提供商设置JMSXGroupID:消息所在消息组的用户标识,由客户端设置
JMSXGroupSeq:组内消息的序号,从1开始.由客户端设置JMSXProducerTEID:产生消息的事务的事务表示,发送方提供商设置JMSConsumerTXID:消费消息的事务的事务表示,接收方提供设置JMSXRevTimestamp:JMS转发消息到消费者的事件,接收方提供设置JMState:假设有个消息仓库,它存储每个消息的单独拷贝,从原始消息被发送时开始,状态有1(等待),2(准备),3(到期),4(保留),由于状态和生产者和消费者无关,所以它不是由他们提供,它只和仓库查找消息相关,因此JMS没有提供这中API,由提供商设置
3.消息体
封装具体的消息数据
3.1 TextMessage(文本消息):编码字符串,对于外发消息,缺省情况下使用 UTF8 编码
3.2 BytesMessage(bytes消息):二进制数组消息,包含一个byte[]
3.3 ObjectMessage(对象消息):是 Java™ Runtime 以正常方式进行序列化的对象。
3.4 MapMessage(键值对消息):消息体包含了一系列的名字-值对.名字是String
3.5 StreamMessage(流消息):java 数据流消息,用标准流操作来顺序填充和读取