JMS组件:activemq(慢)
AMQP组件(advance message queue protocol):rabbitmq和kafka

一.、消息队列解决了什么问题?
异步处理
应用解耦
流量削锋
日志处理

二、rabbitmq安装与配置

三、java操作rabbitmq
1. simple 简单队列
2. work queues 工作队列 公平分发 轮询分发
3. publish/subscribe 发布于订阅
4. routing 路由选择 通配符模式
5. topics 主题
6. 手动和自动确认消息
7. 队列的持久化和非持久化
8. rabbitmq的延迟队列

四、spring AMQP spring-rabbitmq

五、场景demo mq实现搜索引擎DIH增量

六、场景demo 未支付订单30分钟,取消

七、大数据应用 类似百度统计 cnzz架构 消息队列

一、简单队列

ConnectionUtils.java

 public class ConnectionUtils {
public static Connection getConnection() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort();
factory.setVirtualHost("/vhost_mmr");
factory.setUsername("cxx");
factory.setPassword("cxx");
return factory.newConnection();
}
}

Send.java

 /**
* 生产者发送消息
*/
public class Send { private static final String QUEUE_NAME = "test_simple_queue"; public static void main(String[] args) throws IOException, TimeoutException {
Connection connection = ConnectionUtils.getConnection(); Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null); String msg = "hello simple!!!!!!!!!!!";
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
System.out.println("--send msg;" + msg);
channel.close();
connection.close();
}
}

Receive.java

 /**
* 消费者获取消息
*/
public class Receive { private static final String QUEUE_NAME = "test_simple_queue"; public static void main(String[] args) throws IOException, TimeoutException {
//获取链接
Connection connection = ConnectionUtils.getConnection();
//创建通道
Channel channel = connection.createChannel();
//队列声明
channel.queueDeclare(QUEUE_NAME, false, false, false, null); DefaultConsumer consumer = new DefaultConsumer(channel) {
//获取到达的消息
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
super.handleDelivery(consumerTag, envelope, properties, body);
String msg = new String(body, "utf-8");
System.out.println("new api recv:" + msg);
}
}; //监听队列
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}

二、工作队列

2.1 轮询分发

Send.java

 /**
* \---c1
* p---Queue----\
* \---c2
*/
public class Send {
private static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//获取链接
Connection connection = ConnectionUtils.getConnection();
//获取channel
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
for (int i = 0; i < 50; i++) {
String msg = "hello" + i; System.out.println("[WQ ] send:" + msg);
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
Thread.sleep(i * 20);
}
channel.close();
connection.close();
}
}

Receive1.java

 public class Receive1 {
public static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException {
//创建链接
Connection connection = ConnectionUtils.getConnection();
//创建频道
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[1] Recv msg :" + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done");
}
}
};
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}

Receive2.java

 public class Receive2 {
public static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException {
//创建链接
Connection connection = ConnectionUtils.getConnection();
//创建频道
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[2] Recv msg :" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done");
}
}
};
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}

现象:消费者1和消费者2处理的消息是一样的

消费者1偶数

消费者1奇数

这种方式叫做轮询分发(round-robin),结果就是不管谁忙活着谁清闲,都不会多给一个消息,任意消息总是你一个,我一个

2.2 公平分发(fair dipatch)

Send.java

 /**
* \---c1
* p---Queue----\
* \---c2
*/
public class Send {
private static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//获取链接
Connection connection = ConnectionUtils.getConnection();
//获取channel
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
/**
* 每个消费者发送消费之前,消息队列不发送下一个消息到消费者,一次只处理一个消息
* 限制发送给同一个消费者不得超过一个消息
*/
int prefetchCount = 1;
channel.basicQos(prefetchCount); for (int i = 0; i < 50; i++) {
String msg = "hello" + i; System.out.println("[WQ ] send:" + msg);
channel.basicPublish("", QUEUE_NAME, null, msg.getBytes());
Thread.sleep(i * 5);
}
channel.close();
connection.close();
}
}

Receive1.java

 public class Receive1 {
public static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException {
//创建链接
Connection connection = ConnectionUtils.getConnection();
//创建频道
final Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//保证一次只发送一个
channel.basicQos(1); //定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[1] Recv msg :" + msg);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[1] done");
//手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}

Receive2.java

 public class Receive2 {
public static final String QUEUE_NAME = "test_work_queue"; public static void main(String[] args) throws IOException, TimeoutException {
//创建链接
Connection connection = ConnectionUtils.getConnection();
//创建频道
final Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//保证一次只发送一个
channel.basicQos(1);
//定义一个消费者
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body, "utf-8");
System.out.println("[2] Recv msg :" + msg);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("[2] done");
//手动回执
channel.basicAck(envelope.getDeliveryTag(), false);
}
}
};
boolean autoAck = false;
channel.basicConsume(QUEUE_NAME, autoAck, consumer);
}
}

现象:消费者2处理的消息比消费者1多,能者多劳

三、消息与应答ack与消息持久化durable

boolean autoAck = false;

channel.basicConsume(QUEUE_NAME, autoAck, consumer);

boolean autoAck = true;(自动确认模式)一旦rabbitmq将消息分发给消费者,就会从内存中删除

这种情况下,如果杀死正在执行的消费者,就会丢失正在处理的消息

boolnea autoAck = false;(手动模式),如果有一个消费者挂掉,就会交付给其他消费者,

rabbitmq支持消息应答,消费者发送一个应答,告诉rabbitmq这个消息我已经处理完成,你可以删除了,然后rabbitmq就删除

内存中的消息

消息应答模式是打开的,false

Message acknowkedgment

消息持久化

boolean durable = false
channel.queueDeclare(QUEUE_NAME, durable, false, false, null);

rabbitmq简单实例的更多相关文章

  1. PHP 下基于 php-amqp 扩展的 RabbitMQ 简单用例 (四) -- Push API 和 Pull API

    RabbitMQ 中针对消息的分发提供了 Push API (订阅模式) 和 Pull API (主动获取) 两种模式. 在 PHP 中, 这两种模式分别通过 AMQPQueue 类中的 consum ...

  2. Hibernate(二)__简单实例入门

    首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...

  3. 最新 Eclipse IDE下的Spring框架配置及简单实例

    前段时间开始着手学习Spring框架,又是买书又是看视频找教程的,可是鲜有介绍如何配置Spring+Eclipse的方法,现在将我的成功经验分享给大家. 本文的一些源代码来源于码农教程:http:// ...

  4. Spring Rabbitmq HelloWorld实例

    之前的博客和大家分享了Rabbitmq的基本框架,及其工作原理,网址为 < http://www.cnblogs.com/jun-ma/p/4840869.html >.今天呢,想和大家一 ...

  5. 修改js confirm alert 提示框文字的简单实例

    修改js confirm alert 提示框文字的简单实例: <!DOCTYPE html> <html> <head lang="en"> & ...

  6. 利用navicat创建存储过程、触发器和使用游标的简单实例

    利用navicat创建存储过程.触发器和使用游标的简单实例 标签: navicat存储过程触发器mysql游标 2013-08-03 21:34 15516人阅读 评论(1) 收藏 举报  分类: 数 ...

  7. 【转】Android Https服务器端和客户端简单实例

    转载地址:http://blog.csdn.net/gf771115/article/details/7827233 AndroidHttps服务器端和客户端简单实例 工具介绍 Eclipse3.7 ...

  8. Centos7的安装、Docker1.12.3的安装,以及Docker Swarm集群的简单实例

    目录 [TOC] 1.环境准备 ​ 本文中的案例会有四台机器,他们的Host和IP地址如下 c1 -> 10.0.0.31 c2 -> 10.0.0.32 c3 -> 10.0.0. ...

  9. vue路由的简单实例

    vue2.0 和 vue1.0 路由的语法还是有点稍微的差别,下面介绍一下vue-router 2的简单实例: <!DOCTYPE html> <html lang="en ...

随机推荐

  1. C++中 线程函数为静态函数 及 类成员函数作为回调函数

    线程函数为静态函数: 线程控制函数和是不是静态函数没关系,静态函数是在构造中分配的地址空间,只有在析构时才释放也就是全局的东西,不管线程是否运行,静态函数的地址是不变的,并不在线程堆栈中static只 ...

  2. Mac下必备快捷键的符号所对应的按键

    Mac下快捷键的符号所对应的按键 ⌥—> option|alt ⇧—>shift ⌃—>control ⌘—>command ⎋—>esc 注: 与F6/F7/F12等F ...

  3. [Aaronyang] 写给自己的WPF4.5 笔记8[复杂数据处理三步曲,数据视图精讲1/3]

    真的好累了 ,笑了.做回自己吧       -------------      Aaronyang技术分享 www.ayjs.net 博文摘要: 详细介绍了WPF中视图的种类和开始学之前的准备工作 ...

  4. Atitit 错误处理机制:(1)静默模式(2)警告模式 (3)异常模式

    Atitit 错误处理机制:(1)静默模式(2)警告模式 (3)异常模式       三.     PDO的错误处理机制: (1)静默模式 默认情况下与mysql处理方式一致,不现实错误信息(静默模式 ...

  5. [Big Data - ZooKeeper] ZooKeeper: A Distributed Coordination Service for Distributed Applications

    ZooKeeper ZooKeeper: A Distributed Coordination Service for Distributed Applications Design Goals Da ...

  6. rc.d/rc.local 自动启 tomcat 启不来

    针对自己配置的JDK环境有可能会出现这样的情况. tomcat能启来.但自启动就不行,原因 JDK是后安装的,环境变量配置在 /etc/profile 里面. tomcat 配了自启动.但reboot ...

  7. STM32 ADC 采样 频率的确定

    一 STM32 ADC 采样频率的确定 1.       : 先看一些资料,确定一下ADC 的时钟: (1),由时钟控制器提供的ADCCLK 时钟和PCLK2(APB2 时钟)同步.CLK 控制器为A ...

  8. 看雪CTF第十五题

    1.直接运行起来,再用OD附加 在此处luajit加载并调用main函数 004021C7 E8 64FE0000 call CrackMe. ; luaL_newstate 004021CC 8BF ...

  9. 3D点云的深度学习

    使用卷积神经网络(CNN)架构的深度学习(DL)现在是解决图像分类任务的标准解决方法.但是将此用于处理3D数据时,问题变得更加复杂.首先,可以使用各种结构来表示3D数据,所述结构包括: 1  体素网格 ...

  10. 【转】xhEditor技术手册 网页编辑器基础教程

    1. xhEditor入门基础 1.1. 在线可视化HTML编辑器概述1.2. 获取xhEditor1.3. xhEditor运行环境1.4. xhEditor基本使用指南 1.1. 在线可视化HTM ...