一、适用场景

1.解耦
2.最终一致性
3.广播
4.错峰与流控(秒杀业务用于流量削峰场景)

秒杀场景

二、核心组件,关键点(交换器、队列、绑定)

AMPQ消息路由必要三部分:交换器、队列、绑定。

Java核心组件:ConnectionFactory、Connection、Channel、Delivery、DeliverCallback、CancelCallback

队列

1. 建立连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("127.0.0.1");
factory.setPort(5672);
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
2. 声明队列

如果在同一条信道上订阅了另一个队列,那就不能再声明队列,必须先取消订阅。

Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map<String, Object> arguments) throws IOException;

queue:需要指定队列名称,如果不指定,MQ会随机分配一个并在queue.declare命令中返回,

durable:队列将在服务器重启后存在。

exclusive:为true时,队列变成私有的。

autoDelete: 为true时,当最后一个消费者取消订阅时,队列自动移除。

3. 消费者通过AMQP的basic.consume命令订阅消息,将信道置为接收模式。

Java代码Channel:

String basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback) throws IOException;
4. 当有多个消费者存在时,队列里的消息将以循环的方式发送给消费者。消费者接收到消息后必须进行确认,可通过basic.ack显示确认:

Java代码Channel:

void basicAck(long deliveryTag, boolean multiple) throws IOException;

上面的手动确认,第二个参数为true,批量确认;如果为false,会一次确认一条。当有耗时任务时,可以利用手动确认延迟确认消息,防止消息大量涌入应用导致过载。

也可以在订阅队列时就将basicConsume方法的autoAck参数设置为true,开启自动确认。确认成功后rabbitmq会从队列中删除消息。

5. 如果在确认过程中和rabbitmq服务器断链,那么这条消息就会发送给下一个消费者。可以使用basic.reject拒绝消息:

Java代码Channel:

void basicReject(long deliveryTag, boolean requeue) throws IOException;

第二个参数requeue设置为true,消息会重新排队并发送给下一个消费者;为false则会丢弃该条消息。可以利用此性质丢弃错误格式的消息。

6. 发布消息
void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;

exchange:第一个参数是交换的名称。空字符串表示默认或无名交换,消息通过routingKey路由到指定队列。

交换器和绑定

1. 交换器一共有四种类型:fanout、direct 、topic、headers。

Java中Channel申明交换器:

Exchange.DeclareOk exchangeDeclare(String exchange, BuiltinExchangeType type) throws IOException;

BuiltinExchangeType对应有四种枚举类型:

DIRECT("direct"), FANOUT("fanout"), TOPIC("topic"), HEADERS("headers");
2. 队列通过路由键(routing key)绑定到交换器。
channel.queueBind(String queue, String exchange, String routingKey)

RabbitMQ中消息传递模型的核心思想是生产者永远不会将任何消息直接发送到队列。实际上,生产者甚至不知道消息是否会被传递到哪个队列。

不指定队列名时,通过服务器随机生成队列名称:

String queueName = channel.queueDeclare().getQueue();

不传参数时,queueDeclare生成一个非持久的,独占的自动删除队列

在linux服务器上可以通过命令查看所有交换器:

rabbitmqctl list_exchanges
3. fanout广播方式

广播方式会将消息投递给所有附加在此交换器的队列。

4. direct模式

direct类型在绑定时设定一个routing_key,消息的routing_key匹配时, 才会被交换器投递到绑定的队列中去.

5. topic模式

按规则投递,通过通配符#和*组合

*(星号)可以替代一个单词。

(hash)可以替换零个或多个单词。

持久化

将队列和交换器的durable属性设置为true

申明队列时:

channel.queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map<String, Object> arguments) throws IOException;

申明交换器时:

channel.exchangeDeclare(String exchange, BuiltinExchangeType type, boolean durable) throws IOException;

投递消息时将投递模式(delivery mode)设置为2,Java代码中MessageProperties.PERSISTENT_TEXT_PLAIN来设置:

channel.basicPublish(EXCHANGE_NAME, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes("UTF-8"));

在MessageProperties源码中如下所示:

/** Content-type "text/plain", deliveryMode 2 (persistent), priority zero */
public static final BasicProperties PERSISTENT_TEXT_PLAIN =
new BasicProperties("text/plain",
null,
null,
2,
0, null, null, null,
null, null, null, null,
null, null);

实现事务功能(发送方确认)

使用事务会使rabbitmq的性能大大降低,为了避免这个问题,rabbitmq支持:发送方确认模式。通过这个模式来保证消息的投递。当生产者P投递消息后会等待消费者C发送确认,P收到确认后可以调用回调函数处理相关业务。在生产者P等待确认的同时也可以继续发送下一条消息。

服务器管理

1、虚拟主机vhost

rabbitmq支持创建虚拟主机,默认的虚拟主机为“/”,默认用户guest;当在rabbitmq集群中创建虚拟主机时,整个集群都会创建。

2、错误日志查看

rabbitmq的日志文件在/var/log/rabbitmq/下的rabbit@[localhost].log

3、rabbitmq配置文件

配置文件在rpm安装/usr/share/doc/rabbitmq-server-3.6.5/rabbitmq.config.example,复制一份:

cp /usr/share/doc/rabbitmq-server-3.5.3/rabbitmq.config.example /etc/rabbitmq.config

参考官网配置:https://www.rabbitmq.com/configure.html#configuration-file

三、底层原理,主要实现

应用程序和rabbitmq服务器之间建立一条tcp连接,tcp连接打开后,应用程序就可以和rabbitmq创建多条AMQP信道,信道是建立在tcp连接上的虚拟连接。

四、同类技术产品比较

1.ActiveMQ

优点

单机吞吐量:万级

topic数量都吞吐量的影响:

时效性:ms级

可用性:高,基于主从架构实现高可用性

消息可靠性:有较低的概率丢失数据

功能支持:MQ领域的功能极其完备

缺点:

官方社区现在对ActiveMQ 5.x维护越来越少,较少在大规模吞吐的场景中使用。

2.Kafka

号称大数据的杀手锏,谈到大数据领域内的消息传输,则绕不开Kafka,这款为大数据而生的消息中间件,以其百万级TPS的吞吐量名声大噪,迅速成为大数据领域的宠儿,在数据采集、传输、存储的过程中发挥着举足轻重的作用。

Apache Kafka它最初由LinkedIn公司基于独特的设计实现为一个分布式的提交日志系统( a distributed commit log),之后成为Apache项目的一部分。

目前已经被LinkedIn,Uber, Twitter, Netflix等大公司所采纳。

优点

性能卓越,单机写入TPS约在百万条/秒,最大的优点,就是吞吐量高。

时效性:ms级

可用性:非常高,kafka是分布式的,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用

消费者采用Pull方式获取消息, 消息有序, 通过控制能够保证所有消息被消费且仅被消费一次;

有优秀的第三方Kafka Web管理界面Kafka-Manager;

在日志领域比较成熟,被多家公司和多个开源项目使用;

功能支持:功能较为简单,主要支持简单的MQ功能,在大数据领域的实时计算以及日志采集被大规模使用

缺点:

Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长

使用短轮询方式,实时性取决于轮询间隔时间;

消费失败不支持重试;

支持消息顺序,但是一台代理宕机后,就会产生消息乱序;

社区更新较慢;

3.RabbitMQ

RabbitMQ 2007年发布,是一个在AMQP(高级消息队列协议)基础上完成的,可复用的企业消息系统,是当前最主流的消息中间件之一。

RabbitMQ优点:

由于erlang语言的特性,mq 性能较好,高并发;

吞吐量到万级,MQ功能比较完备

健壮、稳定、易用、跨平台、支持多种语言、文档齐全;

开源提供的管理界面非常棒,用起来很好用

社区活跃度高;

RabbitMQ缺点:

erlang开发,很难去看懂源码,基本职能依赖于开源社区的快速维护和修复bug,不利于做二次开发和维护。

RabbitMQ确实吞吐量会低一些,这是因为他做的实现机制比较重。

需要学习比较复杂的接口和协议,学习和维护成本较高。

4.RocketMQ

RocketMQ出自 阿里公司的开源产品,用 Java 语言实现,在设计时参考了 Kafka,并做出了自己的一些改进。

RocketMQ在阿里集团被广泛应用在订单,交易,充值,流计算,消息推送,日志流式处理,binglog分发等场景。

RocketMQ优点:

单机吞吐量:十万级

可用性:非常高,分布式架构

消息可靠性:经过参数优化配置,消息可以做到0丢失

功能支持:MQ功能较为完善,还是分布式的,扩展性好

支持10亿级别的消息堆积,不会因为堆积导致性能下降

源码是java,我们可以自己阅读源码,定制自己公司的MQ,可以掌控

RocketMQ缺点:

支持的客户端语言不多,目前是java及c++,其中c++不成熟;

社区活跃度一般

没有在 mq 核心中去实现JMS等接口,有些系统要迁移需要修改大量代码

github代码

https://github.com/LighterTang/RabbitMQUtils/tree/master/rabbitmq_base/src/main/java/com/mq/mqutils/mqdoc

参考资料

https://www.rabbitmq.com

http://youzhixueyuan.com/comparison-of-kafka-rocketmq-rabbitmq.html

RabbitMQ核心组件及应用场景的更多相关文章

  1. RabbitMQ学习2---使用场景

    RabbitMQ主页:https://www.rabbitmq.com/ AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Serve ...

  2. RabbitMQ 6种应用场景

    http://www.rabbitmq.com/getstarted.html官网 最近业务需要使用Rabbitmq工作队列实现任务的负载分发 1.1.什么是RabbitMQ? RabbitMQ是实现 ...

  3. RabbitMQ 简介以及使用场景

    目录 一. RabbitMQ 简介 二. RabbitMQ 使用场景 1. 解耦(为面向服务的架构(SOA)提供基本的最终一致性实现) 2. 异步提升效率 3. 流量削峰 三. 引入消息队列的优缺点 ...

  4. springboot rabbitmq 死信队列应用场景和完整demo

    何为死信队列? 死信队列实际上就是,当我们的业务队列处理失败(比如抛异常并且达到了retry的上限),就会将消息重新投递到另一个Exchange(Dead Letter Exchanges),该Exc ...

  5. RabbitMQ延时队列应用场景

    应用场景 我们系统未付款的订单,超过一定时间后,需要系统自动取消订单并释放占有物品 常用的方案 就是利用Spring schedule定时任务,轮询检查数据库 但是会消耗系统内存,增加了数据库的压力. ...

  6. 使用RabbitMQ实现延迟任务----实用场景

    1. 使用RabbitMQ实现延迟任务

  7. RabbitMQ的几种典型使用场景

    RabbitMQ主页:https://www.rabbitmq.com/ AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Serve ...

  8. 【RabbitMQ】1、RabbitMQ的几种典型使用场景

    RabbitMQ主页:https://www.rabbitmq.com/ AMQP AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现.它主要包括以下组件: 1.Serve ...

  9. RabbitMQ的特点与应用场景(二)

      1.RabbitMQ的主要特点 (1)可靠性:RabbitMQ可通过队列持久化,交换机持久化,消息持久化及ACK回应等机制保证可靠性 (2)支持多种语言与协议:RabbitMQ几乎支持所有的编程语 ...

随机推荐

  1. AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)

    首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...

  2. Jarvis OJ-level3

    使用ret2libc攻击方法绕过数据执行保护 from pwn import* conn = remote("pwn2.jarvisoj.com",9879) elf = ELF( ...

  3. cocos2d popSceneWithTransition()方法

    要在CCDirector.h中增加如下方法: template <typename T> void popSceneWithTransition(float t) { CCASSERT(_ ...

  4. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...

  5. perl学习笔记之:模式匹配,模块,文档

    Perl语言的最大特点,也是Perl作为CGI首选语言的最大特点,是它的模式匹配操作符.Perl语言的强大的文本处理能力正是通过其内嵌的对模式匹配的支持体现的.模式通过创建正则表达式实现.Perl的正 ...

  6. Python基础:列表(list)和元组(tuple)

    学一门语言,可以用对比其他语言方法加深对这门语言特点的理解. 一.定义:列表和元组,都是一个可以放置任意数据类型的有序集合. mutable的列表:动态的,可以改变元素 immutable的元组:静态 ...

  7. Python之写入文件(1)

    一.写入文件 保存数据也是在各个编程语言中常用的操作,将数据写入到文件中是常用的操作,你可以将程序运行中的一些临时输出保存至文件中,以便后续打开文件查看,也可以把这些文件读入程序中来操作其中的数据. ...

  8. 俯瞰spring

    [简化Java开发] 基于POJO的轻量级和最小入侵性编程: 通过依赖注入和面向接口实现松耦合: 基于切面和惯例进行声明式编程: 通过切面和模板减少样板代码: [容纳你的bean] 容器是spring ...

  9. Knockout v3.4.0 中文版教程-1-入门和安装

    英文原版教程:http://knockoutjs.com/documentation/introduction.html 注:此教程根据英文原版翻译,仅作练习,如有不足或错误,请指正 说明: 对原文中 ...

  10. 【05】project board

    GitHub 上的 project board 我总是用 Jira 做大项目,独立项目用 Trello,这两者我都很喜欢. 后来我知道,GitHub 也有类似的 project board: 我个人为 ...