朋友们晚上好,我是今晚的分享老师kason

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java


今晚给大家带来的分享主题是《Rabbitmq千万级订单量的企业实战》

场景:我所在的公司每天会有千万级别的订单生成,其中各服务对于订单消息的变更和订单流转均是通过Rabbitmq来进行传递的,因此我们的业务场景对Rabbitmq属于重度依赖者,历史上也曾因为Rabbitmq的一些问题导致过几次高级别的严重事故。经过对这些故障的复盘,我们对Rabbitmq有了更深入的了解和使用经验。

下面我们来看一张简单的订单流程图

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_02

用户通过平台下单之后,会生成一条订单消息messageA,这个订单消息被发送到x这个exchange,之后根据routingkey进行对应的投递,支付成功的消息messageB会被配送服务的接口拉取进行下一步的操作。

当然更加复杂的订单流转带有较强的业务属性,有兴趣的同学可以在分享结束后,联系我们的课程顾问,和分享讲师进行更深入的交流。

什么是Rabbitmq

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

RabbitMQ主要是为了实现系统之间的双向解耦而实现的。当生产者大量产生数据时,消费者无法快速消费,那么需要一个中间层。保存这个数据。


为什么选择Rabbitmq

对于消息中间件来说有 kafka、activeMQ、ZeroMq和Rabbitmq,为什么选择Rabbitmq?

1、有人曾经做过activeMQ、ZeroMQ和Rabbitmq三者之间的压测,分析下来activeMQ的TPS最差,Rabbitmq居中,zeroMQ的TPS最高;但是在持久化方面,zeroMQ暂时不支持持久化,也就是说MQ down或者MQ所在的服务器down,消息是会丢失的。在业务上,我们是需要持久化机制的。所以,这点上业务不会选择zeroMQ;

2、高并发上,RabbitMQ的实现语言是天生具备高并发高可用的erlang语言;

3、淘宝的余峰曾经写过这样一篇文章《我为什么要选择RabbitMQ》,这篇文章也描述了Rabbitmq的一些优势;

4、大名鼎鼎的openstack就是使用Rabbitmq作为内部的消息服务器的。

除了以上的优势之外,Rabbitmq还有以下的特点:

可靠性:RabbitMQ提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制。

灵活的路由:消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用。

在提供的内置交换机4种类型中,我们有使用到其中三种,分别是Direct exchange(直连交换机),Topic exchange(主题交换机)和 Fanout exchange(扇型交换机)

那么下面简单说下这几种类型的工作方式,以便于大家更好的理解

    • direct:转发消息到routingKey指定的队列,routingKey是消息的一个属性,由生产者加在消息头中。

    • 如下图所示

      马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_03

X -> Q1 有一个 routingkey,routingKey为 orange;X -> Q2 有 2个routingKey,routingKey为black和green。当消息中的路由键 和这个routingkey对应上的时候,那么就知道了该消息去到哪一个队列中。

    • topic:按规则(通配符)转发消息,这种交换机下,队列和交换器的绑定会定义一种路由模式,通配符就要在这种路由模式和路由键之间匹配后交换机才能转发消息。

    • 如下图所示

      马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_04

X -> Q1 有一个路由模式 *.orange.* 来匹配任何 A.orange.B 类似为路由键的消息;X -> Q2 有两个路由模式 *.*.rabbit 和 lazy.# 来匹配任何 A.B.rabbitmq 和 lazy.A、lazy.A.B或lazy.A.B.C类似为路由键的消息。

其中,井号(#)就表示相当于一个或者多个单词。

    • fanout:转发消息到所有绑定队列,如果不同的consumer需要对同样的消息进行不同的处理,那么这种方式是很有用的。

    • 如下图所示

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_05

这种类型的交换器不管路由键或者是路由模式,会把消息发给绑定给它的全部队列

    • headers:这个模型的交换器用的不多,有兴趣的同学可以查阅相关文档进行了解。

集群

以上就是exchange相关的内容,再跟随我的步伐来看下集群

集群在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用。

目前我们线上的服务均是通过集群的形式来工作的,根据TPS、处理消息的量级来调整集群中机器的数量;

在马哥视频中也详细讲到了Rabbitmq集群的安装,后面会有专门的内容来介绍集群的安装,大家不要着急,请继续往下看。

高可用队列:在同一个集群里,队列可以被镜像到多个机器中,以确保当其中某些硬件出现故障后,你的消息仍然安全。

在我们的实际使用中也有用到镜像的方式,通过在cluster的基础上增加ha-mode、ha-param等policy选项,可以根据需求将cluster中的队列镜像到多个节点上,从而实现高可用,消除cluster模式中队列内容单点带来的风险。

广泛的客户端:只要是你能想到的编程语言几乎都有与其相适配的RabbitMQ客户端。

我们公司目前有java、python、go等三大主流语言,对于我们来说,Rabbitmq有多样的客户端也是比较适合我们公司的。

可视化管理工具:Rabbitmq还给我们提供了易于使用的可视化管理工具,它可以帮助你监控消息代理的每一个环节。

可视化管理工具可以通过命令来启用,也可以禁用;

rabbitmq-plugins enable rabbitmq_management    // 启用

rabbitmq-plugins disable rabbitmq_management    // 禁用

插件系统:RabbitMQ附带了各种各样的插件来对自己进行扩展。你甚至也可以写自己的插件来使用。

通过命令可以获取到rabbitmq支持的插件

rabbitmq-plugins list -v

好的,以上就是对Rabbitmq特性的完整介绍,相信经过以上的介绍,大家肯定想知道Rabbitmq的工作模型吧。  

Rabbitmq的模型

Rabbitmq使用的是AMQP协议,它是一种二进制协议,默认启动端口为5672

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_06

P 代表 生产者,也就是往 RabbitMQ 发消息的程序。

中间即是 RabbitMQ,其中包括 交换机 和 队列。

C 代表 消费者,也就是从 RabbitMQ 拿消息的程序。

这个模型也可以想象成一个发放优惠券的消息队列,优惠券一般由平台或者商家生成,在这个图中P我们认为是商家,商家按照一定的消费额度生成对应的优惠券,比如常见的满50减10,满100减30等,这个优惠券(id)通过消息发送到不同的消费者中,或者消费者点击领取活动按钮进行按钮来领取优惠券放入个人账户中,当然,优惠券的最终状态是落在DB里面进行存储的。通过对上面的例子,我们对Rabbitmq的工作模型应该有了更加深入的了解。

怎样搭建集群

下面再来看下马哥视频中是如何来搭建集群的。

在搭建集群之前,需要满足下面条件:

  1. 所有机器上,必须Erlang运行时和RabbitMQ的版本相同。(否则会不能连接到一起)

  2. 所有机器上,的Erlang的Cookie都相同。

下面将为大家说下4台机器为集群的搭建方式,4台机器依次的主机名为node1至node4:

1、在node1至node4上安装以下服务

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_07

2、查看node1节点的erlang.cookie,将其复制到另外三台,保证cookie一致

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_08

 3、加入集群,以node1为例加入集群

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_09

4、查看其它三台加入集群状态为

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_10

5、更改node1,node2节点为ram

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_11

6、重新查看节点状态:

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_12

7、增加用户

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_13

8、开启管理界面

马哥金牌分享 | Rabbitmq千万级订单量的企业实战_java_14

9、使用用户名和密码访问 http://ip:15672 

建议:建议大家使用Rabbitmq 3.6.9 以上的版本和erlang最新版本

以上就是安装的整个过程,看下来安装还是比较简单、容易上手的。

总结

通过以上对Rabbitmq的了解,最后我们再来看下Rabbitmq如何帮助到我们的?

RabbitMQ是一个消息代理 - 一个消息系统的媒介。它可以为你的应用提供一个通用的消息发送和接收平台,并且保证消息在传输过程中的安全。

随着系统压力的增大和系统解耦的急迫性,各大应用之间通过消息互相连接起来组成了一个更大的应用,并且消息系统通过将消息的发送和接收分离来实现应用程序的异步和解耦。

通过接入rabbitmq解决了数据投递,非阻塞操作和推送通知的操作,实现了发布/订阅,异步处理和工作队列的问题。