消息队列,目前在实际的开发项目中应用十分广泛。本文主要介绍入门级的ActiveMQ的基本使用以及相关的概念。

一、JMS

  全称 Java Message Service,即Java消息服务。JMS是一套Java的面向消息中间件的API接口规范,用于在不同应用程序中异步的发送消息。JMS本身语言无关,绝大多数的消息中间件厂商都提供了对JMS的支持。基于JMS实现的消息中间件,也叫做JMS Provider。

  消息服务,传递的载体自然是消息(Message)。在JMS中,消息主体可以简单分为几个类型:简单文本(TextMessage)、可序列化的对象 (ObjectMessage)、属性集合 (MapMessage)、字节流 (BytesMessage)、原始值流 (StreamMessage)。

  JMS中,有一整套的名词提供,下面简单说说相关的名词以及解释:

  1、Destination

    目的地。JMS Provider(消息中间件)进行维护,用于对消息(Message)对象进行管理。MessageProducer需要指定Destination才能进行发送消息,MessageConsumer需要指定Destination才能进项消息的接收消费。

  2、Producer

    消息生产者,负责发送消息到Destination目的地。应用接口为MessageProducer。

  3、Consumer

    消息接收者,负责接收消费指定Destination的消息,应用接口为MessageConsumer。

  4、Message

    消息体,一般常用的有:TextMessage、ObjectMessage、BytesMessage。

  5、ConnectionFactory

    连接工厂。用于创建连接信息的。

  6、Connection

    连接。用于和ActiveMQ服务端建立连接,一般由连接工厂创建。

  7、Session

    会话。Session是操作消息的接口。可以通过session创建生产者、消费者、消息等信息。Session支持事务特征,当需要批处理(发送或者接收)消息的时候,可以将这些操作放到一个事务中进行。

  8、Queue和Topic

    Queue - 队列目的地。Topic - 主题目的地。都是Destination的子接口。

    Queue:一般队列中的一条消息,默认的只能被一个消费者消费。消费完成即删除。

    Topic:消息会发送给所有订阅的消费者。消息不会持久化,也即如果发消息时不存在订阅关系,则消息直接丢弃。

  9、PTP

    point to point,点对点模型。针对Queue实现的消息处理方式。

  10、Pub/Sub

    Publish & Subscribe,发布订阅模型。针对Topic实现的消息处理方式。

二、ActiveMQ简介

  ActiveMQ是纯Java编写的消息中间件服务,完全支持JMS规范。支持多种语言编写客户端:C、C++、C#、Java、PHP、Python等。应用协议包括:OpenWire、STOMP、WS-Notification、MQTT以及AMQP。对Spring的支持非常好,可以很容易的集成到现有的Spring系统中去使用。在消息的持久化上,支持jdbc和journal两种方式的使用。另外,在集群搭建上,也比较容易。上手难度比较低,适合大多数的中小型项目使用。

三、ActiveMQ安装

  1、下载安装包

    ActiveMQ官网下载包,注意的是,ActiveMQ 5.10.x以上版本需要JDK1.8的环境。其他只需要1.7环境即可。

  2、 上传linux服务器

    本文下载上传的是最新的 5.15.9版本。

  3、解压安装文件

    tar -zxf apache-activemq-5.15.9-bin.tar.gz

  4、检查权限

    ls -al apache-activemq-5.15.9/bin

    如果权限不足的话,会无法执行,修改文件权限:chmod 755 activemq

  5、移动到集中目录(可选)

    cp -r apache-activemq-5.15.9 /usr/local/activemq

  6、ActiveMQ配置文件简介

    配置文件目录为${activemq_home}/conf,对配置文件的修改,都必须重新启动ActiveMQ才能生效。

    6.1、activemq.xml

      就是Spring配置文件,配置了MQ使用的默认的对象组件。

      broker -  ActiveMQ的实例标签,配置的内容基本在此标签内部

      destinationPolicy - 配置目的地的规则信息

      persistenceAdapter - 配置持久化策略

      systemUsage - 内存信息设置

      transportConnectors - 配置连接端口信息,一般Java使用最多的就是openwire协议,也就是基于tcp的协议访问,默认开放端口61616,可自定义修改。

    6.2、jetty.xml

      ActiveMQ默认控制台的配置文件,也是个Spring的配置文件。一般在标签 jettyPort 中可以修改控制台的访问端口,默认是8161。控制台管理的时候需要用户名密码登录,默认为admin:admin。

  7、启动或停止ActiveMQ

    启动:${activemq_home}/bin/activemq start

    重启:${activemq_home}/bin/activemq restart

    停止:${activemq_home}/bin/activemq stop

  8、测试ActiveMQ

    8.1、查看是否成功启动:jps命令,查看是否有activemq.jar的信息:

    8.2、检查进程信息:ps -ef|grep activemq

    8.3、ActiveMQ控制台

    一般,使用浏览器访问ActiveMQ控制台管理信息,地址格式:http://ip:port/admin

    其中端口设置见上述 6.2节中提及。默认为8161。访问正确,出现下面界面几位成功启动:

  9、查看ActiveMQ状态

  ${activemq_home}/bin/activemq status

  

四、ActiveMQ基本使用

  上述安装完ActiveMQ之后,就可以使用Java代码去进行访问操作啦。下面开始介绍使用。

  编写生产者:

package com.cfang.mq.simpleCase;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session; import org.apache.activemq.ActiveMQConnectionFactory; public class SimpleProducer { public static void main(String[] args) {
SimpleProducer simpleProducer = new SimpleProducer();
simpleProducer.sendMsg("我有一只小毛驴");
} public void sendMsg(String msg) {
ConnectionFactory factory = null; //连接工厂
Connection connection = null; //连接对象
Session session = null; //session会话
Destination destination = null; //目的地
MessageProducer producer = null; //生产者
Message message = null; //消息
try {
//创建连接工厂,前两个参数是做安全认证使用,本例中尚未开启。
factory = new ActiveMQConnectionFactory(null, null, "tcp://172.31.31.160:61616");
//通过工厂创建连接对象
connection = factory.createConnection();
//启动连接。生产者通常来说不是必须显式启动的,在发送消息的时候,会检测是否启动,未启动的话会先进行启动操作。
connection.start();
/**
* 根据连接对象信息,创建session会话信息。
* 第一个参数为是否开启事务特性。
* false - 不开启事务。使用比较多的配置。
* true - 开启事务。如果开启事务,这第二个参数默认无效了,建议还是写成Session.SESSION_TRANSACTED
* 第二个参数表示消息确认机制。
* AUTO_ACKNOWLEDGE - 自动消息确认。消息消费者接受处理消息后,自动发送确认信息
* CLIENT_ACKNOWLEDGE - 手动确认。消息消费者在接受处理消息后,必须手动发起确认ack信息
* DUPS_OK_ACKNOWLEDGE - 有副本的手动确认机制。
*/
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建目的地,参数是目的地名称,也即队列名。
destination = session.createQueue("tp_simple_queue");
//创建消息生产者,参数为目的地,也可以不指定,在发送消息的时候再指定
producer = session.createProducer(destination);
//创建消息
message = session.createTextMessage(msg);
//发送到ActiveMQ指定的目的地中
producer.send(message);
System.out.println("=====send msg ok!=====");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 回收资源
if(producer != null){ // 回收消息发送者
try {
producer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if(session != null){ // 回收会话对象
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if(connection != null){ // 回收连接对象
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
}

  编写消费者

package com.cfang.mq.simpleCase;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnectionFactory; public class SimpleConsumer { public static void main(String[] args) {
SimpleConsumer simpleConsumer = new SimpleConsumer();
System.out.println("=====receive msg: " + simpleConsumer.receiveMsg());
} public String receiveMsg() {
String result = "";
ConnectionFactory factory = null; //连接工厂
Connection connection = null; //连接对象
Session session = null; //session会话
Destination destination = null; //目的地
MessageConsumer consumer = null; //生产者
Message message = null; //消息
try {
factory = new ActiveMQConnectionFactory(null, null, "tcp://172.31.31.160:61616");
connection = factory.createConnection();
//不同于生产者存在自动启动机制,消息的消费者必须显式的手动启动连接
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//创建目的地,参数是目的地名称,也即队列名。
destination = session.createQueue("tp_simple_queue");
//创建消费者,参数为目的地,也可以不指定,在发送消息的时候再指定
consumer = session.createConsumer(destination);
//接收一条消息
message = consumer.receive();
//手动确认
// message.acknowledge();
result = ((TextMessage)message).getText();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 回收资源
if(consumer != null){ // 回收消息发送者
try {
consumer.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if(session != null){ // 回收会话对象
try {
session.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
if(connection != null){ // 回收连接对象
try {
connection.close();
} catch (JMSException e) {
e.printStackTrace();
}
}
}
return result;
}
}

五、ActiveMQ安全认证 

  上面简单的写了个生产者、消费者的案例,其中在创建连接工厂ConnectionFactory的时候,前两个参数都没有去设置值,程序运行也没有任何的问题。这是因为安装的ActiveMQ尚未启用安全认证插件,这种情况下,只要知道mq的地址信息,均可以连接上去进行消息的收发。

  在一些特定的需求中,需要对ActiveMQ的连接进行认证,下面介绍ActiveMQ的安全认证配置。

  ActiveMQ的安全认证配置,是基于用户名密码校验的。启用安全认证,需要对activemq.xml进行修改,具体修改办法:

    在broker标签中,增加安全认证插件:

<plugins>
<!-- use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->
<!-- 添加jaas认证插件activemq在login.config里面定义,详细见login.config-->
<jaasAuthenticationPlugin configuration="activemq" />
<!-- lets configure a destination based authorization mechanism -->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
<authorizationEntry queue="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>

  /conf/login.config配置内容:

activemq {
org.apache.activemq.jaas.PropertiesLoginModule required
org.apache.activemq.jaas.properties.user="users.properties"
org.apache.activemq.jaas.properties.group="groups.properties";
};

  其中 user 代表的是用户的配置文件信息,group 代表的是用户组信息配置文件。

  /conf/user.properties,配置文件中格式为:用户名=密码

admin=admin

  /conf/group.properties,配置文件中格式为:用户组名=用户名,用户名,用户名

admins=admin

  确认添加完毕后,需要重启ActiveMQ。之后Java应用程序创建访问ConnectionFactory的时候,必须指定上述配置文件中正确的用户名密码,否则会报错如下:

  

ActiveMQ基本使用的更多相关文章

  1. Java消息队列--ActiveMq 实战

    1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...

  2. 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)

    Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...

  3. (jms)ActiveMQ 安装配置.

    前言 ActiveMQ他是Apache出品的一个JMS提供者,管理会话和队列,运行在JVM下,支持多种语言,如JAVA,C++,C#,应用协议: OpenWire,Stomp REST,WS Noti ...

  4. node(ActiveMq)

    简单尝试了node下的ActiveMQ 1.下载apache-activemq-5.9.0,执行bat文件: 2.登录http://localhost:8161/admin可查看其管理后台: 3.安装 ...

  5. ActiveMQ的集群方案对比及部署

    转载:http://blog.csdn.net/lifetragedy/article/details/51869032 ActiveMQ的集群 内嵌代理所引发的问题: 消息过载 管理混乱 如何解决这 ...

  6. JMS学习之路(一):整合activeMQ到SpringMVC

    JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需求中的话我们可以 ...

  7. ActiveMQ消息队列的使用及应用

    这里就不说怎么安装了,直接解压出来就行了. 谢绝转载,作者保留所有权力 目录:  一:JMQ的两种消息模式 1.1:点对点的消息模式 1.2:订阅模式 二:点对点的实现代码 2.1:点对点的发送端 2 ...

  8. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  9. Spring下ActiveMQ实战

    MessageQueue是分布式的系统里经常要用到的组件,一般来说,当需要把消息跨网段.跨集群的分发出去,就可以用这个.一些典型的示例就是: 1.集群A中的消息需要发送给多个机器共享: 2.集群A中消 ...

  10. ActiveMQ(li)

    一.ActiveMQ 首先,ActiveMQ不是一个框架,它不是struct,webx,netty这种框架,它更像是tomcat服务器,因为你使用它之前必须启动它,activeMQ和JMS的关系有点类 ...

随机推荐

  1. DFS树求割点问题

    时间复杂度:O(n玄学)总之不大 代码实现(好麻烦,蓝题变紫题) #include<iostream> #include<string.h> #include<algor ...

  2. 高级脚本进阶—使用case的多功能选择性脚本

    应用场景: 在应用脚本决解实际的运维问题时,单功能脚本有很多的不同应用环境,如不同的运行环境,不同的系统版本等,这时,就需要对脚本的功能进行选择,一个脚本实现多功能多版本系统的维护,以减少沟通成本,而 ...

  3. 记录一下vue transition 过渡各状态()

    .slide-fade-enter{   opacity: 0;   transform: translateX(100px);   /*从哪里开始过渡:在过渡之前我就把位置定义在100px的位置,并 ...

  4. spring加载bean流程解析

    spring作为目前我们开发的基础框架,每天的开发工作基本和他形影不离,作为管理bean的最经典.优秀的框架,它的复杂程度往往令人望而却步.不过作为朝夕相处的框架,我们必须得明白一个问题就是sprin ...

  5. c#中的委托01

    delegate 是表示对具有特定参数列表和返回类型的方法的引用的类型. 在实例化委托时,你可以将其实例与任何具有兼容签名和返回类型的方法相关联. 你可以通过委托实例调用方法. 委托用于将方法作为参数 ...

  6. [code] python+selenium实现打开一个网页

    转载自: http://www.cnblogs.com/fnng/archive/2013/05/29/3106515.html http://www.testwo.com/blog/6931 在ec ...

  7. CodeForces - 938D-Buy a Ticket+最短路

    Buy a Ticket 题意:有n个点和m条路(都收费),n个点在开演唱会,门票不同,对于生活在n个点的小伙伴,要求计算出每个小伙伴为了看一场演唱会要花费的最小价格: 思路: 这道题我一开始觉得要对 ...

  8. lightoj 1037 - Agent 47(状压dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1037 #include <iostream> #include & ...

  9. hdu1521 排列组合 指数型母函数模板题

    排列组合 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  10. Python学习之旅:使用Python实现Linux中的ls命令

    一.写在前面 前几天在微信上看到这样一篇文章,链接为:https://mp.weixin.qq.com/s/rl6Sgv3uk_IpoFAx6cWa8w,在这篇文章中,有这样一段话,吸引了我的注意: ...