queue与topic的技术特点对比
 

topic

queue

概要

Publish Subscribe messaging 发布订阅消息

Point-to-Point 点对点

有无状态

topic数据默认不落地,是无状态的。

Queue数据默认会在mq服务器上以文件形式保存,比如Active MQ一般保存在$AMQ_HOME\data\kr-store\data下面。也可以配置成DB存储。

完整性保障

并不保证publisher发布的每条数据,Subscriber都能接受到。

Queue保证每条数据都能被receiver接收。

消息是否会丢失

一般来说publisher发布消息到某一个topic时,只有正在监听该topic地址的sub能够接收到消息;如果没有sub在监听,该topic就丢失了。

Sender发送消息到目标Queue,receiver可以异步接收这个Queue上的消息。Queue上的消息如果暂时没有receiver来取,也不会丢失。

消息发布接收策略

一对多的消息发布接收策略,监听同一个topic地址的多个sub都能收到publisher发送的消息。Sub接收完通知mq服务器

一对一的消息发布接收策略,一个sender发送的消息,只能有一个receiver接收。receiver接收完后,通知mq服务器已接收,mq服务器对queue里的消息采取删除或其他操作。

Topic和queue的最大区别在于topic是以广播的形式,通知所有在线监听的客户端有新的消息,没有监听的客户端将收不到消息;而queue则是以点对点的形式通知多个处于监听状态的客户端中的一个。

queue 通讯:

消息提供者:

	 public static void main(String[] args) throws JMSException {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
//JMS 客户端到JMS Provider 的连接
Connection connection = connectionFactory.createConnection();
connection.start();
// Session: 一个发送或接收消息的线程
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
// Destination :消息的目的地;消息发送给谁.
// 获取session注意参数值my-queue是Query的名字
Destination destination = session.createQueue("my-queue");
//Destination destination = session.createTopic("my-topic");
// MessageProducer:消息生产者
MessageProducer producer = session.createProducer(destination);
//设置不持久化
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
//发送一条消息
sendMsg(session, producer);
session.commit();
connection.close();
} public static void sendMsg(Session session, MessageProducer producer) throws JMSException {
//创建一条文本消息
TextMessage message = session.createTextMessage("Hello ActiveMQ!");
//通过消息生产者发出消息
producer.send(message);
System.out.println(message.toString());
}

  消息接收者:

public static void main(String[] args) {
// ConnectionFactory :连接工厂,JMS 用它创建连接
ConnectionFactory connectionFactory;
// Connection :JMS 客户端到JMS Provider 的连接
Connection connection = null;
// Session: 一个发送或接收消息的线程
Session session;
// Destination :消息的目的地;消息发送给谁.
Destination destination;
// 消费者,消息接收者
MessageConsumer consumer;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
// 构造从工厂得到连接对象
connection = connectionFactory.createConnection();
// 启动
connection.start();
// 获取操作连接
session = connection.createSession(Boolean.FALSE,
Session.AUTO_ACKNOWLEDGE);
// 获取session注意参数值xingbo.xu-queue是一个服务器的queue,须在在ActiveMq的console配置
destination = session.createQueue("my-queue");
consumer = session.createConsumer(destination);
while (true) {
TextMessage message = (TextMessage) consumer.receive(1000);
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}

  Topic通讯:

广播提供者:

 private static final int SEND_NUMBER = 5;
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
for (int i = 1; i <=SEND_NUMBER; i++) {
TextMessage message = session
.createTextMessage("ActiveMq发送的消息" + i);
//发送消息到目的地方
System.out.println("发送消息:" + "ActiveMq 发送的消息" + i);
producer.send(message);
}
} public static void main(String[] args) {
// ConnectionFactory:连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection:JMS客户端到JMS Provider的连接
Connection connection = null;
// Session:一个发送或接收消息的线程
Session session;
// Destination:消息的目的地;消息发送给谁.
Destination destination;
// MessageProducer:消息发送者
MessageProducer producer;
// TextMessage message;
//构造ConnectionFactory实例对象,此处采用ActiveMq的实现jar
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnectionFactory.DEFAULT_USER,
ActiveMQConnectionFactory.DEFAULT_PASSWORD,ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL
);
try {
//构造从工厂得到连接对象
connection = connectionFactory.createConnection();
//启动
connection.start();
//获取操作连接
session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
//获取session注意参数值FirstTopic是一个服务器的topic(与queue消息的发送相比,这里是唯一的不同)
destination = session.createTopic("FirstTopic");
//得到消息生成者【发送者】
producer = session.createProducer(destination);
//设置不持久化,此处学习,实际根据项目决定
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
//构造消息,此处写死,项目就是参数,或者方法获取
sendMessage(session, producer);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}

  广播接收者:

   private String threadName;

    ReceiveTopic(String threadName) {
this.threadName = threadName;
} public void run() {
// ConnectionFactory:连接工厂,JMS用它创建连接
ConnectionFactory connectionFactory;
// Connection:JMS客户端到JMS Provider的连接
Connection connection =null;
// Session:一个发送或接收消息的线程
Session session;
// Destination:消息的目的地;消息发送给谁.
Destination destination;
//消费者,消息接收者
MessageConsumer consumer;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnectionFactory.DEFAULT_USER,
ActiveMQConnectionFactory.DEFAULT_PASSWORD,ActiveMQConnectionFactory.DEFAULT_BROKER_BIND_URL);
try {
//构造从工厂得到连接对象
connection = connectionFactory.createConnection();
//启动
connection.start();
//获取操作连接,默认自动向服务器发送接收成功的响应
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//获取session注意参数值FirstTopic是一个服务器的topic
destination = session.createTopic("FirstTopic");
consumer = session.createConsumer(destination);
while (true) {
//设置接收者接收消息的时间,为了便于测试,这里设定为100s
TextMessage message = (TextMessage) consumer
.receive(1 * 1000);
if (null != message) {
System.out.println("线程"+threadName+"收到消息:" + message.getText());
} else {
continue;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
} public static void main(String[] args) {
//这里启动3个线程来监听FirstTopic的消息,与queue的方式不一样三个线程都能收到同样的消息
ReceiveTopic receive1=new ReceiveTopic("thread1");
ReceiveTopic receive2=new ReceiveTopic("thread2");
ReceiveTopic receive3=new ReceiveTopic("thread3");
Thread thread1=new Thread(receive1);
Thread thread2=new Thread(receive2);
Thread thread3=new Thread(receive3);
thread1.start();
thread2.start();
thread3.start();
}

  如果传输中文:可以设置字符串的编码格式new String(msg.getBytes("utf-8"),"ISO-8859-1");  new String(message.toString().getBytes("ISO-8859-1"), "UTF-8");

activemq demo指南的更多相关文章

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

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

  2. ActiveMQ demo

    Maven 配置文件 <dependency> <groupId>org.apache.activemq</groupId> <artifactId>a ...

  3. ActiveMQ - 入门指南

    首先需要下载ActiveMQ,下面的链接给我们列出了所有版本: http://activemq.apache.org/download-archives.html 每个版本为不同的OS提供了链接: 公 ...

  4. 消息中间件系列一:入门、JMS规范、ActiveMQ使用

    一.入门 1. 消息中间件的定义 没有标准定义,一般认为,采用消息传送机制/消息队列 的中间件技术,进行数据交流,用在分布式系统的集成 2. 为什么要用消息中间件 解决分布式系统之间消息的传递.电商场 ...

  5. ActiveMQ 集群配置 高可用

    自从activemq5.9.0开始,activemq的集群实现方式取消了传统的Pure Master Slave方式,增加了基于zookeeper+leveldb的实现方式,其他两种方式:目录共享和数 ...

  6. activemq 实战 四 传输连接器-Transport connectors 4.2

    In order to exchange messages, producers and consumers (clients) need to connect to the broker. This ...

  7. 消息队列之 ActiveMQ(山东数漫江湖)

    简介 ActiveMQ 特点 ActiveMQ 是由 Apache 出品的一款开源消息中间件,旨在为应用程序提供高效.可扩展.稳定.安全的企业级消息通信. 它的设计目标是提供标准的.面向消息的.多语言 ...

  8. Spring和ActiveMQ集成实现队列消息以及PUB/SUB模型

    前言:本文是基于Spring和ActiveMQ的一个示例文章,包括了Point-To-Point的异步队列消息和PUB/SUB(发布/订阅)模型,只是做了比较简单的实现,无任何业务方面的东西,作为一个 ...

  9. java之消息队列ActiveMQ实践

    原创论文:https://www.cnblogs.com/goujh/p/8510239.html 消息队列的应用场景: 消息队列应用场景 异步处理,应用解耦,流量削锋和消息通讯四个场景 异步处理: ...

随机推荐

  1. HDU 5716 带可选字符的多字符串匹配(ShiftAnd)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5716 [题目大意] 给出一个字符串,找出其中所有的符合特定模式的子串位置,符合特定模式是指,该子串 ...

  2. Pascal 线段树 lazy-tag 模板

    先说下我的代码风格(很丑,勿喷) maxn表示最大空间的四倍 tree数组表示求和的线段树 delta表示增减的增量标记 sign表示覆盖的标记 delta,sign实际上都是lazy标志 pushd ...

  3. qt 5.1.1 on CentOS 6.4

    Overview If you are trying to install Qt and Qwt [qwt.sourceforge.net] (Qt Widgets for Technical App ...

  4. 使用AFNetworking请求新浪微博数据接口出错解决办法

    在使用AFNetworking请求新浪微博数据接口时会出这样的错误,如 这样的错误说明,AFNetworking无法处理这样的数据格式.所以,我们需要修改AFNetworking中的一些接收数据格式. ...

  5. 轻轻谈一下seaJs——模块化开发的利器

    "仅做一件事,做好一件事." 这个应该就是seaJs的精髓了. 我在自己的一些项目中使用过seaJs.对其算是了解一二.如今就班门弄斧.轻轻地谈一下. 首先上一段度娘的话: &qu ...

  6. oracle超过最大游标数异常分析(转贴)

    问题描述 Oracle 使用 OPEN_CURSORS 参数指定一个会话一次最多可以打开的游标的数量.超过此数量时,Oracle 将报告 ORA-01000 错误.当此错误传播到 WebLogic S ...

  7. validate 表单验证

    转自博客园:http://www.cnblogs.com/easyinsc/archive/2009/02/27/1407826.html (1)required:true               ...

  8. hive 使用脚本清洗数据:时间戳转日期

    import sys import datetime for line in sys.stdin: line = line.strip() userid, movieid, rating, unixt ...

  9. PHP学习遇到的问题

    使用php ob_start()模板生成html 内容无法撑开 生成后主要的内容 <body><warp><main> 生成后这个几个节点总是固定大小,不能被内容撑 ...

  10. [转]printf 函数实现的深入剖析

    研究printf的实现,首先来看看printf函数的函数体 int printf(const char *fmt, ...) { int i; char buf[256];          va_l ...