一、写在前面

使用过分布式中间件的人都知道,程序员使用起来并不复杂,常用的客户端 API 就那么几个,比我们日常编写程序时用到的 API 要少得多。但是分布式中间件在中小研发团队中使用得并不多,为什么会这样呢?

原因是中间件的职责相对单一,客户端的使用虽然简单,但整个环境搭起来却不容易。所以对于系列中的几篇中间件文章,我们重点放在解决门槛问题,把服务端环境搭好(后期可云或运维解决),把中间件的基本职责和功能介绍好,把客户端 Demo 写好,让程序员抬抬脚,在调试代码中即可轻松入门。

根据我们以往几年的经验,初次接触也可以自主快速学习,文章和 Demo 以实用为主,以下是消息队列 RabbitMQ 的快速入门及应用。

二、为什么要用消息队列 MQ

     1、业务系统往往要求响应能力特别强,能够起到削峰填谷的作用。

     2、解耦:如果一个系统挂了,则不会影响另外系统的继续运行。

     3、业务系统往往有对消息的高可靠要求,以及有对复杂功能如 Ack 的要求。

     4、增强业务系统的异步处理能力,减少甚至几乎不可能出现并发现象:

使用消息队列,就好比为了防汛而建葛洲坝,有大量数据的堆积能力,然后可靠地进行异步输出。例如:

传统做法存在如下问题,请见上图:

  1. 一旦业务处理时间超过了定时器时间间隔,就会导致漏单。
  2. 如果采用新开线程的方式获取数据,那么由于大量新开线程处理,会容易造成服务器宕机。
  3. 数据库压力大,易并发。

     使用 MQ 后的好处,请见上图

  1. 业务可注册、可配置。
  2. 获取数据规则可配置。
  3. 成功消费 MQ 中的消息才会被 Ack,提高可靠性。
  4. 大大增强了异步处理业务作业的能力:

定时从数据库获取数据后,存入 MQ 消息队列,然后 Job 会定期扫描 MQ 消息队列,假设 Job 扫描后先预取 5 条消息,然后异步处理这 5 条消息,也就是说这 5 条消息可能会同时被处理。

三、RabbitMQ 简介

RabbitMQ 是基于 AMQP 实现的一个开源消息组件,主要用于在分布式系统中存储转发消息,由因高性能、高可用以及高扩展而出名的 Erlang 语言写成。

其中,AMQP(Advanced Message Queuing Protocol,即高级消息队列协议),是一个异步消息传递所使用的应用层协议规范,为面向消息的中间件设计。

RabbitMQ 特点如下

     高可靠:RabbitMQ 提供了多种多样的特性让你在可靠性和性能之间做出权衡,包括持久化、发送应答、发布确认以及高可用性。

     高可用队列:支持跨机器集群,支持队列安全镜像备份,消息的生产者与消费者不论哪一方出现问题,均不会影响消息的正常发出与接收。

     灵活的路由:所有的消息都会通过路由器转发到各个消息队列中,RabbitMQ 内建了几个常用的路由器,并且可以通过路由器的组合以及自定义路由器插件来完成复杂的路由功能。

     支持多客户端:对主流开发语言(如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等)都有客户端实现。

     集群:本地网络内的多个 Server 可以聚合在一起,共同组成一个逻辑上的 broker。

     扩展性:支持负载均衡,动态增减服务器简单方便。

     权限管理:灵活的用户角色权限管理,Virtual Host 是权限控制的最小粒度。

     插件系统:支持各种丰富的插件扩展,同时也支持自定义插件,其中最常用的插件是 Web 管理工具 RabbitMQ_Management,可参考如下文章:https://www.cnblogs.com/gossip/p/4475978.html

四、RabbitMQ 工作原理

消息从发送端到接收端的流转过程即 RabbitMQ 的消息工作机制,请见下图:

消息发送与接收的工作机制

五、RabbitMQ 基本用法

共有 6 种基本用法:单对单、单对多、发布订阅模式、按路由规则发送接收、主题、RPC(即远程存储调用)。我们将介绍单对单、单对多和主题的用法。

1、单对单:单发送、单接收。请见下图。

2、单对多:一个发送端,多个接收端,如分布式的任务派发。请见下图:

3、主题:Exchange Type 为 topic,发送消息时需要指定交换机及 Routing Key,消费者的消息队列绑定到该交换机并匹配到 Routing Key 实现消息的订阅,订阅后则可接收消息。只有消费者将队列绑定到该交换机且指定的 Routing Key 符合匹配规则,才能收到消息。

其中 Routing Key 可以设置成通配符,如:*或 #(*表示匹配 Routing Key 中的某个单词,# 表示任意的 Routing Key 的消息都能被收到)。如果 Routing Key 由多个单词组成,则单词之间用. 来分隔。

命名规范:

交换机名的命名建议:Ex{AppID}.{自定义 ExchangeName},队列名的命名建议:MQ{AppID}.{自定义 QueueName} 。

六、Demo 下载及更多资料

RabbitMQDemo 下载地址https://github.com/das2017/RabbitMQDemo

RabbitMQ 的官方网址http://www.rabbitmq.com

转载地址:http://www.infoq.com/cn/articles/architecture-practice-02-rabbitmq?utm_source=infoq&utm_campaign=user_page&utm_medium=link

中小型研发团队架构实践六:如何用好消息队列RabbitMQ?的更多相关文章

  1. 中小型研发团队架构实践:Redis快速入门及应用

    Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...

  2. 中小型研发团队架构实践:分布式协调服务ZooKeeper

    一.ZooKeeper 是什么 Apache ZooKeeper 由 Apache Hadoop 的子项目发展而来,于 2010 年 11 月正式成为了 Apache 的顶级项目. 相关厂商内容 优秀 ...

  3. 中小型研发团队架构实践:任务调度Job

    一.Job 简介 Job 类似于数据库中的作业,多用于实现定时执行任务.适用场景主要包括定时轮询数据库同步.定时处理数据.定时邮件通知等. 我们的 Job 分为操作系统级别定时任务 WinJob 和 ...

  4. 中小型研发团队架构实践八:分布式协调服务ZooKeeper

    一.ZooKeeper 是什么 Apache ZooKeeper 由 Apache Hadoop 的子项目发展而来,于 2010 年 11 月正式成为了 Apache 的顶级项目. ZooKeeper ...

  5. 中小型研发团队架构实践七:集中式日志ELK

    一.集中式日志 日志可分为系统日志.应用日志以及业务日志,系统日志给运维人员使用,应用日志给研发人员使用,业务日志给业务操作人员使用.我们这里主要讲解应用日志,通过应用日志来了解应用的信息和状态,以及 ...

  6. 中小型研发团队架构实践五:Redis快速入门及应用

    Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...

  7. 中小型研发团队架构实践三:微服务架构(MSA)

    一.MSA 简介 1.1.MSA 是什么 微服务架构 MSA 是 Microservice Architect 的简称,它是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相通讯.互相 ...

  8. 中小型研发团队架构实践九:任务调度Job

    一.Job 简介 Job 类似于数据库中的作业,多用于实现定时执行任务.适用场景主要包括定时轮询数据库同步.定时处理数据.定时邮件通知等. 我们的 Job 分为操作系统级别定时任务 WinJob 和 ...

  9. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

随机推荐

  1. 3.Ubuntu下安装mysql并在windows下使用Navicat来连接

    一.安装mysql(只需要三条命令) 1.第一条命令(中间需要输入root用户密码): sudo apt-get install mysql-server 2.第二条命令: sudo apt-get ...

  2. delphi中OleContainer的使用总结

    1:定义流的header , OleContainer要求流中要有Headertype //流Header的结构 TStreamHeader = record Signature: Integer; ...

  3. 我的ecshop二次开发经验分享

    https://jingyan.baidu.com/article/358570f65dbad2ce4724fcc7.html

  4. (原创)c++中的类型擦除

    c++11 boost技术交流群:296561497,欢迎大家来交流技术. 关于类型擦除,可能很多人都不清楚,不知道类型擦除是干啥的,为什么需要类型擦除.有必要做个说明,类型擦除就是将原有类型消除或者 ...

  5. node.js second day

    create global link 使用全局模式安装的包不能直接通过require使用,但是nmp提供了一个 nmp link ,这个可以打破限制 $ nmp link [express] ./no ...

  6. c# 数据写入三菱PLC

    public void Data_Write_Value(int[] m_write_data)        {            int lSize = 2; string[] Address ...

  7. 魔方Newlife.Cube权限系统的使用及模版覆盖详解

    讲人:大石头 时间:2018-11-14 晚上20:00 地点:钉钉群(组织代码BKMV7685)QQ群:1600800 内容:魔方Newlife.Cube权限系统的使用及模版覆盖详解 准备 源码地址 ...

  8. python 通过pytz模块进行时区的转换,获取指定时区的时间

    import pytz import time import datetime print(pytz.country_timezones('cn')) # 查询中国所拥有的时区 print(pytz. ...

  9. static、final、static final的区别

    final: final可以修饰属性,方法,类,局部变量(方法中的变量) final修饰的属性的初始化可以在编译期,也可以在运行期,初始化后不能被改变. final修饰的属性跟具体对象有关,在运行期初 ...

  10. hdu5745--La Vie en rose (DP+bitset)

    好题,学到新姿势! 题意:给两个字符串 a 和 b ,b可以进行变换,规则是可以任意交换相邻两个字符的位置,但是不可以有交叉(例如3和4交换,5和6交换 互不影响,但是2和3,3和4就不可以).求a中 ...