ActiveMQ简述
概述
ActiveMQ是Apache所提供的一个开源的消息系统,全然採用Java来实现。因此。它能非常好地支持J2EE提出的JMS(Java Message Service,即Java消息服务)规范。
JMS是一组Java应用程序接口。它提供消息的创建、发送、读取等一系列服务。JMS提供了一组公共应用程序接口和响应的语法。相似于Java数据库的统一訪问接口JDBC,它是一种与厂商无关的API,使得Java程序能够与不同厂商的消息组件非常好地进行通信。
JMS支持两种消息发送和接收模型。一种称为P2P(Ponit to Point)模型。即採用点对点的方式发送消息。P2P模型是基于队列的,消息生产者发送消息到队列。消息消费者从队列中接收消息,队列的存在使得消息的异步传输称为可能,P2P模型在点对点的情况下进行消息传递时採用。
还有一种称为Pub/Sub(Publish/Subscribe,即公布-订阅)模型,公布-订阅模型定义了怎样向一个内容节点公布和订阅消息,这个内容节点称为topic(主题)。主题能够觉得是消息传递的中介,消息公布这将消息公布到某个主题,而消息订阅者则从主题订阅消息。主题使得消息的订阅者与消息的公布者互相保持独立。不须要进行接触就可以保证消息的传递,公布-订阅模型在消息的一对多广播时採用。
ActiveMQ的安装
下载最新的安装包apache-activemq-5.13.2-bin.tar.gz(此包linux下的,案例也是针对linux系统进行阐述,当然ActiveMQ也有win版的。这里就不赘述了)。能够去官网下载。也能够在下方留言区留下你的邮箱。博主会发给你的~
下载之后解压: tar -zvxf apache-activemq-5.13.2-bin.tar.gz
ActiveMQ文件夹内容有:
- bin文件夹包括ActiveMQ的启动脚本
- conf文件夹包括ActiveMQ的全部配置文件
- data文件夹包括日志文件和持久性消息数据
- example: ActiveMQ的演示样例
- lib: ActiveMQ执行所须要的lib
- webapps: ActiveMQ的web控制台和一些相关的demo
执行命令:activemq start(在activemq/bin下执行)
INFO: Loading '/users/shr/apache-activemq-5.13.2//bin/env'
INFO: Using java '/users/shr/util/JavaDir/jdk/bin/java'
INFO: Starting - inspect logfiles specified in logging.properties and log4j.properties to get details
INFO: pidfile created : '/users/shr/apache-activemq-5.13.2//data/activemq.pid' (pid '986')
查看activemq是否执行命令:ps -aux | grep activemq
shr 986 1.2 9.7 1281720 201936 pts/5 Sl 19:43 0:17 /users/shr/util/JavaDir/jdk/bin/java -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/users/shr/apache-activemq-5.13.2//conf/login.config -Dcom.sun.management.jmxremote -Djava.awt.headless=true -Djava.io.tmpdir=/users/shr/apache-activemq-5.13.2//tmp -Dactivemq.classpath=/users/shr/apache-activemq-5.13.2//conf:/users/shr/apache-activemq-5.13.2//../lib/: -Dactivemq.home=/users/shr/apache-activemq-5.13.2/ -Dactivemq.base=/users/shr/apache-activemq-5.13.2/ -Dactivemq.conf=/users/shr/apache-activemq-5.13.2//conf -Dactivemq.data=/users/shr/apache-activemq-5.13.2//data -jar /users/shr/apache-activemq-5.13.2//bin/activemq.jar start
shr 1501 0.0 0.0 5176 724 pts/5 S+ 20:06 0:00 grep activemq
关闭命令: activemq stop
INFO: Loading '/users/shr/apache-activemq-5.13.2//bin/env'
INFO: Using java '/users/shr/util/JavaDir/jdk/bin/java'
INFO: Waiting at least 30 seconds for regular process termination of pid '986' :
Java Runtime: Oracle Corporation 1.7.0_79 /users/shr/util/JavaDir/jdk1.7.0_79/jre
Heap sizes: current=63232k free=62218k max=932096k
JVM args: -Xms64M -Xmx1G -Djava.util.logging.config.file=logging.properties -Djava.security.auth.login.config=/users/shr/apache-activemq-5.13.2//conf/login.config -Dactivemq.classpath=/users/shr/apache-activemq-5.13.2//conf:/users/shr/apache-activemq-5.13.2//../lib/: -Dactivemq.home=/users/shr/apache-activemq-5.13.2/ -Dactivemq.base=/users/shr/apache-activemq-5.13.2/ -Dactivemq.conf=/users/shr/apache-activemq-5.13.2//conf -Dactivemq.data=/users/shr/apache-activemq-5.13.2//data
Extensions classpath:
[/users/shr/apache-activemq-5.13.2/lib,/users/shr/apache-activemq-5.13.2/lib/camel,/users/shr/apache-activemq-5.13.2/lib/optional,/users/shr/apache-activemq-5.13.2/lib/web,/users/shr/apache-activemq-5.13.2/lib/extra]
ACTIVEMQ_HOME: /users/shr/apache-activemq-5.13.2
ACTIVEMQ_BASE: /users/shr/apache-activemq-5.13.2
ACTIVEMQ_CONF: /users/shr/apache-activemq-5.13.2/conf
ACTIVEMQ_DATA: /users/shr/apache-activemq-5.13.2/data
Connecting to pid: 986
..Stopping broker: localhost
.. TERMINATED
ActiveMQ的默认服务端口为61616。这个能够在conf/activemq.xml配置文件里改动:
<transportConnectors>
<!-- DOS protection, limit concurrent connections to 1000 and frame size to 100MB -->
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
</transportConnectors>
案例
在下载的apache-activemq-5.13.2-bin.tar.gz包中解压有一个jar包:activemq-all-5.13.2.jar,引入这个jar到你的项目中就可以開始编写案例代码。
博主的activemqserver地址为10.10.195.187。这个在以下代码中会有体现。
依照JMS的规范,我们首先须要获得一个JMS connection factory.。通过这个connection factory来创建connection.在这个基础之上我们再创建session, destination, producer和consumer。因此基本的几个过程例如以下:
- 获得JMS connection factory. 通过我们提供特定环境的连接信息来构造factory。
- 利用factory构造JMS connection
- 启动connection
- 通过connection创建JMS session.
- 指定JMS destination.
- 创建JMS producer或者创建JMS message并提供destination.
- 创建JMS consumer或注冊JMS message listener.
- 发送和接收JMS message.
- 关闭全部JMS资源,包括connection, session, producer, consumer等。
以下来看代码举例(P2P式)。
通过Java实现的基于ActiveMQ的请求提交:
package com.zzh.activemq;
import java.io.Serializable;
import java.util.HashMap;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class RequestSubmit
{
//消息发送者
private MessageProducer producer;
//一个发送或者接受消息的线程
private Session session;
public void init() throws Exception
{
//ConnectionFactory连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://10.10.195.187:61616");
//Connection:JMSclient到JMS Provider的连接。从构造工厂中得到连接对象
Connection connection = connectionFactory.createConnection();
//启动
connection.start();
//获取连接操作
session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destinatin = session.createQueue("RequestQueue");
//得到消息生成(发送)者
producer = session.createProducer(destinatin);
//设置不持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
public void submit(HashMap<Serializable,Serializable> requestParam) throws Exception
{
ObjectMessage message = session.createObjectMessage(requestParam);
producer.send(message);
session.commit();
}
public static void main(String[] args) throws Exception{
RequestSubmit submit = new RequestSubmit();
submit.init();
HashMap<Serializable,Serializable> requestParam = new HashMap<Serializable,Serializable>();
requestParam.put("朱小厮", "zzh");
submit.submit(requestParam);
}
}
创建Session时有两个非常重要的參数,第一个boolean类型的參数用来表示是否採用事务消息。
假设是事务消息。对于的參数设置为true。此时消息的提交自己主动有comit处理,消息的回滚则自己主动由rollback处理。
增加消息不是事务的。则相应的该參数设置为false,此时分为三种情况:
- Session.AUTO_ACKNOWLEDGE表示Session会自己主动确认所接收到的消息。
- Session.CLIENT_ACKNOWLEDGE表示由client程序通过调用消息的确认方法来确认所接收到的消息。
- Session.DUPS_OK_ACKNOWLEDGE使得Session将“懒惰”地确认消息,即不会马上确认消息,这样有可能导致消息反复投递。
提供Java实现的基于ActiveMQ的请求处理:
package com.zzh.activemq;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class RequestProcessor
{
public void requestHandler(HashMap<Serializable,Serializable> requestParam) throws Exception
{
System.out.println("requestHandler....."+requestParam.toString());
for(Map.Entry<Serializable, Serializable> entry : requestParam.entrySet())
{
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
public static void main(String[] args) throws Exception
{
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://10.10.195.187:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("RequestQueue");
//消息消费(接收)者
MessageConsumer consumer = session.createConsumer(destination);
RequestProcessor processor = new RequestProcessor();
while(true)
{
ObjectMessage message = (ObjectMessage) consumer.receive(1000);
if(null != message)
{
System.out.println(message);
HashMap<Serializable,Serializable> requestParam = (HashMap<Serializable,Serializable>) message.getObject();
processor.requestHandler(requestParam);
}
else
{
break;
}
}
}
}
输出结果:
ActiveMQObjectMessage {commandId = 6, responseRequired = false, messageId = ID:hidden-PC-58748-1460550507055-1:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:hidden-PC-58748-1460550507055-1:1:1:1, destination = queue://RequestQueue, transactionId = TX:ID:hidden-PC-58748-1460550507055-1:1:1, expiration = 0, timestamp = 1460550507333, arrival = 0, brokerInTime = 1460550505969, brokerOutTime = 1460550509143, correlationId = null, replyTo = null, persistent = false, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@74a456bb, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false}
requestHandler.....{朱小厮=zzh}
朱小厮:zzh
能够通过页面查看队列的使用情况。在浏览器中输入http://10.10.195.187:8161/admin/queues.jsp。username和password都是:admin,看到以下页面:
这个是在jettyserver下跑的,能够改动conf/jetty.xml来改动相关jetty配置。
上面的样例是关于P2P模式的,只是有个不妥之处,就是没有资源的释放。
以下举一个Pub/Sub模式的。
通过JMS创建ActiveMQ的topic。并给topic发送消息:
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.Produce;
public class TopicRequest
{
//消息发送者
private MessageProducer producer;
//一个发送或者接受消息的线程
private Session session;
//Connection:JMSclient到JMS Provider的连接
private Connection connection;
public void init() throws Exception
{
//ConnectionFactory连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://10.10.195.187:61616");
//从构造工厂中得到连接对象
connection = connectionFactory.createConnection();
//启动
connection.start();
//获取连接操作
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("MessageTopic");
producer = session.createProducer(topic);
//设置不持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
}
public void submit(String mess) throws Exception
{
TextMessage message = session.createTextMessage();
message.setText(mess);
producer.send(message);
}
public void close()
{
try
{
if(session != null)
session.close();
if(producer != null)
producer.close();
if(connection !=null )
connection.close();
}
catch (JMSException e)
{
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception
{
TopicRequest topicRequest = new TopicRequest();
topicRequest.init();
topicRequest.submit("I'm first");
topicRequest.close();
}
}
消息发送到相应的topic后,须要将listener注冊到须要订阅的topic上,以便能够接收该topic的消息:
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class TopicReceive
{
private MessageConsumer consumer;
private Session session;
public void init() throws Exception
{
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://10.10.195.187:61616");
Connection connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
Topic topic = session.createTopic("MessageTopic");
consumer = session.createConsumer(topic);
consumer.setMessageListener(new MessageListener(){
@Override
public void onMessage(Message message)
{
TextMessage tm = (TextMessage) message;
System.out.println(tm);
try
{
System.out.println(tm.getText());
}
catch (JMSException e)
{
e.printStackTrace();
}
}
});
}
public static void main(String[] args) throws Exception
{
TopicReceive receive = new TopicReceive();
receive.init();
}
}
输出结果:
ActiveMQTextMessage {commandId = 5, responseRequired = false, messageId = ID:hidden-PC-50073-1460597487065-1:1:1:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:hidden-PC-50073-1460597487065-1:1:1:1, destination = topic://MessageTopic, transactionId = null, expiration = 0, timestamp = 1460597487308, arrival = 0, brokerInTime = 1460597487297, brokerOutTime = 1460597487298, correlationId = null, replyTo = null, persistent = false, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence@2e4d3abf, marshalledProperties = null, dataStructure = null, redeliveryCounter = 0, size = 0, properties = null, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = I'm first}
I'm first
參考文献
1. 《大型分布式站点架构——设计与实践》陈康贤著。
ActiveMQ简述的更多相关文章
- Sping+ActiveMQ整合
通过前一篇<ActiveMQ简述>大概对ActiveMQ有了一个大概的认识.本篇所阐述的是怎样通过Spring继承ActiveMQ进而更有效.更灵活的运用ActiveMQ. Spring和 ...
- Spring Boot 监听 Activemq 中的特定 topic ,并将数据通过 RabbitMq 发布出去
1.Spring Boot 和 ActiveMQ .RabbitMQ 简介 最近因为公司的项目需要用到 Spring Boot , 所以自学了一下, 发现它与 Spring 相比,最大的优点就是减少了 ...
- Java消息队列--ActiveMq 实战
1.下载安装ActiveMQ ActiveMQ官网下载地址:http://activemq.apache.org/download.html ActiveMQ 提供了Windows 和Linux.Un ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- (jms)ActiveMQ 安装配置.
前言 ActiveMQ他是Apache出品的一个JMS提供者,管理会话和队列,运行在JVM下,支持多种语言,如JAVA,C++,C#,应用协议: OpenWire,Stomp REST,WS Noti ...
- node(ActiveMq)
简单尝试了node下的ActiveMQ 1.下载apache-activemq-5.9.0,执行bat文件: 2.登录http://localhost:8161/admin可查看其管理后台: 3.安装 ...
- 简述 OAuth 2.0 的运作流程
本文将以用户使用 github 登录网站留言为例,简述 OAuth 2.0 的运作流程. 假如我有一个网站,你是我网站上的访客,看了文章想留言表示「朕已阅」,留言时发现有这个网站的帐号才能够留言,此时 ...
- JavaScript单线程和浏览器事件循环简述
JavaScript单线程 在上篇博客<Promise的前世今生和妙用技巧>的开篇中,我们曾简述了JavaScript的单线程机制和浏览器的事件模型.应很多网友的回复,在这篇文章中将继续展 ...
- ActiveMQ的集群方案对比及部署
转载:http://blog.csdn.net/lifetragedy/article/details/51869032 ActiveMQ的集群 内嵌代理所引发的问题: 消息过载 管理混乱 如何解决这 ...
随机推荐
- (六)if流程控制
(1)单分支结构 if 条件判断;then fi 例 #!/bin/bash read -p "please input Y" num if [ "$num" ...
- Django CRM查询(一对多,多对多以及相关的反查)
Customer模型: class Customer(models.Model): name = models.CharField(max_length=32) qq = models.CharFie ...
- fmod()函数和modf()函数
最近从博客上看到了一个fmod函数,结果又蹦出来一个modf函数 fmod()函数: 头文件:#include<math.h> C库函数... fmod()用来对浮点数进行取模(求余),原 ...
- Java的Hashtable类(转)
文章来源:http://blog.csdn.net/zhna123_2011/article/details/6741479 ps:直接copy 哈希表是一种重要的存储方式,也是一种常见的检索方法.其 ...
- System Center VMM请注意不同语言版本的差异
在私有云的项目中,经常需要判断System Center一些组件的连接是否OK. 我这里有开发,和测试两个环境,开发是英文版的System Center VMM,测试用的是中文版的System Cen ...
- CF 834B The Festive Evening【差分+字符串处理】
B. The Festive Evening time limit per test1 second memory limit per test256 megabytes inputstandard ...
- Django项目静态文件加载失败问题
在我们平时的开发过程中,为了方便调试程序,我们都是打开开发者模式,即Debug=True,当我们正式上线的时候肯定就需要把开发者模式关掉,用uwsgi部署上去以后,突然发现我们平时辛苦做的项目的静态文 ...
- 并查集【p1197】[JSOI2008]星球大战
Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治着整个星系. 某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通 ...
- 学习python网站
http://code.ziqiangxuetang.com/python/python-dictionary.html
- 【数论】【枚举约数】【欧拉函数】bzoj2705 [SDOI2012]Longge的问题
∵∑gcd(i, N)(1<=i <=N) =k1*s(f1)+k2*s(k2)+...+km*s(km) {ki是N的约数,s(ki)是满足gcd(x,N)=ki(1<=x< ...