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. Django Web开发学习笔记(4)

    第四章 模板篇 上一章的内容,我们将HTML的代码和Python代码都混合在了在view.py的文件下.但是这样做的坏处无疑是明显的,引用DjangoBook的说法: 对页面设计进行的任何改变都必须对 ...

  2. OpenLayers 官网例子的中文详解

    https://segmentfault.com/a/1190000009679800?utm_source=tag-newest 当你希望实现某种功能的时候,即使你对 openlayers 几乎一窍 ...

  3. SQL SERVER 行列转换(动态)

    行转列测试数据: --测试数据 if not object_id(N'Tempdb..#T') is null drop table #T Go Create table #T([Name] nvar ...

  4. django admin list_filter的使用

    一.举例 class CategoryTreeRelatedFieldListFilter(admin.SimpleListFilter): title = _('课程章节') parameter_n ...

  5. InstallShield:卸载时文字叠加,文字乱码

    问题: InstallShield2010打包的程序.如果程序正在运行,卸载程序,提示关闭程序,然后消息界面出现文字叠加. 定位问题: 新建Installshield项目,依次修改SetupType, ...

  6. Java四类八种数据类型

    http://www.cnblogs.com/simplefrog/archive/2012/07/15/2592011.html 第一类:逻辑型boolean 第二类:文本型char 第三类:整数型 ...

  7. MySQL的binlog日志<转>

    binlog 基本认识 MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日 ...

  8. 解决:github上传时出现error: src refspec master does not match any

    原因分析 引起该错误的原因是,目录中没有文件,空目录是不能提交上去的 解决方法 touch README git add README git commit -m 'first commit' git ...

  9. Vue获取DOM元素的属性值

    项目中需要做一个小弹层,如下图: 我需要知道点击元素距离顶部的值,再计算弹层的top值,如下图: 在vue中如何获取到DOM元素距离窗口顶部的值呢? 1.通过$event获取 html: <di ...

  10. const读书笔记

    Const 的使用读书笔记 Const的主要主要用法有: 常变量: const 类型说明符 变量名 常引用: const 类型说明符 &引用名  常对象: 类名 const 对象名 常成员函数 ...