概述

本示例程序全部来自rabbitmq官方示例程序,rabbitmq-demo

官方共有6个demo,针对不同的语言(如 C#,Java,Spring-AMQP等),都有不同的示例程序;

本示例程序主要是Spring-AMQP的参考示例,如果需要其他语言的参考示例,可以参考官网;

rabbitmq模拟器

模拟器

rabbitmq简介

核心架构图





AMQP 0-9-1 Model Explained

重要语法说明

  • producer或publisher: 消息生产者/发布者,即:产生消息的;
  • Exchange:producer或publisher只会将message发送到Exchange,目前有4种不同的Exchange类型;
  • Queue:消息队列,所有的消费者都是直接从Queue获取Message并消费;
  • Binging:连接Exchange和Queue的纽带,决定Exchange如何路由消息到不同的Queue;
  • routingKey:生产者-->message-->Exchange,需要指定一个key,叫做routingKey;
  • routingKey:Exchange-->Binging-->Queue,Binging有一个Key值,叫routingKey或bingingKey;
  • bingingKey:Exchange-->Binging-->Queue,Binging有一个Key值,bingingKey;

核心理解

4种不同的Exchange,对routingKey的解释都不相同;

对routingKey的不同解释,决定了Exchange路由Message到Queue的不同方案;

  1. direct exchange: 匹配2个routingKey(即routingKey和bingingKey)是否相等,相等时才进行消息路由;
  2. fanout exchange: 忽略routingKey,会将Message路由到所有绑定的Queue;
  3. topic exchange: routingKey格式形如aaa.bbb.xxx*.ccc.dd.#,类似正则表达式匹配;
  4. headers exchange:

jar包说明

  • Java版本:

    Java版本使用如下jar(说明:若是使用):
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

demo1: 单生产者-单消费者

spring.profiles.active=hello-world, sender, receiver

demo2: 单生产者-多消费者

Work queues官方示例



application.properties配置

spring.profiles.active=work-queues, sender, receiver
#spring.profiles.active=work-queues, sender
#spring.profiles.active=work-queues, receiver

详细描述参见:单生产者-多消费者详细


demo3: 发布/订阅

Publish/Subscribe官方示例

  • 消费广播到多个消费者进行消费;
  • 使用fanout pattern;

application.properties配置

spring.profiles.active=pub-sub, receiver , sender

详细描述参见:发布/订阅详细


demo4: Routing

Routing官方示例

Direct exchange 模式进行route结构图



a message goes to the queues whose binding key exactly matches the routing key of the message;(相等时才路由)

Multiple bindings



两个Queue使用相同的BingingKey(black) ==> 效果类似于:发布/订阅模式(demo3);

完整的结构图

application.properties配置

pring.profiles.active=routing, receiver , sender

详细描述参见:发布/订阅详细


demo5: Topics

Topics官方示例

  • 使用 Topic exchange实现;
  • 发送到Topic exchange的routingKey必须满足一定要求:用"."分割的words列表,如:*.aaa.bbb.#
  • BingingKey和routingKey有相同的格式要求;
  • * : 可以匹配一个word;
  • #: 可以匹配0个或多个words;

application.properties配置

pring.profiles.active=topics, receiver , sender

详细描述参见:Topics


demo6: RPC over RabbitMQ

RPC官方示例

结构图

application.properties配置

spring.profiles.active=rpc,server
#spring.profiles.active=rpc,client

详细描述参见:RPC


消费端确认

Delivery Identifiers: Delivery Tags

消费者注册后,rabbitmq将消息交付给消费者时,都会带有一个“Delivery Tags”,这个是唯一的ID标识,id以整数的递增的方式实现。

Acknowledgement Modes(消费端)

自动确认模式

  • 发送之后,就认为是发送成功(fire-and-forget)
  • 消息不停的发送到消费端消费,无需等待消费端任何确认;

缺点:

  • 可能造成消费端不堪重负;

手动模式

  1. basic.ack: 肯定的确认;
  2. basic.nack: 否定的确认(RabbitMQ对AMQP 0-9-1的扩展),支持消息批量确认;
  3. basic.reject:否定的确认,消息消费失败后,直接从broker中将消息delete不支持批量确认

Acknowledging Multiple Deliveries at Once(消息批量确认)

  • 一次确认多个消息发送,而不是每一个消息单独确认;
  • basic.reject:不具备该功能;
  • basic.nack: 具备该功能;

实现方式

  • multiple field: 设置为true;

示例

假设:在Channel(ch)上有5,6,7,8这4个delivery tags未确认;

  • 情况1,delivery_tag=8 & multiple=true: 则5,6,7,8这4个tags都将被确认;
  • 情况2,delivery_tag=8 & multiple=false:则只有8被确认,而5,6,7将不会被被确认;

Channel Prefetch Count (QoS)[可以设置消费端消费的速率]

  • 消息消费是异步完成的,手动确认也是异步的;
  • 有一部分消息是被消费了,但是还未来得及确认:希望控制未被确认消息的size,防止无界的缓存
  • prefetch count:使用basic.qos方法设置该值可以控制未被确认消息的max size;
  • 当达到该最大值时,rabbitmq将停止交付消息进行消费;
  • 仅对basic.qos方法有效,对basic.get方法无效;

示例

假设:在Channel(Ch)上有5,6,7,8共4个未被确认的消息,且ch的prefetch count=4

结果:rabbitmq将不会再交付任何消息到该Channel上,除非有消息被确认;

消费确认选择,prefetch设置以及吞吐量

  • 情况1:增大prefetch:提高向消费者传递消息的速度;
  • 情况2:自动确认模式可以产生最佳的传送速率;

应避免:

  1. 自动确认模式
  2. 手动确认模式 + 无限制的prefetch

结论:

  • 情况1情况2都可能导致交付但未来得及处理的Message增加,增大RAM的消耗;

推荐值:

  • prefetch: 100~300,可以有效提高吞吐量,并避免RAM消耗过多的风险;

消费失败或连接中断: 自动重新reQueue

当消息发送给消费端后,如果出现如下情况,则消息会重新reQueue,会被再次发送;

  1. TCP连接中断;
  2. 消费端挂掉:无法进行消息确认;

Client Errors: Double Acking and Unknown Tags

消费端无法对同一个消息确认超过一次,当超过一次之后,将抛出Channel error: PRECONDITION_FAILED - unknown delivery tag XXXX

总结

  • 每个交付给消费端的消息,都有一个唯一的标识delivery tag
  • 自动消息确认;
  • 手动消息确认:每个消息单独确认批量消息确认;
  • prefetchCount:可以控制消息端的吞吐量,避免消费端消费过慢,产生RAM大量消耗;
  • 失败重传:TCP连接中断消费端挂掉,都会引起消息重新入队列,重新消费(手动消息确认时);
  • 无法对同一个消息进行2次或2次以上的确认,否则会抛出异常;

发送端确认

Channel事务

  • 不推荐使用: 会严重降低吞吐量;

在 AMQP 0-9-1中,保证消息不丢失的唯一方法,就是使用事务;

  1. 开启Channel事务;
  2. 发送消息,提交事务;

类似消费端的应答确认机制

  • confirm.select: 应用于Channel时,表示使用确认模式
  • 事务确认模式无法共存:二者只能选择其一;

确认模式 (confirm.select)

  • 发送端使用confirm.select;
  • broker发送basic.ack来确认Message已被处理;
  • delivery-tag: 消息序列,具有唯一性;
  • multiple=true: 用于设置批量消息确认
  • 无法保证消息何时被确认;
  • 确认模式:消息要么被confirmed(OK),要么被nack(fail),且only once;

Java示例:(发送端发送大量messages,使用确认模式)

程序-确认模式

否定确认

异常情况时,服务端无法处理消息,则broker发送basic.nack来进行否定确认

应答延时和持久化消息

  • 仅当消息被持久化到disk之后,才会发送basic.ack应答;
  • 吞吐量提高建议:异步处理应答批量发送消息;

应答顺序

当使用异步发送和持久化消息时,broker对消息的确认顺序可能和发送者的消息发送顺序不一致;

发送确认 + 保证交付

  • 消息持久化: 并不能保证消息不丢失(在写入disk前broker就挂掉);

限制

Delivery tag is a 64 bit long value, and thus its maximum value is 9223372036854775807.Since delivery tags are scoped per channel, it is very unlikely that a publisher or consumer will run over this value in practice.

参考

Consumer Acknowledgements and Publisher Confirms

【rabbitmq】rabbitmq概念解析--消息确认--示例程序的更多相关文章

  1. 【ABAP系列】SAP ABAP解析XML的示例程序

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP解析XML的示例 ...

  2. RabbitMQ基础概念(消息、队列、交换机)

    1.消息的确认 RabbitMQ需要对每一条发送的消息进行确认.消费者必须通过AMQP的basic.ack命令显式地向RabbitMQ发送一个确认,或者在订阅到队列的时候就将auto_ack参数设置为 ...

  3. rabbitMQ学习笔记(三) 消息确认与公平调度消费者

    从本节开始称Sender为生产者 , Recv为消费者   一.消息确认 为了确保消息一定被消费者处理,rabbitMQ提供了消息确认功能,就是在消费者处理完任务之后,就给服务器一个回馈,服务器就会将 ...

  4. SpringBoot 整合 RabbitMQ(包含三种消息确认机制以及消费端限流)

    目录 说明 生产端 消费端 说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同 ...

  5. 消息队列RabbitMQ(三):消息确认机制

    引言 RabbitMQ的模型是生产者发送信息到 Broker (代理),消费者从 Broker 中取出信息.但是生产者怎么知道消息是否真的发送到 Broker 中了呢?Broker 又怎么知道消息到底 ...

  6. RabbitMQ安装、集群搭建、概念解析

    RabbitMQ安装.集群搭建.概念解析 基本概念 为什么会产生MQ 1.解耦:采用异步方式实现业务需求达到解耦的目的. 2.缓冲流量,削峰填谷: 问:为什么会有流量冲击? 答:采用"直接调 ...

  7. SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门

    1.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.Rabbi ...

  8. RabbitMQ消息确认(发送确认,接收确认)

    前面几篇记录了收发消息的demo,今天记录下关于 消息确认方面的 问题. 下面是几个问题: 1.为什么要进行消息确认? 2.rabbitmq消息确认 机制是什么样的? 3.发送方如何确认消息发送成功? ...

  9. RabbitMQ (十二) 消息确认机制 - 发布者确认

    消费者确认解决的问题是确认消息是否被消费者"成功消费". 它有个前提条件,那就是生产者发布的消息已经"成功"发送出去了. 因此还需要一个机制来告诉生产者,你发送 ...

随机推荐

  1. HDU 1159:Common Subsequence(LCS模板)

    Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. (11)线程池(最新的concurrent.futures包去开启)

    '''concurrent.futures是最新的开启线程池的包'''import timefrom concurrent.futures import ThreadPoolExecutor #开启线 ...

  3. 实验吧—Web——WP之 因缺思汀的绕过

    首先打开解题链接查看源码: 查看源码后发现有一段注释: <!--source: source.txt-->这点的意思是:原来的程序员在写网页时给自己的一个提醒是源码在这个地方,我们要查看时 ...

  4. hdu3746 Cyclic Nacklace KMP

    CC always becomes very depressed at the end of this month, he has checked his credit card yesterday, ...

  5. hdu1846 Brave Game 博弈

    十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻.今天,大家选择上 ...

  6. Java中final的用法总结

    1.         修饰基础数据成员的final 这是final的主要用途,其含义相当于C/C++的const,即该成员被修饰为常量,意味着不可修改.如java.lang.Math类中的PI和E是f ...

  7. 【usaco 2006 feb gold】 牛棚安排

    终于自己独立做出来一道题QAQ然而本校数据实在太水不能确定我是不是写对了... 原题: Farmer John的N(1<=N<=1000)头奶牛分别居住在农场所拥有的B(1<=B&l ...

  8. jsp页面继承

    功能类似 django template 中的  extends 功能 使用 1.需要下载rapid-core-4.0.jar    导入到web-inf下lib中   下载地址   http://w ...

  9. mac-ppt-auto-open-recovery-files

    mac 每次打开PPT都会出现一个自动保存的文件,不知道这个文件是保存在哪里,该怎么删除 打开finder(访达),按 shift+command+G,输入~/Library/Containers/c ...

  10. windows知识

    文章目录 系统 修改远程桌面的端口号 IE选项中reset web setting不可用(灰色)的解决办法 重装系统后,修改默认程序安装目录.我的文档.桌面 路径 Keep network addre ...