文章目录
设计消息中心的主要原因
1.实现系统解耦
各个子系统或者组件通过消息中心进行通信,而不是直接调用,这可以实现系统解耦,降低各组件之间的依赖性。这有利于系统的稳定性、扩展性和维护性。
2.异步处理
消息中心实现的是异步通信机制,这可以帮助我们实现异步处理任务或者流程。生产者投递消息后不需要等待消费者的响应,继续处理其他任务。这有助于提高处理效率。
3.流量削峰
利用消息队列,可以实现消息缓冲,在高峰期将消息暂存于队列中,待处理资源释放后再进行消费。这有助于应对高并发场景,防止系统崩溃。
4.自动重试
消费发生异常时,消息并不会丢失,会重新回到队列中。消费者可以定期重新消费,实现自动重试机制。这有助于提高系统的稳定性。
5.顺序保证
某些场景下,消息消费需要保证顺序。消息中心利用队列的先入先出特性,可以实现消息有序消费。
6.消息投递保障
利用消息队列,生产环境的重要消息可以实现持久化存储。这样即使消费者在处理消息的过程中发生故障,也不会导致消息丢失。消费者重启后可以重新消费消息,从而确保消息不会遗漏。
7.流量控制
通过消息中心,可以实现对消息生产和消费速率的管控。当下游处理能力上不去时,可以通过速率限制避免消息堆积过快;当处理能力释放时,也可以accordion提高速率。这有助于避免系统崩溃。
总之,设计消息中心主要是为了实现系统解耦,支持异步处理,削峰限流,自动重试,顺序保障,消息可靠投递以及流量控制等目的。它是构建一个稳定可靠、灵活可扩展的系统架构的核心组件之一。
但引入消息中心也会增加系统的复杂性,需要对消息传输过程进行严密管理,避免消息丢失或重复消费等情况出现。所以,是否需要消息中心,还需要结合具体的系统架构和业务场景进行权衡。
其具体典型的设计与实现如下(这里以RocketMQ为例,给出一个简单的消息中心设计与实现):
1.消息格式定义
首先需要定义消息的通用格式和协议,一般包含消息ID、消息类型、消息体、时间戳等字段。格式常用JSON,XML或自定义二进制格式。
以JSON格式定义消息:
{
"id": "msg_001",
"type": "ORDER_CREATE",
"content": {
"orderNo": "123456789",
"productCode": "P123456789"
},
"timestamp": 1577836800
}
2.消息发送
提供消息发送与接收的API,供系统内各业务模块调用。发送API一般需要接收消息体、消息类型、接收者列表等参数
使用RocketMQ提供的发送API:
Message msg = new Message("TOPIC1", "ORDER_CREATE", "{'orderNo':'12345'}".getBytes(RemotingHelper.DEFAULT_CHARSET));
SendResult sendResult = rocketMQProducer.send(msg);
3.消息接收API
接收API一般返回一个消息队列或流供业务模块消费。
使用RocketMQ提供的接收API:
// 定义消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("CID1");
// 设置消费者订阅的Topic和Tag
consumer.setNamesrvAddr("127.0.0.1:9876");
consumer.subscribe("TOPIC1", "*");
// 注册消费者监听并设置消费逻辑
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
// 消费逻辑
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者
consumer.start();
4.消息队列
实现消息的异步传输和解耦合合,一般用到消息队列中间件,如Kafka、RabbitMQ、RocketMQ等。这些消息队列能实现消息的管道化和缓冲。
RocketMQ本身就是一款消息队列产品,会隐式使用其消息队列功能。
5.消息分发
当生产者产生消息时,需要实现分发机制将消息投递到指定接收者或接收组。这需要在消息和接收者之间建立关联关系,一般通过配置的形式完成。
通过RocketMQ的Topic实现消息分发,生产者定义发送到哪个Topic,消费者订阅该Topic即可获取消息。
6.消息并发控制
考虑到高并发场景下消息的产生速度可能远远超过消费速度,需要实现機制避免消息堆积过多而导致系统崩溃。常用的方式是设置消息队列大小限制和拒绝策略。
RocketMQ支持设置各个主题的队列数和消息大小限制,可以通过这两者避免消息堆积过多。
7.消息可靠性
为保证消息不丢失,通常需要消息中心实现消息持久化、消息回溯、消息补发等机制。持久化一般用数据库完成;回溯和补发利用消息队列中的消息历史轨迹实现。
RocketMQ支持持久化,同时提供延迟队列和死信队列功能,可以保证消息不丢失。
8.系统监控
消息中心作为一个关键的基础组件,需要提供丰富的监控指标和监控接口,包括消息产生速率、消息堆积量、消息消费速率、连接数、时延等关键指标的监测。
RocketMQ提供丰富的Dashboard和Metrics用于监控消息产生与消费的速率、时延、堆积等指标。
9.权限管理
对消息中心的访问需要进行权限管理,不同的系统模块和用户应具有不同的权限,如某些模块只能发送消息而不能消费消息。权限管理一般通过登录认证结合配置的方式完成。
RocketMQ提供基于用户、权限、角色的访问控制功能,可以控制用户对Topic的读写权限。
以上就是一个简单的RocketMQ消息中心设计与实现的示例。利用RocketMQ提供的完备服务,我们可以快速构建一套消息中心方案,实现系统内各模块的异步解耦和通信。RocketMQ只是众多消息队列产品的一种选择,其它如Kafka、RabbitMQ也同样具备实现消息中心的全部功能。可以根据业务场景具体选择和设计。
写在最后
如果大家对相关文章感兴趣,可以关注公众号"架构殿堂",会持续更新AIGC,java基础面试题, netty, spring boot,spring cloud等系列文章,一系列干货随时送达!