MQ的常用场景 && 最佳实践

RocketMQ

消息队列 RocketMQ 版是阿里云基于 Apache RocketMQ 构建的低延迟、高并发、高可用、高可靠的分布式消息中间件。消息队列 RocketMQ 版既可为分布式应用系统提供异步解耦和削峰填谷的能 力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性。


建议统一消息格式

统一消息格式,message由两部分组成
MQ的常用场景 && 最佳实践_第1张图片

  • id:由生产者生成,每次不重复,代表一条消息。消费者可用于做幂等。

  • timestamp:消息的创建时间,消费方可根据业务需求,拒绝某个时间点前的消息。

  • traceId: 链路id,用于追溯业务链路。

  • payload:业务数据。


异步解耦

最常见的一个场景是用户注册后,需要发送注册邮件和短信通知,以告知用户注册成功。

传统实现(串行):

MQ的常用场景 && 最佳实践_第2张图片
以上三个任务全部完成后,才返回注册结果到客户端,用户才能使用账号登录。

假设每个任务耗时分别为 50 ms,则用户需要在注册页面等待总共需要 150 ms 才能登录。

异步解耦实现:

对于用户来说,注册功能实际只需要注册系统存储用户的账户信息后,该用户便可以登录,后续的注册短信和邮件不是即时需要关注的步骤。

对于注册系统而言,发送注册成功的短信和邮件通知并不一定要绑定在一起同步完成,所以实际当数据写入注册系统后,注册系统就可以把其他的操作放入对应的消息队列 RocketMQ 版中然后马上返回用户结果,由消息队列 RocketMQ 版异步地进行这些操作。
MQ的常用场景 && 最佳实践_第3张图片


分布式事务的数据一致性方案

1、本地消息表

本地消息表这种实现方式应该是业界使用最多的,其核心思想是将分布式事务拆分成本地事务进行处理,这种思路是来源于ebay。我们可以从下面的流程图中看出其中的一些细节:

MQ的常用场景 && 最佳实践_第4张图片

基本思路就是:

消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。

消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。

2、事务消息处理

主要用来保证本地事务和消息发送,要么同时成功要么同时失败。

事务消息交互流程如下:
MQ的常用场景 && 最佳实践_第5张图片

  • 生产者将消息发送至MQ服务端,MQ服务端会将消息持久化至文件中;
  • MQ服务端向发送方返回 Ack 确认消息已经发送成功,此时发送方开始执行本地事务逻辑;
  • 发送方根据本地事务执行结果向服务端提交本地事务结果(Commit 或是 Rollback),服务端收到 Commit 状态则将事务消息标记为可投递,订阅方开始消费该消息;

消息的顺序收发

顺序消息分为两种情况:

全局顺序:对于指定的一个 Topic,所有消息将按照严格的先入先出(FIFO)的顺序,进行顺序发布和顺序消费;

分区顺序:对于指定的一个 Topic,所有消息根据 Sharding Key 进行区块分区,同一个分区内的消息将按照严格的 FIFO 的顺序,进行顺发布和顺序消费,可以保证一个消息被一个进程消费。


削峰填谷

流量削峰也是消息队列 MQ 的常用场景,一般在秒杀或团队抢购活动中使用广泛。

在秒杀或团队抢购活动中,由于用户请求量较大,导致流量暴增,秒杀的应用在处理如此大量的访问流量后,下游的通知系统无法承载海量的调用量,甚至会导致系统崩溃等问题而发生漏通知的情况。为解决这些问题,可在应用和下游通知系统之间加入MQ 。


大规模机器的缓存同步

双十一大促时,各个分会场会有玲琅满目的商品,每件商品的价格都会实时变化。使用缓存技术也无法满足对商品价格的访问需求,缓存服务器网卡满载。访问较多次商品价格查询影响会场页面的打开速度。

此时需要提供一种广播机制,一条消息本来只可以被集群的一台机器消费,如果使用消息队列的广播消费模式,那么这条消息会被所有节点消费一次,相当于把价格信息同步到需要的每台机器上,取代缓存的作用。

你可能感兴趣的:(架构之路,MQ)