ActiveMQ是Apache出品的,非常流行的消息中间件,可以说要掌握消息中间件,需要从ActiveMQ开始。首先去官网下载:ActiveMQ官网

一,ActiveMQ目录配置文件

1.1,ActiveMQ目录

bin

存放的是ActiveMQ的启动脚本activemq.bat。

conf

里面是配置文件,重点关注的是activemq.xml、jetty.xml、jetty-realm.properties。在登录ActiveMQ Web控制台需要用户名、密码信息、在JMS CLIENT和ActiveMQ进行何种协议的连接端口等这些信息都在上面的配置文件中可以体现。

data

目录下是ActiveMQ进行消息持久化存放的地方,默认采用的是kahadb,当然我们可以采用leveldb,或者采用JDBC存储到MySQL,或者干脆不使用持久化机制。

webapps

注意ActiveMQ自带Jetty提供Web管控台。

lib

中ActiveMQ为我们提供了分功能的JAR包。

1.2,ActiveMQ启动

CMD进入ActiveMQ所在的bin目录,输入ActiveMQ start即可启动ActiveMQ,这里必须已经安装JDK,需要注意JDK版本号。

浏览器输入localhost:8161即可访问ActiveMQ web后台管理

生产的消息查看方式:

Number Of Pending Messages

还有多少条消息没有被消费,实际上是表示消息的积压程度,就是P-C

Number Of Consumers

在该队列上还有多少消费者在等待接受消息

Messages Dequeued

消费了多少条消息,记做C

Messages Enqueued

生产了多少条消息,记做P

ActiveMQ 各个版本所依赖的JDK版本:

可以通过查看文件 activemq-all-*.jar包里面的\META-INF\MANIFEST.MF 属性值 Build-Jdk

1.3,ActiveMQ配置文件

jetty.xml

Jetty web容器的配置文件,里面可以修改ActiveMQ web后台的端口号。

jetty-realm.properties

这里保存了ActiveMQ web控制台的用户名、密码。

activemq.xml

内容太多,单独说。

二,ActiveMQ入门例

pom.xml中添加ActiveMQ依赖:

<dependency>

  <groupId>org.apache.activemq</groupId>

  <artifactId>activemq-all</artifactId>

  <version>5.14.5</version>

</dependency>

ActiveMQ接受/发送消息流程图:

2.1,ActiveMQLinkUtil帮助类:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Session;
 
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class ActiveMQLinkUtil {
private static final Logger logger = LoggerFactory.getLogger(ActiveMQLinkUtil.class);
//ActiveMQ 的默认用户名
private static String USERNAME = ActiveMQConnection.DEFAULT_USER;
//ActiveMQ 的默认登录密码
private static String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
//ActiveMQ 的链接地址
private static String BROKEN_URL = ActiveMQConnection.DEFAULT_BROKER_URL;
//链接工厂对象
private static ConnectionFactory connectionFactory = null;
//链接对象
private static Connection connection = null;
//会话对象
private static Session session = null;
/**
*
* @方法名: initConnection
* @描述: 初始化Connection,并返回Session对象,默认开启事务和自动签收
* @return Session对象
*/
public static Session initConnection(){
try {
String parameters = String.format("连接参数:userName=%s, pwd=%s, url=%s", USERNAME, PASSWORD, BROKEN_URL);
logger.info(parameters);
//第一步:创建一个链接工厂
connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
//第二步:从工厂中创建一个链接
connection = connectionFactory.createConnection();
//开启链接(默认是关闭的)
connection.start();
//第三步:创建session
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
logger.info("Init Connection success");
} catch (JMSException e) {
e.printStackTrace();
}
return session;
} /**
*
* @方法名: initConnection
* @描述: 初始化Connection
* @param transactionState 是否开启事务
* @param model 签收模式
* @return Session对象
*/
public static Session initConnection(Boolean transactionState, int model){
try {
String parameters = String.format("连接参数:userName=%s, pwd=%s, url=%s", USERNAME, PASSWORD, BROKEN_URL);
logger.info(parameters); connectionFactory = new ActiveMQConnectionFactory(USERNAME,PASSWORD,BROKEN_URL);
connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(transactionState, model);
logger.info("Init Connection success");
} catch (JMSException e) {
e.printStackTrace();
}
return session;
} /**
*
* @方法名: updateLinkParameter
* @描述: 修改默认ActiveMQ的连接属性
* @param userName
* @param pwd
* @param url
*/
public static void updateLinkParameter(String userName, String pwd , String url){
if(!StringUtils.isBlank(userName)){
USERNAME = userName;
}
if(!StringUtils.isBlank(pwd)){
PASSWORD = pwd;
}
if(!StringUtils.isBlank(url)){
BROKEN_URL = url;
}
} /**
*
* @方法名: closeConnection
* @描述: 关闭连接
*/
public static void closeConnection(){
if(connection != null){
try {
connection.close();
logger.info("close Connection success");
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}

2.2,创建生产者

package com.zender.activemq;
 
import javax.jms.DeliveryMode;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
 
/**
*
* @类名称:ActiveMQProducter
* @类描述:生产者
*/
public class ActiveMQProducter {
//会话对象
private static Session session = null; public static void sendMessages(String name){
try {
session = ActiveMQLinkUtil.initConnection();
if(session != null){
//第四步:创建一个消息目标,在PTP模式下是Queue,pub/sub模式下是topic
Queue queue = session.createQueue(name); //第五步:创建一个消息生产者
MessageProducer messageProducer = session.createProducer(queue); //第六步:设置持久化方式,默认设置为PERSISTENT(持久性)
messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
//第七步:创建文本消息,并发送
TextMessage textMessage = session.createTextMessage("消息内容" + (i + 1 ));
System.out.println("消息内容:" + textMessage.getText());
//使用生产者,发送消息
messageProducer.send(textMessage);
//提交事务
session.commit();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//第八步:释放连接
ActiveMQLinkUtil.closeConnection();
}
} public static void main(String[] args) {
ActiveMQProducter.sendMessages("Zender-MQ");
}
}

2.3,创建消费者

import javax.jms.MessageConsumer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
 
/**
*
* @类名称:ActiveMQComsumer
* @类描述:消费者
*/
public class ActiveMQComsumer {
//会话对象
private static Session session = null; public static void getMessages(String name){
try {
session = ActiveMQLinkUtil.initConnection();
if(session != null){
//创建一个消息队列
Queue queue = session.createQueue(name);
//创建一个消息消费者
MessageConsumer messageConsumer = session.createConsumer(queue);
for (int i = 0; i < 5; i++) {
Thread.sleep(1000);
//获取消息
TextMessage msg = (TextMessage) messageConsumer.receive();
//确认接到消息,这条代码可以不写,上面设置了自动消息确认
//msg.acknowledge();
System.out.println("消息内容:" + msg.getText());
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ActiveMQLinkUtil.closeConnection();
}
} public static void main(String[] args) {
ActiveMQComsumer.getMessages("Zender-MQ");
}
}

2.4,运行,查看结果

先运行生产者,再运行消费者。

生产者日志:

消费者日志:

三,Session中的事务和签收模式(消息确认机制)

在通过Connection创建Session的时候,需要设置2个参数,一个是否支持事务,另一个是签收的模式。重点说一下签收模式,ActiveMQ支持一下三种模式:

AUTO_ACKNOWLEDGE

表示在消费者receive消息的时候自动的签收

CLIENT_ACKNOWLEDGE

表示消费者receive消息后必须手动的调用acknowledge()方法进行签收

DUPS_OK_ACKNOWLEDGE

签不签收无所谓了,只要消费者能够容忍重复的消息接受,当然这样会降低Session的开销

在实际中,我们应该采用CLIENT_ACKNOWLEDGE这种签收模式,采用手动的方式较自动的方式可能更好些,因为接收到了消息,并不意味着成功的处理了消息,假设我们采用手动签收的方式,只有在消息成功处理的前提下才进行签收,那么只要消息处理失败,那么消息还有效,仍然会继续消费,直至成功处理。

四,消息选择器Selector

JMS Selectors,即消息选择器,前面介绍过消息的组成部分,其中谈到消息对象有消息属性,用于消息选择器。我们来看一段代码:

生产者:

package com.zender.activemq.selectors;
 
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
 
import com.zender.activemq.ActiveMQLinkUtil;
 
/**
*
* @类名称:ActiveMQSelectorsProducter
* @类描述:生产者-JSM选择器-消息选择器
*/
public class ActiveMQSelectorsProducter {
//会话对象
private static Session session = null; public static void sendMessages(String name){
try {
session = ActiveMQLinkUtil.initConnection(false, Session.CLIENT_ACKNOWLEDGE);
if(session != null){
//创建一个消息目标
Queue queue = session.createQueue(name);
//创建一个消息生产者
MessageProducer messageProducer = session.createProducer(queue);
for (int i = 0; i < 10; i++) {
//创建消息,并发送
TextMessage textMessage = session.createTextMessage("消息A-"+i);
textMessage.setStringProperty("JMSXtestId", "a");
//使用生产者,发送消息
messageProducer.send(textMessage); TextMessage textMessage1 = session.createTextMessage("消息B-"+i);
textMessage1.setStringProperty("JMSXtestId", "b");
messageProducer.send(textMessage1);
}
}
} catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args) {
ActiveMQSelectorsProducter.sendMessages("SelectorsDemo");
}
}

消费者:

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
 
import com.zender.activemq.ActiveMQLinkUtil;
 
/**
*
* @类名称:ActiveMQSelectorsComsumer
* @类描述:消费者-JSM选择器-消息选择器
*/
public class ActiveMQSelectorsComsumer {
//会话对象
private static Session session = null; @SuppressWarnings("unchecked")
public static void getMessages(String name){
try {
session = ActiveMQLinkUtil.initConnection(false, Session.CLIENT_ACKNOWLEDGE);
if(session != null){
//创建一个消息队列
Queue queue = session.createQueue(name);
//创建一个消息消费者
MessageConsumer messageConsumer = session.createConsumer(queue, "JMSXtestId='a'");
//获取消息
messageConsumer.setMessageListener(new MessageListener(){
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println(textMessage.getText());
//签收
textMessage.acknowledge();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
} public static void main(String[] args) {
ActiveMQSelectorsComsumer.getMessages("SelectorsDemo");
}
}

结果:

一个生产了20个消息,这边只消费了消息A的消息,消息B的并没有被消费。

2,ActiveMQ-入门的更多相关文章

  1. ActiveMQ入门练习

    ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线.ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久 ...

  2. jms - activeMQ入门案例

    activeMQ入门案例 叨叨一波,很久没写博客了,最近比较慢,时间抽不出来,这个借口说的很尴尬...我知道作为一名合格的码农就必须养成每天一博客的习惯.希望友友们别像我这样懒,闲话不多时进入今天的主 ...

  3. ActiveMQ 入门Nodejs版

    ActiveMQ 入门下载与安装 官方下载地址 解压,运行bin/win[32|64]/activemq[.bat] 启动服务 环境信息 控制台: http://localhost:8161 默认端口 ...

  4. 深入浅出 JMS(二) - ActiveMQ 入门指南

    深入浅出 JMS(二) - ActiveMQ 入门指南 上篇博文深入浅出 JMS(一) – JMS 基本概念,我们介绍了消息通信的规范JMS,这篇博文介绍一款开源的 JMS 具体实现-- Active ...

  5. ActiveMQ之一--ActiveMQ入门

    MQ的消费-生产者模型的一个典型的代表,一端往消息队列中不断的写入消息,而另一端则可以读取或者订阅队列中的消息.MQ和JMS类似,但不同的是JMS是SUN JAVA消息中间件服务的一个标准和API定义 ...

  6. ActiveMQ介绍和ActiveMQ入门实例

    ActiveMQ百度百科   ActiveMQ入门实例-cnblogs.com      作者用的是5.5的版本,我测试时用的是5.6,按照作者说的整了一下,走得通

  7. ActiveMQ 入门和与 Spring 整合

    ActiveMQ 入门演示 activemq 依赖 <dependency> <groupId>org.apache.activemq</groupId> < ...

  8. ActiveMQ入门系列三:发布/订阅模式

    在上一篇<ActiveMQ入门系列二:入门代码实例(点对点模式)>中提到了ActiveMQ中的两种模式:点对点模式(PTP)和发布/订阅模式(Pub & Sub),详细介绍了点对点 ...

  9. ActiveMQ入门系列二:入门代码实例(点对点模式)

    在上一篇<ActiveMQ入门系列一:认识并安装ActiveMQ(Windows下)>中,大致介绍了ActiveMQ和一些概念,并下载.安装.启动他,还访问了他的控制台页面. 这篇,就用代 ...

  10. Java消息中间件----ActiveMQ入门①

    一 首先到ActiveMQ下载安装包 Active官网地址http://activemq.apache.org/activemq-5150-release.html 如图所示,有两个下载的链接,我们下 ...

随机推荐

  1. java 多线程并发问题总结

    java 多线程并发主要通过关键字synchronized实现 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问 ...

  2. 【Linux-设备树】.dtb文件的反汇编

    在使用设备树时我们将**.dts文件利用dtc编译器编译为**.dtb文件. 在已知**.dtb文件的情况下我们有两种方法可以得到dts源码: 方法一:使用fdtdump工具进行反汇编 使用命令:ro ...

  3. SwipeRefreshLayout和RecyclerView类

    1 SwipeRefreshLayout和RecyclerView之间的关系 内容栏上下滚动是RecyclerView控制的,只有当内容栏滑动到最顶上时,再也拉不动了的时候,这个时候将动作交给Swip ...

  4. [转帖]青岛uber偷拍设备

    爱彼迎民宿路由器暗藏摄像头:官方回应已移除房源 https://www.cnbeta.com/articles/tech/844233.htm 罚款 就是搞笑啊.. 不过现在偷拍设备真多... 5月5 ...

  5. C++中的赋值操作符重载和拷贝构造函数

    1,关于赋值的疑问: 1,什么时候需要重载赋值操作符? 2,编译器是否提供默认的赋值操作符? 2,关于赋值的疑问: 1,编译器为每个类默认重载了赋值操作符: 1,意味着同类型的类对象可以相互赋值: 2 ...

  6. 腾讯云从零搭建PHP运行环境

    一.首先我们得注册腾讯云,租用一台服务器,我选择的是CentOS 7.2 64位,这时候会给你这台主机的公网IP和内网IP,以及这台主机的用户名及密码. 二.我们可以使用腾讯云网页上自带的登录按钮进行 ...

  7. 06: django+celery+redis

    目录: 1.1 Celery介绍 1.2 celery 组件 1.3 安装相关包 与 管理命令 1.4 celery与Django执行异步任务 1.5 在django中使用计划任务功能 1.1 Cel ...

  8. Django创建mysql数据表流程

    在Django项目建好后,在setting.py中设置好mysql连接参数: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysq ...

  9. 【ES6】对象的新功能与解构赋值

    ES6 通过字面量语法扩展.新增方法.改进原型等多种方式加强对象的使用,并通过解构简化对象的数据提取过程. 一.字面量语法扩展 在 ES6 模式下使用字面量创建对象更加简洁,对于对象属性来说,属性初始 ...

  10. HDU 1594 find the max

    数序问题. 题意是说 一个数列 a1,a2,--ai,--an;  x=i , y = ai:找两个点斜率绝对值.!最大. 第一次没找绝对值,--认真读题. .. x 每次加1 . 仅仅须要找 相邻的 ...