为什么要使用消息中间件

案例:假如我们开发了一个商品抢购网站。这个网站的目的就是在某一时间点进行抢购商品,同时要求用户注册,在注册的时候会同时给用户电话和邮箱中发送验证码,以便完成信息注册。传统做法应该是这样的。两种方式,并行即启用两个线程,当用户提交信息后,分别去发送邮件和发送短信。这种方式很明显比串行的方式更快。当我们加入消息队列后,处理方式如下图:

加入消息中间件后,我们只需要注册信息存库后,给消息队列中添加一条消息就完事了。然后邮件服务和短信服务分别去消费消息即可。

当用户注册完成后,到了抢购商品的时间,大家都去抢购某个商品的时候这个量很大。消息队列可以设置队列长度来保证系统的稳定性。当队列满了的时候,则不再处理这些用户请求。

因此我们可以总结一下消息队列的特点:

  1. 异步处理 -- 用户注册信息提交后,直接返回响应。然后邮件服务和短信服务监听到队列有消息后去主动处理
  2. 应用解耦 -- 用户注册流程分成了三个服务,注册服务、邮件服务、短信服务互不干扰。
  3. 流量削峰 -- 控制用户请求,以防系统奔溃。

常见消息中间件介绍

ActiveMQ:apache出品,能力强劲的开源消息总线,完全支持jms规范的消息中间件。api丰富,在传统行业的中小型企业中应用广泛。缺点:服务性能和数据存储性能不好。

Kafka:apache顶级项目,追求高吞吐量。一开始的目的是用于日志收集和传输。不支持事务,对消息重复,丢失,错误没有严格的请求。适合产生大量数据的互联网服务的数据收集业务。

RocketMQ:阿里开源中间件,目前已孵化成apache顶级项目,纯java开发,思路起源于kafka,对消息的可靠性传输和事务性做了优化。特点:高吞吐量、高可用。适合大规模分布式系统应用。目前在阿里集团被广泛使用,用于交易、充值,流计算,日志处理,消息推送等。现在推出了商业版,有些功能对外不开发。

RabbitMQ:是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用ErLang语言来编写的,并且基于AMQP协议。erlang语言开发,性能较好,高并发。社区活跃度高,网上资料比较多。

什么是AMQP协议

AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一个进程间传递异步消息网络协议

涉及到的具体概念:

  • server - 又称broker,接收客户端的链接,实现amqp实体服务。
  • Connection - 链接,应用程序跟broker的网络链接。
  • channel - 网络信道,几乎所有的操作都是在channel中进行,数据的流转都要在channel上进行。channel是进行消息读写的通道。客户端可以建立多个channel,每个channel代表一个会话任务。
  • message - 消息,服务器与应用程序之间传送的数据。由properties和body组成。properties可以对消息进行修饰,比如消息的升级,延迟等高级特性。body就是消息体的内容。
  • virtual host - 虚拟主机,用于进行逻辑隔离,最上层的消息路由,一个虚拟地址里面可以有多个交换机。exchange和消息队列message quene。
  • exchange - 交换机,接收消息,根据路由器转发消息到绑定的队列。
  • binding - 绑定,交换机和队列之间的虚拟链接,绑定中可以包含routing key。
  • routing key - 一个路由规则,虚拟机可以用它来确定如何路由一个特定消息。
  • quene - 消息队列,保存消息并将它们转发给消费者。

详细了解AMQP协议可参考这篇文章--------详解AMQP协议

交换机简单介绍

exchange:接收消息,并根据路由键转发消息所绑定的队列。

交换机的属性:

name:交换机的名称

type:交换机的类型direct,topic,fanout,headers

durability:是否需要持久化,true为持久化。

auto delete:当最后一个绑定到exchange上的队列删除后,自动删除该exchange。

internal:当前exchange是否用于rabbitMQ内部使用,默认为false。

arguments:可扩展参数。用户自自定义的交换机时,用到的参数。

交换机常用的类型为direct,topic,fanout。headers不常用。

direct(直连交换机):

  1. 所有发送到directExchange的消息被转发到RouteKey中指定的Queue

  2. rabbitmq有一个自带的exchange叫default exchange,这个交换机是direct类型的。rabbitmq会让路由键跟队列名相等进行绑定。

topic(主题交换机):

  1. 所有发送到topic exchange的消息被转发到所有关心RouteKey的Queue上

  2. Exchange将RouteKey和某些队列进行模糊匹配,此时队列需要绑定一个Topic

模糊匹配可以使用通配符:

#可以匹配一个或多个词

*只能匹配一个词

比如:"log.#"可以匹配到“log.info.oa”。“log.*”只会匹配到“log.error”

Fanout(扇型交换机):

  1. 不处理路由键,只需要简单的将队列绑定到交换机上。

  2. 发送到交换机的消息都会被转发到与该交换机绑定的所有队列上

  3. fanout交换机转发消息是最快的。

如果文章对您有帮助,请记得点赞关注哟~
欢迎大家关注我的公众号:字节传说,每日推送技术文章供大家学习参考。

rabbitmq系列(一)初识rabbitmq的更多相关文章

  1. [RabbitMQ学习笔记] - 初识RabbitMQ

    RabbitMQ是一个由erlang开发的AMQP的开源实现. 核心概念 Message 消息,消息是不具名的,它由消息头和消息体组成,消息体是不透明的,而消息头则由 一系列的可选属性组成,这些属性包 ...

  2. 初识RabbitMQ系列之一:简单介绍

    一:RabbitMQ是什么? 众所周知,MQ是Message  Queue(消息队列)的意思,RabbitMQ就是众多MQ框架其中的一款,开源实现了AMQP协议(官网:http://www.amqp. ...

  3. 在Node.js中使用RabbitMQ系列二 任务队列

    在上一篇文章在Node.js中使用RabbitMQ系列一 Hello world我有使用一个任务队列,不过当时的场景是将消息发送给一个消费者,本篇文章我将讨论有多个消费者的场景. 其实,任务队列最核心 ...

  4. RabbitMQ入门-初识RabbitMQ

    初识RabbitMQ 要说RabbitMQ,我们不得不先说下AMQP.AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面 ...

  5. .Net RabbitMQ系列之环境搭建于RabbitMQ基本介绍

    本系列主要讲解RabbitMQ在.Net环境下的应用,由于Linux环境下,本人Linux功力有限,所以本系列的RabbitMQ跑在Windows环境中.所以的配置之类都在Windows环境中进行. ...

  6. RabbitMQ系列(四)RabbitMQ事务和Confirm发送方消息确认——深入解读

    RabbitMQ事务和Confirm发送方消息确认--深入解读 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器 ...

  7. RabbitMQ系列(三)RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  8. RabbitMQ系列(二)深入了解RabbitMQ工作原理及简单使用

    深入了解RabbitMQ工作原理及简单使用 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchange介绍 ...

  9. RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介(转载)

    RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介 今天这篇博文是我翻译的RabbitMQ的最后一篇文章了,介绍一下RabbitMQ的C#开发的接口.好了,言归正传吧. N ...

  10. RabbitMQ系列教程之六:远程过程调用(RPC)(转载)

    RabbitMQ系列教程之六:远程过程调用(RPC) 远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习 ...

随机推荐

  1. Python--day27--复习

    例1:

  2. [转]C#中 ??、 ?、 ?: 、?.、?[ ] 问号

    1. 可空类型修饰符(?) 引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=null; 编译器就会报错.为了使值类型也 ...

  3. 【js】 vue 2.5.1 源码学习(六) initProxy initLifeCycle 渲染函数的作用域代理

    大体思路 (五) 1. initProxy 渲染函数的作用域代理 ==> es6 如果支持proxy (hasProxy) 就用proxy 不支持就用 defineProperty() prox ...

  4. H3C命令调试debugging--用户视图

    <H3C>terminal debugging     //使用debugging必须使用的命令--打开调试信 息的屏幕输出开关 <H3C>display debugging  ...

  5. JS(JavaScript)的深入了解1(更新中···)

    面向对象 1.单列模式 2.工厂模式 3.构造函数 (1) 类Js天生自带的类Object 基类Function Array Number Math Boolean Date Regexp Strin ...

  6. Linux 内核 标准 PCI 配置寄存器

    一些 PCI 配置寄存器是要求的, 一些是可选的. 每个 PCI 设备必须包含有意 义的值在被要求的寄存器中, 而可选寄存器的内容依赖外设的实际功能. 可选的字段不被 使用, 除非被要求的字段的内容指 ...

  7. oracle中update语句修改多个字段

    如需要修改下列数据:表名为student 一般会这样写: update student set sname = '李四', sage = 20, sbirthday = to_date('2010-0 ...

  8. k8s数据持久化实验

    Step 1:创建PV ============================================ apiVersion: v1kind: PersistentVolumemetadat ...

  9. unsupported jsonb version number 123

    PostgreSQL  jsonb 入库时遇到   unsupported jsonb version number 123 变通方法 insert into  htclanedata (laneda ...

  10. HBase写过程详解

    1首次读写流程图 2 首次写基本流程 (1)客户端发起PUT请求,Zookeeper返回hbase:meta所在的region server (2)去(1)返回的server上,根据rowkey去hb ...