概述

本示例程序全部来自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. Angular版本

    Index of (-1.6) 没有Angular 3,下一个Angular主版本将是Angular 4

  2. [LeetCode&Python] Problem 606. Construct String from Binary Tree

    You need to construct a string consists of parenthesis and integers from a binary tree with the preo ...

  3. Unity3D UGUI下拉菜单/Dropdown组件用法、总结

    Unity3D中UGUI实现下拉菜单 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  4. Gym101482 NWERC 2014(队内训练第4场)

    -----------------------前面的两场感觉质量不高,就没写题解----------------------------- A .Around the Track pro:给定内多边形 ...

  5. 【JVM】java对象

    一.对象内存布局 对象在内存中存储可分为3块区域:对象头,实例数据,对齐填充 1.对象头 对象头包含两部分内容. 第一部分:存储对象自身的运行时数据,哈希吗(hashCode),GC分代年龄,锁状态标 ...

  6. 使用Maven插件启动tomcat服务

    新建maven web项目,首先保证maven环境OK,maven项目能正常install1.pom.xml文件配置如下: <build> <pluginManagement> ...

  7. 关闭eth0或者某个网络接口

    ifdown eth0 关闭eth0网络接口 ifup eth0 打开eth0网络接口 如果上面的命令无效,请使用下面的 ifconfig eth0 down 关闭eth0接口 ifconfig et ...

  8. firefox一搜索就提示是否进入***网站和取消占地方的标题栏

    来看一下这个蛋疼的提示 每次都要手动关闭.后来在网上看到一个解决方法 解决方法: 地址栏输入about:config回车进入设置, 去掉警告那个勾 点击确定,进入配置页 搜索 取消最上面方人的fire ...

  9. Cassandra--设置数据保留时间

    在Cassandra中,可以设置列的保留时间(Time To Live),当该列超过保留时间后,会下一次读取中被墓碑(Tombstone)标记,然后保留一个垃圾回收周期(表属性gc_grace_sec ...

  10. lapis 项目添加prometheus 监控集成grafana

    操作很简单,主要是进行界面的配置以及prometheus 服务的配置, 可以和https://www.cnblogs.com/rongfengliang/p/10074044.html &&a ...