为了账号安全,请及时绑定邮箱和手机立即绑定

RocketMQ IM和业务服务沟通学习入门教程

概述

本文详细介绍了RocketMQ在IM系统和业务服务中的应用,包括用户状态同步、实时消息推送和业务数据处理等功能。通过RocketMQ实现异步通信,能够提高系统的性能、可靠性和可扩展性。文章还提供了详细的配置与部署指南以及示例代码,帮助读者更好地理解和学习RocketMQ IM和业务服务沟通的相关知识。RocketMQ IM和业务服务沟通学习涵盖了多种应用场景和实现方式。

RocketMQ 简介
RocketMQ 基础概念

RocketMQ 是一款由阿里巴巴开源的分布式消息中间件,适用于多种大规模分布式系统中的消息传输需求。它不仅支持异步消息传递,还支持分布式事务处理,能够满足实时处理的需求。RocketMQ 的设计主要考虑了高可用性、高可扩展性、高可靠性和高性能等特性。

消息模型

RocketMQ 支持两种消息模型:同步消息模型和异步消息模型。

  • 同步消息模型:消息发送者发送消息后等待消息接收者的响应。这种模型适用于需要等待处理结果的场景。
  • 异步消息模型:消息发送者发送消息后不需要等待响应,可以立即返回。这种模型适用于不需要等待结果的场景,能够提升系统的响应速度和吞吐量。

主要组件

  • NameServer:NameServer 是一个无状态的服务节点,负责管理 Broker 的注册信息,提供查询服务。
  • Broker:Broker 是 RocketMQ 的消息处理节点,负责消息的存储和转发。Broker 负责接收消息、存储消息、转发消息到消费者。
  • Producer:Producer 是消息的生产者,负责将消息发送到 Broker。
  • Consumer:Consumer 是消息的消费者,负责从 Broker 订阅并消费消息。
  • 消息队列:消息队列是存储消息的实体,一个 Topic 对应一个或多个消息队列。
  • Topic:Topic 是 RocketMQ 中的消息分类,相当于一个逻辑上的主题。
  • Tag:Tag 是消息的标签,用于进一步细分消息。
  • Message:消息是 RocketMQ 中的基本单位,包含消息体、消息属性等。
RocketMQ 的主要特点和优势
  • 高可用性:RocketMQ 具有非常高的可用性,支持主备节点和集群模式,保证在单点故障的情况下依然能够正常运行。
  • 高可扩展性:RocketMQ 支持水平扩展,可以通过增加 Broker 实例来提升系统的处理能力和存储能力。
  • 高性能:RocketMQ 在消息传输方面具有非常高的性能,每秒能够处理数百万条消息。
  • 高可靠性:RocketMQ 通过多副本和持久化机制保证消息的可靠传输,支持消息的回溯和重复消费。
  • 丰富功能:RocketMQ 提供了丰富的功能,如消息过滤、消息重试、消息延时、事务消息等。
IM 系统与 RocketMQ 的集成
IM 系统概述

即时通讯(IM,Instant Messaging)系统是一种实时在线沟通系统,主要功能包括文本消息、语音通话、视频通话、文件传输等。IM 系统的核心在于实时消息传递和用户状态同步。

IM 系统的关键组件

  • 用户管理:管理用户的登录、注册和状态。
  • 消息传递:实时传输文本、语音、视频等数据。
  • 会话管理:管理用户之间的会话。
  • 消息存储:存储历史消息,支持消息的回溯。
  • 消息推送:将消息推送到用户的客户端。
  • 消息状态同步:同步消息发送和接收的状态。
RocketMQ 在 IM 系统中的应用场景

RocketMQ 在 IM 系统中主要用于消息的异步传输和实时推送,提高系统的可靠性和性能。具体应用场景包括:

  • 用户状态同步:实时同步用户在线状态信息,提高用户体验。
  • 消息推送:将消息推送到用户客户端,通常需要支持多种消息类型。
  • 会话管理:实时更新会话状态,如新消息提醒、未读消息计数等。
  • 消息存储与回溯:存储用户之间的历史消息,支持消息的回溯功能。
  • 负载均衡:通过 RocketMQ 的消息分发机制,实现消息的负载均衡。

案例分析

假设我们有一个 IM 系统,需要实时推送新消息到用户的客户端。可以使用 RocketMQ 实现这个功能,具体的实现如下:

  1. 生产者发送消息:当有新消息时,IM 系统的生产者将消息发送到 RocketMQ 的指定 Topic 和 Tag。
  2. 消费者消费消息:用户客户端订阅指定 Topic 和 Tag 的消息,当有新消息时,实时接收并处理。

示例代码

生产者发送消息

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class Producer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("TopicTest", // topic
                "TagA", // tag
                ("Hello RocketMQ").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}

消费者消费消息

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class Consumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("TopicTest", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive New Messages: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}
业务服务与 RocketMQ 的交互
业务服务的基本概念

业务服务是指企业或组织内部运行的系统和服务,用于完成特定的业务逻辑和流程。例如,电商系统的订单处理、物流系统的信息跟踪、金融系统的交易处理等。业务服务通常需要处理大量的数据和复杂的逻辑,因此需要使用高效的消息中间件来实现异步通信。

业务服务的关键组件

  • 业务逻辑处理:处理业务逻辑,如订单处理、支付处理等。
  • 数据存储:存储业务数据,如订单信息、用户信息等。
  • 服务治理:管理服务的注册、发现和调用。
  • 消息传递:通过消息中间件实现异步通信。
业务服务如何利用 RocketMQ 实现异步通信

RocketMQ 作为高效的消息中间件,能够帮助业务服务实现消息的异步传输和负载均衡。具体实现方式如下:

发布-订阅模式

业务服务通过生产者发送消息到 RocketMQ 的指定 Topic,其他服务通过订阅该 Topic 的消息来实现消息的消费。这种方式能够实现解耦合和负载均衡,提升系统的可扩展性和可靠性。

示例代码

生产者发送消息到 RocketMQ

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class BusinessProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("BusinessProducer");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("BusinessTopic", // topic
                "BusinessTag", // tag
                ("Business Message").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}

消费者订阅并消费消息

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class BusinessConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("BusinessConsumer");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("BusinessTopic", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive Business Message: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}
RocketMQ 配置与部署
快速安装 RocketMQ

安装 RocketMQ 的步骤如下:

  1. 下载 RocketMQ
    下载 RocketMQ 的压缩包,可以从 Apache 官方网站下载最新版本。

  2. 解压压缩包
    使用命令行工具解压压缩包到指定目录。

  3. 配置环境变量
    根据需要配置环境变量,如设置 JAVA_HOME 和 ROCKETMQ_HOME。

  4. 启动 NameServer
    进入解压后的目录,启动 NameServer。

    cd rocketmq-4.9.4
    sh bin/mqnamesrv

    启动后,将会输出 NameServer 的运行信息,包括端口号等。

  5. 启动 Broker
    启动 Broker 服务。

    sh bin/mqbroker -n localhost:9876

    启动后,将会输出 Broker 的运行信息,包括端口号等。

  6. 验证安装成功
    可以通过访问 NameServer 的控制台来验证是否安装成功。
基本配置项介绍

RocketMQ 的配置文件通常位于 conf 目录下,主要包括 broker.conflogback 配置文件。

broker.conf

broker.conf 配置文件中包含了 Broker 的基本配置项,如 NameServer 地址、Broker 名称、数据目录等。

# Broker 名称
brokerName=broker-a
# NameServer 地址
namesrvAddr=localhost:9876
# 消息文件目录
storePathRootDir=/opt/message
# 日志文件目录
storePathCommitLog=/opt/message/commitlog
# 日志文件滚动时间(毫秒)
fileReservedTime=172800000

logback

logback 配置文件用于设置 RocketMQ 的日志输出配置,如输出格式、日志滚动策略等。

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/opt/message/rocketmq.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/opt/message/rocketmq.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
``

# RocketMQ 消息生产和消费

## 发送消息到 RocketMQ

发送消息到 RocketMQ 的步骤如下:

1. **创建生产者实例**:
   使用 `new DefaultMQProducer` 方法创建生产者实例。

2. **设置 NameServer 地址**:
   调用 `setNameserverAddress` 方法设置 NameServer 地址。

3. **启动生产者**:
   调用 `start` 方法启动生产者。

4. **创建消息**:
   使用 `Message` 类创建消息,设置消息的 Topic、Tag 和 Body。

5. **发送消息**:
   调用 `send` 方法发送消息。

6. **关闭生产者**:
   调用 `shutdown` 方法关闭生产者。

### 示例代码

```java
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class MessageProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("ProducerGroupName");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("TopicTest", // topic
                "TagA", // tag
                ("Hello RocketMQ").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}
订阅和消费消息

RocketMQ 提供了消息订阅和消费的功能,通过消费者的订阅来接收并处理消息。

消费者订阅消息

消费者订阅指定 Topic 的消息,并设置消息的过滤条件。

  1. 创建消费者实例
    使用 new DefaultMQPushConsumer 方法创建消费者实例。

  2. 设置 NameServer 地址
    调用 setNameserverAddress 方法设置 NameServer 地址。

  3. 设置 Topic
    调用 subscribe 方法设置消费者订阅的 Topic 和 Tag。

  4. 启动消费者
    调用 start 方法启动消费者。

  5. 注册消息监听器
    调用 registerMessageListener 方法注册消息监听器,处理接收到的消息。

示例代码

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class MessageConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("ConsumerGroupName");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("TopicTest", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive New Messages: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}
实战案例:RocketMQ 在 IM 和业务服务中的应用
使用 RocketMQ 解决 IM 和业务服务沟通中的实际问题

假设我们有一个 IM 系统和一个业务服务,需要实现用户状态同步、实时消息推送和业务数据处理等功能。可以使用 RocketMQ 实现这些功能,具体实现如下:

用户状态同步

用户登录或退出时,IM 系统发送用户状态变化的消息到 RocketMQ,业务服务订阅这些消息并同步用户状态。

示例代码

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class UserStatusProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("UserStatusProducer");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 用户登录消息
        Message loginMsg = new Message("UserStatus", // topic
                "Login", // tag
                ("User 123456 Logged In").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 用户退出消息
        Message logoutMsg = new Message("UserStatus", // topic
                "Logout", // tag
                ("User 123456 Logged Out").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送登录消息
        SendResult sendResult = producer.send(loginMsg);
        System.out.printf("%s%n", sendResult);

        // 发送退出消息
        sendResult = producer.send(logoutMsg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class UserStatusConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("UserStatusConsumer");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("UserStatus", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                String body = new String(msg.getBody());
                if (body.contains("Logged In")) {
                    System.out.printf("User Logged In: %s%n", body);
                } else if (body.contains("Logged Out")) {
                    System.out.printf("User Logged Out: %s%n", body);
                }
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}

实时消息推送

IM 系统向用户客户端推送新消息,通过 RocketMQ 实现异步消息推送。

示例代码

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class MessagePushProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("MessagePushProducer");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 创建消息
        Message msg = new Message("MessagePush", // topic
                "NewMessage", // tag
                ("New Message to User 123456").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送消息
        SendResult sendResult = producer.send(msg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class MessagePushConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("MessagePushConsumer");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("MessagePush", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive New Messages: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}

业务数据处理

业务服务通过 RocketMQ 发送和接收业务数据,实现异步业务处理。

示例代码

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;

public class BusinessDataProducer {
    public static void main(String[] args) throws Exception {
        // 创建生产者实例
        DefaultMQProducer producer = new DefaultMQProducer("BusinessDataProducer");
        // 设置 NameServer 地址
        producer.setNameserverAddress("localhost:9876");
        // 启动生产者
        producer.start();

        // 创建业务数据消息
        Message businessMsg = new Message("BusinessData", // topic
                "OrderCompleted", // tag
                ("Order 123456 Completed").getBytes(RemotingHelper.DEFAULT_CHARSET), // body
                1024 // body length
        );

        // 发送业务数据消息
        SendResult sendResult = producer.send(businessMsg);
        System.out.printf("%s%n", sendResult);

        // 关闭生产者
        producer.shutdown();
    }
}
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;

public class BusinessDataConsumer {
    public static void main(String[] args) throws Exception {
        // 创建消费者实例
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("BusinessDataConsumer");
        // 设置 NameServer 地址
        consumer.setNameserverAddress("localhost:9876");
        // 设置 Topic
        consumer.subscribe("BusinessData", "*");
        // 设置从何处开始消费
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
        // 注册消息监听器
        consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
            for (MessageExt msg : msgs) {
                System.out.printf("Receive Business Data: %s%n", new String(msg.getBody()));
            }
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        });
        // 启动消费者
        consumer.start();
    }
}
案例分析与总结

通过使用 RocketMQ 实现 IM 系统和业务服务之间的异步通信,能够提升系统的性能、可靠性和可扩展性。RocketMQ 的高可用性和高性能特性能够保证消息的可靠传输,支持大规模分布式系统中的消息传输需求。同时,RocketMQ 的灵活配置和丰富的功能能够满足各种业务场景的需求。

总结

  • 高可用性:RocketMQ 能够保证在单点故障的情况下依然能够正常运行,具有非常高的可用性。
  • 高性能:RocketMQ 每秒能够处理数百万条消息,能够满足大规模分布式系统中的高性能需求。
  • 灵活配置:RocketMQ 提供了灵活的配置选项,可以根据实际需求进行定制化配置。
  • 丰富的功能:RocketMQ 提供了丰富的功能,如消息过滤、消息重试、消息延时、事务消息等,能够满足各种业务场景的需求。

通过本文的介绍和示例代码,读者可以深入了解 RocketMQ 的使用方法和应用场景,为实际项目中的应用提供参考。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消