Skip to main content

RabbitMQ

RabbitMQ 是什么

RabbitMQ 是一个实现了 高级消息队列协议(AMQP, Advanced Message Queuing Protocol)的开源中间件, 一般的用途就是在各个系统之间接收消息,分发消息

用了有什么好处

引入 RabbitMQ 大致可以有以下三个好处

解耦

系统各个模块之间总会需要数据传递, 以前的单体应用会将所有模块全都做在一起, 好处是系统内的通信畅通无阻, 但是对于后续的扩展比较麻烦

所以需要对业务进行拆分, 根据业务模块拆分出多个可以独立部署运行的子系统, 比如订单系统,配送系统,通知系统,客户信息系统等

假设配送完成之后, 需要从 配送 发送消息给 订单 更新订单状态, 还需要发给 通知 提醒用户配送完成, 这时候可以选择在配送中分别调用订单通知的对应接口

乍一看没什么问题, 但业务总是会有变更的, 如果这时候出现一个第三方的系统, 也需要对接这个 配送完成 的消息, 那么就需要在 配送 中再加一次接口调用

这样的变更不止一处, 每个地方都这样处理就非常麻烦了, 所以可以通过某种配置动态进行调整

如果不考虑其他服务, 我们可以将地址写在类似 appsettings.json 这样的配置里, 这样只需要修改配置文件即可增减需要发送消息的地址

这种方式还是需要我们手动操作, 虽然省去了动代码的麻烦, 每次其它系统有业务变更还是需要做修改

此时就可以使用消息队列进行解耦

配送 只需要保证 配送完成 这个消息正常发送到消息队列即可, 至于有哪些系统需要使用这条消息, 就不是 配送 需要考虑的事情了

这样可以极大的简化各个系统之间的设计, 降低各系统之间的耦合

异步

以上一点为例, 配送 直接调用 订单通知 的接口

如果是以同步的方式调用, 除了执行 配送 自身业务的耗时以外, 还需要加上等待 订单通知 两个系统执行完成的总耗时

如果采用异步的方式调用, 除了执行 配送 自身业务的耗时以外, 还需要加上等待 订单通知 两个系统执行完成的最大耗时

若是两个系统中有任意一个调用失败, 即使该次 配送 业务执行成功了, 但也有可能会将自己的成功操作回滚

若是使用消息队列, 配送 只需要保证自己的消息发送成功即可, 订单通知 的处理并不会有影响

削峰

以上上一点为例, 配送 直接调用 订单通知 的接口

如果并发数量极高, 一次性有一万个 配送完成, 然后就同时调用了一万次 订单通知 接口, 此时可能会产生大量数据库io操作

会不会崩溃我不知道, 但是大概率会有阻塞

如果使用消息队列, 由于上一条的异步特性, 配送 的操作只到发送消息就结束了, 可以直接给 前端/客户端 返回操作成功的提示, 不用陪着一起阻塞卡死

消息发送成功后可以由 订单通知 自己决定如何处理这些消息, 不管是一次取一条一个一个处理, 亦或是一次取一千条批量处理, 总的数据库io操作也会比之前的方式少很多

如何部署

在这里只推荐使用docker部署, 不然需要装 erlang 环境, 太麻烦

docker run -itd -p 5672:5672 -p 15672:15672 --restart always --name rabbitmq rabbitmq:management

建议在实际部署的时候把端口换一下, 免得被人用默认端口攻击

最好设置一下默认的账号密码

docker run -itd \
-p 5672:5672 \
-p 15672:15672 \
-e RABBITMQ_DEFAULT_USER=rabbitmq \
-e RABBITMQ_DEFAULT_PASS=abc@123 \
--restart always \
--name rabbitmq \
rabbitmq:management