MassTransit & RabbitMq 实战开发指南

2020-06-29  本文已影响0人  Skeeh

一、什么是消息队列(MQ)

相比消息队列可能大家更熟悉队列这一种先进先出的数据结构,那消息队列就可以简单的理解为:把要传输的数据放在队列中。相应的把数据放在消息队列的就叫做生产者,从消息队列里面取数据则叫做消费者

二、为什么要用消息队列?

2.1 异步

从单一业务场景出发,用户下单支付成功后流程结束,假如支付需要耗时100ms则响应时间则为100ms,但随着业务体量的不断扩大用户下单后还需要做扣减优惠券、增减积分、发送短信等操作那这种场景下链路越长流程越多则响应时间越久,假如各操作的耗时如下图,(同步方式)则响应时间为500ms。

越来越庞杂的业务体量

当然,我们可以用异步的方式同时处理增加的流程。假如支付耗时不变,(异步方式)则响应时间为100ms。

异步方式处理增加的流程

但异步处理方式的同时也带来了耦合度过高的问题当其中一个流程出现异常时很可能就会影响其他流程,并且增加一个流程就要调用一个接口然后重新发布系统,由此带来的问题排查也比较麻烦。这就不得不谈到引入消息队列的下一个优点:解耦。

2.2 解耦

当客户下单成功后订单系统将支付成功的消息写入消息队列,其他服务收到后去做相应的处理,后面的话即使再接入其他的系统那直接订阅发送的支付成功的消息就可以了,就是你支付成功其他服务监听。

例如用户下单后订单系统完成持久化处理将消息写入消息队列,返回用户订单下单成功,此时库存系统订阅下单的消息采用拉/推的方式获取下单的信息,然后库存系统根据下单信息进行相应的操作。整个过程中即使库存系统出现异常也不会影响正常下单,因为下单后,订单系统将消息写入消息队列后就不再关心其他后续操作,实现了订单系统与库存系统的应用解耦。

引入消息中间件


但引入消息中间件的同时也会带来很多问题,比如提高系统复杂性,数据一致性(分布式事务),高可用性(集群/分布式)等都是需要考虑的问题。

2.3 削峰/限流

流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛因为可以缓解短时间的高流量导致压垮应用。

就拿电商中的秒杀活动举例,当活动开始时流量瞬间提升后因为服务器、Redis、MySql各自的承受能力都不一样,若还是照单全收的话整个系统就很有可能出现宕机,若是引入消息中间件的话服务器就可以先将所有请求放到队列里然后各系统根据自身能够处理的最大请求数去每秒消费多少请求。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

三、怎么用消息队列

3.1 在Docker环境中部署RabbitMQ(单机模式),需要的命令如下:

1.docker search rabbitmq:management    —— 搜索rabbitmq镜像,以“management”结尾的镜像版本,是包含网页控制台的;

2.docker pull rabbitmq:management    ——  拉取镜像,可以直接键入此命令拉取镜像;

3.docker run -d --hostname rabbit --name myrabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:management  ——  启动RabbitMQ。

指令说明:-d 后台运行容器;--name 指定容器名;--hostname 主机名(RabbitMQ的一个重要注意事项是它根据所谓的 “节点名称” 存储数据,默认为主机名) ;-p 指定服务运行端口(5672:应用访问端口;15672:控制台Web端口号);-e 指定环境变量;(RABBITMQ_DEFAULT_VHOST:默认虚拟机名;RABBITMQ_DEFAULT_USER:默认的用户名;RABBITMQ_DEFAULT_PASS:默认用户名的密码);-v 映射目录或文件。

容器启动之后就可以访问web管理端:http://宿主机IP:15672,默认创建了一个guest用户,密码也是guest。


3.2 启动多个RabbitMQ,需要的命令如下:

docker run -d --hostname rabbit01 --name myrabbitmq01 -p 15672:15672 -p 5672:5672 rabbitmq:management

docker run -d --hostname rabbit02 --name myrabbitmq02 -p 15673:15672 -p 5673:5672 rabbitmq:management

这样我们就可以使用,http://宿主机IP:15672 和http://宿主机IP:15673 进行访问了,默认账号密码依旧是guest/guest。


3.3 在Docker环境中部署RabbitMQ(普通集群模式),需要的命令如下:

步骤一:运行RabbitMQ

1. docker run -d --hostname rabbit01 --name myrabbitmq01 -p 5672:5672 -p 15672:15672 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:management

2. docker run -d --hostname rabbit02 --name myrabbitmq02 -p 5673:5672 -p 15673:15672 --link myrabbitmq01:rabbit01 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:management

3. docker run -d --hostname rabbit03 --name myrabbitmq03 -p 5674:5672 -p 15674:15672 --link myrabbitmq01:rabbit01 --link myrabbitmq02:rabbit02 -e RABBITMQ_ERLANG_COOKIE='rabbitmqCookie' rabbitmq:managemen

步骤二:加入RabbitMQ节点到集群

设置节点1:

docker exec -it myrabbitmq01 bash

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl start_app

exit

设置节点2,加入到集群:

docker exec -it myrabbitmq02 bash

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl join_cluster --ram rabbit@rabbit01

rabbitmqctl start_app

exit

设置节点3,加入到集群:

docker exec -it myrabbitmq03 bash

rabbitmqctl stop_app

rabbitmqctl reset

rabbitmqctl join_cluster --ram rabbit@rabbit01

rabbitmqctl start_app

exit

所有命令如下:

以集群方式部署RabbitMQ

最终效果如下:

启动了3个节点,1个磁盘节点和2个内存节点

参考文章:使用Docker部署RabbitMQ集群;你不知道的RabbitMQ集群架构全解

四、利用MassTransit集成RabbitMQ

上一篇下一篇

猜你喜欢

热点阅读