持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第28天,点击查看活动详情
消息中间件 rocketmq
消息队列作为高并发系统的核心组件之一,能够帮助业务系统解构提升开发效率和系统稳定性。主要具有以下优势:
- 削峰填谷(主要解决瞬时写压力大于应用服务能力导致消息丢失、系统奔溃等问题)
- 系统解耦(解决不同重要程度、不同能力级别系统之间依赖导致一死全死)
- 提升性能(当存在一对多调用时,可以发一条消息给消息系统,让消息系统通知相关系统)
- 蓄流压测(线上有些链路不好压测,可以通过堆积一定量消息再放开来压测)
目前主流的MQ主要是Rocketmq、kafka、Rabbitmq,Rocketmq相比于Rabbitmq、kafka具有主要优势特性有:
- 支持事务型消息(消息发送和DB操作保持两方的最终一致性,rabbitmq和kafka不支持)
- 支持结合rocketmq的多个系统之间数据最终一致性(多方事务,二方事务是前提)
- 支持18个级别的延迟消息(rabbitmq和kafka不支持)
- 支持指定次数和时间间隔的失败消息重发(kafka不支持,rabbitmq需要手动确认)
- 支持consumer端tag过滤,减少不必要的网络传输(rabbitmq和kafka不支持)
- 支持重复消费(rabbitmq不支持,kafka支持)
Rocketmq 的架构及基本概念
基本概念
Producer 消息生产者,生产者的作用就是将消息发送到 MQ,生产者本身既可以产生消息,如读取文本信息等。
也可以对外提供接口,由外部应用来调用接口,再由生产者将收到的消息发送到 MQ。
Producer Group 生产者组,简单来说就是多个发送同一类消息的生产者称之为一个生产者组。在这里可以不用关心,只要知道有这么一个概念即可。
Consumer 消息消费者,简单来说,消费 MQ 上的消息的应用程序就是消费者,至于消息是否进行逻辑处理,还是直接存储到数据库等取决于业务需要。
Consumer Group 消费者组,和生产者类似,消费同一类消息的多个 consumer 实例组成一个消费者组。
Topic Topic 是一种消息的逻辑分类,比如说你有订单类的消息,也有库存类的消息,那么就需要进行分类,一个是订单 Topic 存放订单相关的消息,一个是库存 Topic 存储库存相关的消息。
Message Message 是消息的载体。一个 Message 必须指定 topic,相当于寄信的地址。Message 还有一个可选的 tag 设置,以便消费端可以基于 tag 进行过滤消息。也可以添加额外的键值对,例如你需要一个业务 key 来查找 broker 上的消息,方便在开发过程中诊断问题。
Tag 标签可以被认为是对 Topic 进一步细化。一般在相同业务模块中通过引入标签来标记不同用途的消息。
Broker Broker 是 RocketMQ 系统的主要角色,其实就是前面一直说的 MQ。Broker 接收来自生产者的消息,储存以及为消费者拉取消息的请求做好准备。
Name Server Name Server 为 producer 和 consumer 提供路由信息。
部署架构
名称服集群务 NameServer cluster
NameServer服务提供了轻量级的服务发现和路由。每个NameServer服务记录完整的路由信息,提供一致的读写服务,支持快速存储扩展
代理服务集群 Broker Cluster
Broker通过提供轻量级主题和队列机制来处理消息存储。它们支持Push和Pull模型,包含容错机制(2个副本或3个副本),提供了极强的峰值处理里能力和按照时间顺序存储数以百万记的消息存储能力,此外,代理提供了灾难恢复、丰富的度量统计和警报机制,这些都是在传统的消息传递系统中缺乏的
生产者集群 Producer Cluster
produce支持分布式部署,分布式的produce通过broker集群提供的各种负载均衡策略将消息发送到broker集群中。发送过程支持快速失败是低延迟的。
消费者集群 Consumer Cluster
消费者也支持在推送和者拉取模式下分布式部署,它还支持集群消费和消息广播。提供实时的消息订阅机制,能够满足大多数消费者的需求。RocketMQ的网站为感兴趣的用户提供了一个简单的快速入门指南。
名称服务NameServer
NameServer是一个功能齐全的服务器,主要包括两个功能:
- broker 管理,nameserver 接受来自broker集群的注册信息并提供心跳来检测他们是否可用。
- 路由管理 每一个nameserver都持有关于broker集群和队列的全部路由信息,用来向客户端提供查询。
我们知道 ,rocketMQ客户端(生产者/消费者)会从nameserver查询队列的路由信息,客户端是如何知道nameserver的地址的呢?
有四种方式能够让客户端获取到nameserver的地址:
- 通过程序,像这样producer.setNamesrvAddr(“ip:port”)
- java 配置项,这么用rocketmq.namesrv.addr
- 环境变量 NAMESRV_ADDR
- HTTP 端点
代理服务 broker server
broker server负责消息的存储传递,消息查询,保证高可用等等。
像下图所示,broker server有一些非常重要的子模块:
- remoting(远程) 模块,broker的入口,处理从客户端发起的请求。
- client manager(客户端管理) 管理各个客户端(生产者/消费者)还有维护消费者主题订阅。
- store(存储服务),提供简单的api来在磁盘保持或者查询消息。
- HA 高可用服务 提供主从broker的数据同步。
- index(索引服务)为消息建立索引提供消息快速查询。