【云小课】应用平台第19课 消息中间件之-分布式消息服务RocketMQ版
在电商场景中,促销活动已经成为不可或缺的一个环节,如618、双11、双12等。促销时,电商系统会面临如下问题:
-
活动开始时,海量的订单提交,订单系统在处理完这些订单后,下游的子系统(如物流系统、通知系统等)是否可以承受海量的调用量?
-
一笔订单的成功交易涉及到多个子系统(如订单系统、库存系统、积分系统等)协同工作,如果其中一个子系统故障,将会导致整个系统崩溃。怎样确保系统的稳定性?
-
用户下单后,并未对该订单付款,一段时间后系统能否在没有人工干预的情况下自动删除此订单,释放库存给其他用户购买?
解决以上难题的一大利器就是华为云分布式消息服务RocketMQ版。
什么是分布式消息服务RocketMQ版呢?它又是怎么解决以上问题的?
什么是分布式消息服务RocketMQ版?
介绍分布式消息服务RocketMQ版前,先来了解下什么是消息中间件。
消息中间件是分布式系统中重要的组件,本质就是一个具有接受消息、存储消息、分发消息的队列,应用程序通过读写出入队列来通信。当前业界使用比较广泛的消息中间件为Kafka、RabbitMQ和RocketMQ等。
分布式消息服务RocketMQ版是一个低延迟、弹性高可靠、高吞吐、动态扩展、便捷多样的消息中间件服务。兼容开源RocketMQ客户端,提供顺序、延迟、定时、重投、死信、事务消息、会话消息等功能,可以更好地适配电商、金融等多样的业务场景。
分布式消息服务RocketMQ版可以实现如下功能:削峰填谷、异步解耦、消息延迟发送等等,下面具体为大家介绍下分布式消息服务RocketMQ版是怎样实现这些功能的。
削峰填谷
削峰填谷指的是在瞬间大流量的冲击下,利用分布式消息服务RocketMQ版抗住流量突增,保护系统的稳定性。
电商促销活动开始时,海量订单提交,订单系统在处理完这些订单后,下游的子系统(如物流系统、通知系统等)由于性能问题,无法承受海量的调用量,导致子系统崩溃。
为解决此问题,我们可以在订单系统和下游子系统之前增加分布式消息服务RocketMQ版,订单系统将请求发送到分布式消息服务RocketMQ版,下游子系统根据自身性能从分布式消息服务RocketMQ版获取消息,并处理。
异步解耦
耦合指2个或以上应用通过相互作用而彼此影响的现象,异步解耦就是使用分布式消息服务RocketMQ版将核心应用和非核心应用隔离开,减少应用间的相互作用相互影响,提高了系统的响应速度。
如下图所示,在每个子系统都正常运行的情况下,完成一次订单所需时间为50ms+30ms+70ms+100ms=250ms。如果其中一个子系统(如通知系统)故障,会导致整个业务无法使用,用户下单失败。
用户下单购物时,第一时间关心的是有没有下单成功,而快递什么时候发、积分是不是增加了等事件不是立刻会关心的步骤。对于订单业务,订单系统处理完订单,库存系统扣减相应库存,订单数据库更新完订单状态后,就可以返回下单成功的信息给用户。而物流系统、积分系统、促销系统和通知系统非核心应用,可以后续异步去处理。因此,我们在订单系统和非核心应用(如物流系统、通知系统等)之间增加分布式消息服务RocketMQ版,实现核心应用和非核心应用的隔离,如下图所示。
增加分布式消息服务RocketMQ版后,完成一次订单的时间为50ms+30ms+70ms+10ms=160ms,对比改造前的250ms,系统的响应速度增加了。非核心应用(如通知系统)故障后,不会影响订单业务,只是发送短信的时间延长了。
消息延迟发送
利用分布式消息服务RocketMQ版的延迟消息功能可以实现消息发送后,不会立刻发送给消费者消费,而是延迟到特定时间后才会发送给消费者进行消费。
电商场景中,经常会遇到用户下单后不付款的情况,一段时间后商家需要关闭这些未付款的订单,释放库存给其他用户购买。那么商家怎样关闭这些未付款订单呢?一个个手动关闭是可行的,但是促销活动时,订单量太大,这种方法显然是既耗时又耗力,且效率很差。有没有办法无需人工干预,自动删除此订单,释放库存给其他用户购买呢?
分布式消息服务RocketMQ版支持延迟消息,可以很好的解决此问题。用户下单后,订单系统生成订单,并发送一条延迟消息给分布式消息服务RocketMQ版。分布式消息服务RocketMQ版收到消息后,延迟到设置的时间后,检查订单数据库中订单状态,如果未支付,则关闭此订单。如果已支付,则不做任何处理。
消息中间件如何选型?
华为云当前支持三种消息中间件:Kafka、RabbitMQ、RocketMQ,他们之间的区别如下表所示。
功能项 |
RocketMQ |
Kafka |
RabbitMQ |
优先级队列 |
不支持 |
不支持 |
支持。建议优先级大小设置在0-10之间。 |
延迟队列 |
支持 |
不支持 |
支持 |
死信队列 |
支持 |
不支持 |
支持 |
消息重试 |
支持 |
不支持 |
不支持 |
消费模式 |
支持客户端主动拉取和服务端推送两种方式。 |
客户端主动拉取。 |
支持客户端主动拉取以及服务端推送两种模式。 |
广播消费 |
支持 |
支持 |
支持 |
消息回溯 |
支持 |
支持。Kafka支持按照offset和timestamp两种维度进行消息回溯。 |
不支持。RabbitMQ中消息一旦被确认消费就会被标记删除。 |
消息堆积 |
支持 |
支持。考虑吞吐因素,Kafka的堆积效率比RabbitMQ总体上要高。 |
支持 |
持久化 |
支持 |
支持 |
支持 |
消息追踪 |
支持 |
不支持 |
支持。RabbitMQ中可以采用Firehose或者rabbitmq_tracing插件实现,但开启rabbitmq_tracing插件会影响性能,建议只在定位问题过程中开启。 |
消息过滤 |
支持 |
支持 |
不支持,但可以自行封装。 |
多租户 |
支持(待规划) |
不支持 |
支持 |
多协议支持 |
兼容RocketMQ协议。 |
只支持Kafka自定义协议。 |
RabbitMQ基于AMQP协议实现,同时支持MQTT、STOMP等协议。 |
跨语言支持 |
支持多语言的客户端。 |
采用Scala和Java编写,支持多种语言的客户端。 |
采用Erlang编写,支持多种语言的客户端。 |
流量控制 |
支持(待规划) |
支持client和user级别,通过主动设置可将流控作用于生产者或消费者。 |
RabbitMQ的流控基于Credit-Based算法,是内部被动触发的保护机制,作用于生产者层面。 |
消息顺序性 |
单队列(queue)内有序。 |
支持单分区(partition)级别的顺序性。 |
不支持。需要单线程发送、单线程消费并且不采用延迟队列、优先级队列等一些高级功能整体配合,才能实现消息有序。 |
安全机制 |
支持SSL认证。 |
支持SSL、SASL身份认证和读写权限控制。 |
与Kafka相似。 |
事务性消息 |
支持 |
支持 |
支持 |
-
RocketMQ基于Java语言开发,适用于对数据可靠性、数据实时性要求高,Topic数量非常多的场景,如订单、交易、充值、流计算、消息推送、日志流式处理、binglog分发等。
-
Kafka基于Pull的模式来处理消息消费,适用于追求高吞吐量、对延迟不敏感、Topic数量可控、对于消息丢失不敏感的场景,如日志采集、大数据场景的MySQL-2Hive、MySQL-2-Flink的数据流通道、日志数据流通道等。
-
RabbitMQ基于Erlang语言开发,不利于做二次开发和维护,适用于对路由、负载均衡、数据一致性、稳定性和可靠性要求很高,对性能和吞吐量的要求没那么高的场景。
与开源RocketMQ有哪些差异?
华为云分布式消息服务RocketMQ版在兼容开源RocketMQ基础上,对版本特性做了一定程度的定制和增强。
功能项 |
分布式消息服务RocketMQ版 |
开源RocketMQ |
延迟消息 |
支持 |
支持 |
顺序消息 |
支持 |
支持 |
消息重试 |
支持 |
支持 |
死信消息 |
支持 |
支持 |
集群消费 |
支持 |
支持 |
广播消费 |
支持 |
支持 |
死信队列 |
支持 |
支持 |
消费重置 |
支持 |
支持 |
消息查询 |
支持 |
支持 |
加密传输 |
支持 |
支持 |
消息轨迹 |
支持 |
支持 |
事务消息 |
支持 |
支持 |
死信导出 |
支持 |
不支持 |
动态规格变更 |
待规划 |
不支持 |
链路诊断 |
待规划 |
不支持 |
数据转储 |
待规划 |
不支持 |
如果您想获取分布式消息服务RocketMQ版的使用指导,戳这里
如果您想获取开源客户端访问分布式消息服务RocketMQ版来收发消息的示例,戳这里
如果您想获取RocketMQ业务迁移的指导,戳这里
- 点赞
- 收藏
- 关注作者
评论(0)