用RabbitMQ了好几年之后,我总结出来5点RabbitMQ的使用心得
大概从 2013 年开始,我就开始了自己和 RabbitMQ 的接触,到现在已经有七年多了。
在这七年中,既有一些对 RabbitMQ 的深度体验,更有无数的血泪史。
而根据我这么多年的使用经验,我将 RabbitMQ 的心得形成一些提醒或者规范分享给大家,这样,大家以后使用 RabbitMQ 的时候,就不会再走我走过的弯路了。
我想把我这些关于 RabbitMQ 的经验和心得,分成三篇来写:
- 开发前的规范;
- 开发中的注意事项;
- 以及 MQ 本身的优化。
这次咱们先从开发前的规范开始谈起。
我曾经一直都很奇怪,为何大家使用开发语言有开发规范,使用数据库有数据库规范,但是使用 MQ 却很少见一些规范。
使用 MQ 缺少规范,这是普遍的问题?还只是我身边的个例?
不管答案是哪个,在 RabbitMQ 使用时,为了避免在开发中少出现问题,为了事半功倍,都需要提前规范好一些配置和事项。
1. 一个 RabbitMQ 应用里建立多个 vhost,去对应不同的开发项目
我们在使用数据库的时候,会在一个数据库应用里建立多个不同的数据库去给不同的项目使用,而不用在不同的服务器专门每个项目都安装个数据库应用。
在 RabbitMQ 的 vhost,也是类似的理念。
vhost 本质上是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、绑定、交换器和权限控制,当在 RabbitMQ 中创建一个用户时,用户通常会被指派给至少一个 vhost,并且只能访问被指派 vhost 内的队列、交换器和绑定,vhost 之间是绝对隔离的。
所以,不同的 vhost 对应不同的项目,互不影响,而这些 vhost 其实都是在一台主机一个 RabbitMQ 应用上。
但是,现在的状况是大部分使用 RabbitMQ 的技术团队往往就使用默认的 vhost:“/”,如果多出一个项目了,就再去创建一个 RabbitMQ 的进程。这样做,非常浪费开发资源。
推荐一个项目对应一个 vhost。
2. 不直接使用 RabbitMQ 自己的客户端
很多公司使用 RabbitMQ 都是直接使用 RabbitMQ 自己的 java 版本客户端,但是由于 RabbitMQ 本身内在的复杂性和多样性,有很多技术细节需要独自处理。
比如网络连接的处理,比如异常的处理,比如消息失败的处理等等等。这些,如果手头没有一套成熟的框架,那么很可能由于一些细节处理不到位,导致非常多的问题,这都是不必要的成本。
所以,要么使用一套已有的 RabbitMQ 客户端框架(比如 Spring 的 RabbitMQ 框架),要么自己封装出一套底层 RabbitMQ 客户端框架,而不是单独使用 RabbitMQ 的客户端
3. 无论如何消费者必须给回 ACK 响应
ACK 机制就是消费者从 RabbitMQ 收到消息并处理完成后,反馈给 RabbitMQ,然后 RabbitMQ 收到反馈后才将此消息从队列中删除。
由于 ACK 机制本身必须回复给 RabbitMQ,消息才会丢弃这个特点。对于何时给 ACK,我们做开发的时候一定要在开发项目前提前规划好、设计好。
我们使用 RabbitMQ 通常不想在收到消息就立即给回 ACK 的,也不会设置 autoACK 机制即消费端收到自动返回一个 ACK 响应。一般来讲,我们都会根据业务逻辑的不同,会在不同的位置手动返回 ACK。
这时候,就可能出现问题:当收到消息,有时候处理业务逻辑报错了,往往在处理完业务逻辑就会忽略 ACK,这会导致消息始终卡死在 queue 里……如果数量越来越多,后续处理非常麻烦。
4. 考虑设置 dead letter exchanges
为什么那么多人不设置 dead letter exchanges?这是我非常疑惑的点。
出去和各类使用 RabbitMQ 的项目团队交流,发现很少人设置了 dead letter exchanges。这个是有问题的。
我们得知道,有时候消息投递出错,并不总是在应用接收的时候出了问题,会有很多非应用的问题。比如:
消费端有问题,发出的消息被拒绝了。并且我们也设置了 requeue=false;
消息可能因为没有收到 ACK 超时被删除,或者消费端消费速度跟不上导致消息超时被删除;
消息数量超过了队列最大长度限制被抛弃;
消息总大小超过了队列消息总大小限制被抛弃。
对于这些问题,设置 dead letter exchanges 算是一个解决办法。
当消息一旦出现我上面列举出来的情况,就会被发送到我们设置的 dead letter exchanges。然后我们就可以对这些特殊情况的消息进行单独处理,这样的做法可以让我们的项目更健壮,更容易追踪问题。
5. 尽量使用 Direct Exchange
RabbitMQ 的Exchange 就是消息交换机,它指定消息按什么规则,路由到哪个队列。
这家伙有四种类型:
Direct:处理路由键,需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键为“green”,则只有路由键为“green”的消息才被转发,不会转发路由键为"red",只会转发路由键为“green”。
Topic:将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”只能匹配一个词。
Fanout:不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到该类型交换机的消息都会被广播到与该交换机绑定的所有队列上。
Headers:不处理路由键,而是根据发送的消息内容中的 headers 属性进行匹配。在绑定 Queue 与 Exchange 时指定一组键值对;当消息发送到 RabbitMQ 时会取到该消息的 headers 与 Exchange 绑定时指定的键值对进行匹配;如果完全匹配则消息会路由到该队列,否则不会路由到该队列。
在这四种类型里,Direct 类型的 Exchange 投递消息是最快的。其他的 Exchange,MQ 还得花时间计算投递的位置。
所以,能使用 Direct 类型的建议使用 Direct。
以上就是在使用 RabbitMQ 前,需要考虑使用的规范,有了这些规范,很多程序员就能据此写出比较稳定健壮的程序,而不会导致各种莫名其妙的问题。
强烈建议大家在团队使用之前,先弄一份规范。否则,如果很多程序员使用 RabbitMQ 非常随意,容易导致出现各种幺蛾子问题。
在下一篇文章里,我将写一些开发中需要注意的事项。
虽说是开发需要注意的事项,其实就是我在开发一套成熟的 RabbitMQ 客户端框架时,碰到的各种问题的总结。如果有些读者所在的开发团队恰好也有类似的经历,那么我说的所有问题,你会发现你可能都会遇到。
我们下篇文章见!
我准备了一些纯手打的高质量PDF:
深入浅出Java多线程、HTTP超全汇总、Java基础核心总结、程序员必知的硬核知识大全、简历面试谈薪的超全干货。别看数量不多,但篇篇都是干货,看完的都说很肝。
领取方式:扫码关注后,在公众号后台回复:666

我最近建了一个读者交流群,里面大部分是程序员,一起聊技术、工作、八卦。欢迎加我微信,拉你入群。

用RabbitMQ了好几年之后,我总结出来5点RabbitMQ的使用心得的更多相关文章
- RabbitMQ从零到集群高可用(.NetCore5.0) - RabbitMQ简介和六种工作模式详解
一.RabbitMQ简介 是一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,RabbitMQ是使用Erlang(高并发语言)语言来编写的,并且RabbitMQ是基于AMQ ...
- RabbitMQ从概念到使用、从Docker安装到RabbitMQ整合Springboot【1.5w字保姆级教学】
@ 目录 一.前言 二.RabbitMQ作用 1. 异步处理 2. 应用解耦 3. 流量控制 三.RabbitMQ概念 1. RabbitMQ简介 2. 核心概念 四.JMS与AMQP比较 五.Rab ...
- rabbitmq
send端 import pika credentials = pika.PlainCredentials(') connection = pika.BlockingConnection(pika.C ...
- 初识RabbitMQ,附RabbitMQ+PHP演示实例
RabbitMQ是一个在AMQP基础上实现的企业级消息系统.何谓消息系统,就是消息队列系统,消息队列是""消费-生产者模型""的一个典型的代表,一端往消息队列中 ...
- Mac搭建PHP+rabbitMQ环境
RabbitMQ是一个在AMQP基础上实现的企业级消息系统.何谓消息系统,就是消息队列系统,消息队列是“”消费-生产者模型“”的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取或者订阅 ...
- rabbitMQ 安装,集群搭建, 编码
RabbitMQ 一.背景 命令行工具: http://www.rabbitmq.com/man/rabbitmqctl.1.man.html 介绍入门文章: http://blog.csdn.net ...
- 微服务中使用MQ——RabbitMQ
概念 什么是消息 消息是指在两个独立的系统间传递的数据.这两个系统可以是两台计算机,也可以是两个进程. 消息是平台无关和语言无关的! 什么是队列 队列是一种数据结构,内部是用数组或链表实现的, 队列的 ...
- 编译安装Erlang+RabbitMQ
楔子 由于国内信创越来越火,客户现场也开始使用国产操作系统替换CentOS之类的开源操作系统,最近做实施的同事找到我,说现场是ARM架构的操作系统编译安装RabbitMQ一直提示无法启动也没有日志文件 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
随机推荐
- 【kinetic】操作系统探索总结(八)键盘控制
如果尝试过前面的例子,有没有感觉每次让机器人移动还要在终端里输入指令,这也太麻烦了,有没有办法通过键盘来控制机器人的移动呢?答案室当然的了.我研究了其他几个机器人键盘控制的代码,还是有所收获的,最后移 ...
- javaweb登陆实例
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncod ...
- LInux学习笔记之常用命令
以下命令主要是平时用到的命令,对于一些经常用到的,就收集资料,归纳一下. 指令目录: 1.yum命令: 2.wget命令: 3.tar命令: 4../configure,make,make insta ...
- Daphile FAQ -- 官方文档译文 [原创]
Daphile FAQ 英文原文:https://www.daphile.com/download/FAQ.txt 采集日期:2021-01-03 常见问题解答:(FAQ) Q1:没有声音.Daphi ...
- Appium自动化如何控制多设备并行执行
前言: 如何做到,控制多设备并行执行测试用例呢. 思路篇 我们去想下,我们可以获取参数的信息,和设备的信息,那么我们也可以针对每台设备开启不一样的端口服务.那么每个服务都对应的端口,我们在获取设备列 ...
- mysql 双主复制 windows10
1. 整体思路 MySQL开始复制是很简单的过程,不过,根据特定的应用场景,都会在基本的步骤上有一些变化.最简单的场景就是一个新安装的master和slave,整个过程如下:(1)在每个服务器上创建一 ...
- java使用正则的例子
package com.accord.util; import java.util.ArrayList; import java.util.List; import java.util.regex.M ...
- 建立索引和创建视图(结合YGGL.sql)
一.请按要求对YGGL库建立相关索引 (1)使用create index 语句创建索引 1.对employees表中的员工部门号创建普通索引depart_ind. mysql> create i ...
- Qt开发的应用记录读取用户习惯设置的方法
Qt开发的应用记录读取用户习惯设置的方法 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/w ...
- Python3爬取小说并保存到文件
问题 python课上,老师给同学们布置了一个问题,因为这节课上学的是正则表达式,所以要求利用python爬取小说网的任意小说并保存到文件. 我选的网站的URL是'https://www.biquka ...