文档章节

RabbitMQ使用时注意的一些问题

o
 osc_w9s1w4o0
发布于 2019/04/08 08:25
字数 1933
阅读 12
收藏 0

精选30+云产品,助力企业轻松上云!>>>

 一、前言

      上篇RabbitMQ的博文居然上了推荐,效果很不错,接下来我们就来聊聊我们RabbitMQ的方案,先谈方案,代码等等后面补上,感觉不错给我点点关注,点点👍,本来能早点写完这篇博文的,由于工作最近很繁忙稍微推迟一些时间。

 二、方案

      方案从两方面谈:生产者的投递以及消费端的消费。

      生产端

      生产端要保障的是消息发出去,RabbitMQ的Borker收到并且返会确认收到,由于网络的原因消息发送Borker的时候可能失败,另外Borker返回给生产者确认的时候也可能发生闪断,所以为了保障100%投递我们还需要合理的补偿机制。主要提供两种方案:消息打标和延时队列,还是以最经典的下订单的场景为例:

      消息打标:

      消息打标的意思就是将消息落库以后,里面对消息状态进行记录,标记为发送中以及发送成功两种状态,然后采用定时轮询任务的方式去查找消息是否发送成功,具体看下图:

      

        接下来我们详细介绍一下该流程:

        1.订单生成同时落地到订单表和消息记录表,这里的消息记录表可以用MongoDB或者ES等方式进行替代;

        2.从消息记录表读取消息,发送消息到Borker同时更改消息状态为发送中;

        3.假设消息接收成功,Borker接收消息成功,并返回确认收到给生产者,这个时候更新消息记录表消息状态为成功;

        4.假设消息接收失败,可能失败的地方有两个处:Borker接收消息和返回消息都可能发生网络问题或者其他状况,导致生产者接收不到返回值;

        5.定时任务轮询,规定时间内没有发送成功消息再次按照步骤2进行投递,这个规定时间最多容忍2或者次查询轮询同一个条消息,如果依然接收不成功,那么则设置消息接收失败,这里可能是交换机或者队列绑定失败造成的,需要我们人工排查;

        延迟队列:

        使用延迟队列对消息的延迟投递,通过回调函数做二次检查确认消息投递成功;延迟队列是针对消息来说,是指当消息发送出去以后不想立即被消费,而是等待特定的时间后,消费者才进行消费,比如我们常见的支付付款,30分钟内必须付款成功,否则就异常,这里是延迟队列的经典场景;RabbitMQ来说本身是不支持延迟队列的,但是可以通过死信队列和过期时间来实现延迟队列,简单解释下就是生产队发布消息到正常队列,设置过期时间,绑定死信交换机,消费端直接消费死信队列,这样就完成延迟队列的实现;通过延时队列去实现消息100%可靠投递的化,会涉及到消费者消费的问题,相对比较复杂;

       

       接下来我们详细介绍通过延迟队列实现消息100%可靠投递的流程:

       1.当订单落库以后,生产者发送消息给Borker,并且发送延时消息,该消息是用来做二次检查确认的;

       2.消费者(2)消费成功以后,将消费成功的消息体回发到Borker中(3);

       3.回调服务(4)消费Boker中消费者消费成功的消息体并且入库;

       4.当延时队列(5)中存在消息时候做检查数据库是否存在消息,如果存在着消息消费成功,如果不存在则消息消费失败,同时再次调用生产者发送消息;

       以上就是我前面提到过的两种方案,我们公司现在还是再用第一种 ,对于第二种主要是为了提升系统的吞吐量,减少一次入库;其实合适思想就是通过补偿,来完成消息100%投递,这里面就存在一个问题,同一条消息可能会被投递多次,可能照成消费端多次消费同一条消息,所以这个时候我们就要考虑客户端幂等性的设计;另外消费端消费的时候,消息的顺序是得不到保障的,如果有业务之间相互依赖就需要考虑消息顺序不一致时候处理。

       消费端

       消费端消费需要注意得地方就是上面提到得两种情况:幂等性以及消息的顺序问,接下来我们也来聊一聊消费端的设计问题。

       幂等性

       幂等性这个也是我们Web端设计时候要考虑的问题之一,幂等性就是多次提交与一次提交看到的结果是相同的,这里解释的有点简单,感兴趣的自己百度下深入了解下;这里我们来聊聊我们消费端怎么来设计实现幂等;

       1.唯一id+业务规则,利用数据库主键去重,我们现在就是通过唯一id去重,业务规则具体可以根据你们的使用场景去决定你是否需要加上这个条件;

       2.通过Redis去实现幂等,通过Redis缓存去判断该消息是否消费过,但是这个时候我们要考虑Redis与数据库怎么要保障原子性的问题;

       业务依赖(顺序性)

       这个问题其实我不太介意设计这么复杂,但是要是真是存在这样的场景,那也聊一聊我的一些想法:

       1.保障顺序消费的消息都需要在同一个队列中,保障顺序消费的消息的Id是一致的,并且消费者只能有一个;

       2.增加消息体属性:顺序消费的标记用来区分谁先消费;

       3.当消费端消费以后,如果是消费顺序正确,那么落库,如果消息顺序不正确,则先落库消息,并且发送延时消息;

       4.当收到延时队消息的时候,然后根据消息id查询数据库,进行数据处理,如果还是顺序不对则再次发送延时消息;

       为什么这么设计?其实不这么设计也是可以,比如我们消息顺序不对的时候,直接投入延时队列,这种不能区分到底谁先被消费,只能靠随机去尝试,极端情况下可能很多次都无法保证顺序是一致,所以我增加顺序标记的想法,为什么要保证到同一个队列和只有一个消费者,这是为了保证顺序性,当多个队列,多个消费者的时候顺序性更难保证。

       以上都是我自己的一些想法,如果发现不对,请指正谢谢!

 三、结束

       最近一段时间比较忙,代码部分我想做一些封装,暂时没时间写,等等稳定以后补充上,大家在稍微等等,接下来还会介绍一些消息存储和镜像队列方面的知识,欢迎大家加群438836709!欢迎大家关注我!

       

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
RabbitMQ 问题汇总

问题1. 安装过程(CentOS 7):RabbitMQ 的安装很简单,网上也有很多的教程,首先安装 Erlang, 然后安装 rabbitmq, 但在安装 rabbitmq 中,执行 yum install rabbitmq-server-3.7.7-1.el7.noar...

osc_bkhfgue7
03/04
1
0
rabbitmq学习(八) —— 可靠机制上的“可靠”

接着上一篇,既然已经有了手动ack、confirm机制、return机制,还不够吗? 以下博文转自https://www.jianshu.com/p/6579e48d18ae和https://my.oschina.net/u/3523423/blog/1620885 本以为这样...

osc_panqs2jh
2019/03/14
7
0
RabbitMQ在Windows环境下的安装与使用

环境配置 部署环境 部署环境:windows server 2008 r2 enterprise 官方安装部署文档:http://www.rabbitmq.com/install-windows.html官方文档说明 下载erlang 原因在于RabbitMQ服务端代码是使...

osc_bnzpjhof
2019/03/02
2
0
RabbitMQ - work queue 工作模式

前言 上一篇 RabbitMQ 入门 对 RabbitMQ 做了入门了解并介绍了他的一种工作模式-简单模式。本篇来学习一下 RabbitMQ 的第二种工作模式 - work queue。 ---- worke queue介绍 先来看官网的一张...

nimo10050
2019/04/09
8
0
rabbitmq安装

简单说下个人的理解,mq就是一个消息代理,负责异步消息转发,可以很大程度缓解服务器压力,并且防止服务器宕机影响业务等。 安装: 环境:vbox+centos7+php 1).首先需要安装erlang #wget ht...

osc_fhl05ph9
2019/06/05
3
0

没有更多内容

加载失败,请刷新页面

加载更多

linux下java环境搭建

1、jdk下载: 官方地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html 如下图所示,我这边选择的是红框中的版本 2、压缩包上传至服务器 将下载的压缩包上传...

wc_飞豆
43分钟前
17
0
面试题:Java对象不再使用时,为什么要赋值为null?

前言 许多Java开发者都曾听说过“不使用的对象应手动赋值为null“这句话,而且好多开发者一直信奉着这句话;问其原因,大都是回答“有利于GC更早回收内存,减少内存占用”,但再往深入问就回...

码农突围
45分钟前
22
0
设计模式(5) 原型模式

原型模式 原型模式的适用场景 浅拷贝 深拷贝 用Initialize方法修改初始化状态 原型模式与之前学习的各种工厂方法、单例模式、建造者模式最大、最直观的区别在于,它是从一个既有的对象“克隆...

zhixin9001
45分钟前
7
0
获取免费的pycharm激活码网站

http://www.lookdiv.com/

云烟成雨forever
45分钟前
27
0
用Helm部署Kubernetes应用,支持多环境部署与版本回滚

1 前言 Helm是优秀的基于Kubernetes的包管理器。利用Helm,可以快速安装常用的Kubernetes应用,可以针对同一个应用快速部署多套环境,还可以实现运维人员与开发人员的职责分离。现在让我们安...

南瓜慢说
47分钟前
25
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部