消息队列大杂烩,kafka,rocketmq,rabbitmq专题

Kafka安装以及kafka的特性。

Java安装

步骤1 - 验证Java安装

验证Java是否已安装:

$ java -version

如果Java未安装,继续下一步。

步骤1.1 - 下载JDK

访问Oracle官网下载最新版本的JDK:
Download the Latest Java LTS Free
例如,最新版本为JDK 8u60,文件名为jdk-8u60-linux-x64.tar.gz

步骤1.2 - 提取文件

进入下载路径并解压文件:

$ cd /path/to/download
$ tar -zxf jdk-8u60-linux-x64.tar.gz

步骤1.3 - 移动到选择目录

将Java移动到/opt/jdk目录:

$ su
password: (输入root用户密码)
$ mkdir /opt/jdk
$ mv jdk-1.8.0_60 /opt/jdk/

步骤1.4 - 设置路径

将以下内容添加到~/.bashrc文件中:

export JAVA_HOME=/opt/jdk/jdk-1.8.0_60
export PATH=$PATH:$JAVA_HOME/bin

应用更改:

$ source ~/.bashrc

步骤1.5 - Java替代

设置Java替代:

update-alternatives --install /usr/bin/java java /opt/jdk/jdk1.8.0_60/bin/java 100

步骤1.6 - 验证Java安装

验证Java版本:

$ java -version

ZooKeeper安装

步骤2.1 - 下载ZooKeeper

访问Apache ZooKeeper官网下载最新版本:
Apache ZooKeeper Releases
例如,最新版本为ZooKeeper 3.4.6,文件名为zookeeper-3.4.6.tar.gz

步骤2.2 - 提取tar文件

解压ZooKeeper文件:

$ cd /opt/
$ tar -zxf zookeeper-3.4.6.tar.gz
$ cd zookeeper-3.4.6
$ mkdir data

步骤2.3 - 创建配置文件

编辑conf/zoo.cfg文件:

$ vi conf/zoo.cfg

配置内容如下:

tickTime=2000
dataDir=/opt/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2

步骤2.4 - 启动ZooKeeper服务器

启动ZooKeeper:

$ bin/zkServer.sh start

启动成功后,输出如下:

JMX enabled by default
Using config: /path/to/zookeeper-3.4.6/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

步骤2.5 - 启动CLI

连接到ZooKeeper服务器:

$ bin/zkCli.sh

连接成功后,输出如下:

Connecting to localhost:2181
................
Welcome to ZooKeeper!
................
WATCHER::
WatchedEvent state:SyncConnected type: None path:null
[zk: localhost:2181(CONNECTED) 0]

步骤2.6 - 停止ZooKeeper服务器

停止ZooKeeper:

$ bin/zkServer.sh stop

Apache Kafka安装

步骤3.1 - 下载Kafka

访问Apache Kafka下载页面:
Apache Download Mirrors
下载最新版本kafka_2.11-0.9.0.0.tgz

步骤3.2 - 解压tar文件

解压Kafka文件:

$ cd /opt/
$ tar -zxf kafka_2.11-0.9.0.0.tgz
$ cd kafka_2.11-0.9.0.0

步骤3.3 - 启动Kafka服务器

启动Kafka服务器:

$ bin/kafka-server-start.sh config/server.properties

启动成功后,输出如下:

[2016-01-02 15:37:30,410] INFO KafkaConfig values:
request.timeout.ms = 30000
log.roll.hours = 168
inter.broker.protocol.version = 0.9.0.X
log.preallocate = false
security.inter.broker.protocol = PLAINTEXT

步骤4 - 停止Kafka服务器

停止Kafka服务器:

$ bin/kafka-server-stop.sh config/server.properties

关于kafka的消息模型:
image

RocketMQ和RabbitMQ学习提示

  • RocketMQ学习:可以参考Apache RocketMQ官网文档,了解其架构、特性及使用方法。官网地址:Apache RocketMQ
  • RabbitMQ学习:可以参考RabbitMQ官网文档,学习其安装、配置及消息队列的使用。官网地址:RabbitMQ
    Rocketmq的安装以及Rockemq的特性
    以下是整理后的整齐格式内容:

消息生产者代码

/***************************消息生产者***************************/
@Autowired
private MQTransactionListener mqTransactionListener;        // 事务消息监听器
// 消息生产者配置信息
@Value("${rocketmq.producer.namesrvAddr:127.0.0.1:9876}")
private String pNamesrvAddr;                                // 生产者 NameServer 地址
@Value("${rocketmq.producer.maxMessageSize:4096}")
private Integer maxMessageSize;                             // 消息最大大小,默认 4M
@Value("${rocketmq.producer.sendMsgTimeout:30000}")
private Integer sendMsgTimeout;                             // 消息发送超时时间,默认 30 秒
@Value("${rocketmq.producer.retryTimesWhenSendFailed:2}")
private Integer retryTimesWhenSendFailed;                   // 消息发送失败重试次数,默认 2 次
private static ExecutorService executor = ThreadUtil.newExecutor(32); // 执行任务的线程池

// 普通消息生产者
@Bean("default")
public DefaultMQProducer getDefaultMQProducer() {
    DefaultMQProducer producer = new DefaultMQProducer(this.groupName);
    producer.setNamesrvAddr(this.pNamesrvAddr);
    producer.setMaxMessageSize(this.maxMessageSize);
    producer.setSendMsgTimeout(this.sendMsgTimeout);
    producer.setRetryTimesWhenSendFailed(this.retryTimesWhenSendFailed);
    try {
        producer.start();
    } catch (MQClientException e) {
        System.out.println(e.getErrorMessage());
    }
    return producer;
}

// 事务消息生产者(RocketMQ 支持柔性事务)
@Bean("transaction")
public TransactionMQProducer getTransactionMQProducer() {
    // 初始化事务消息基本与普通消息生产者一致
    TransactionMQProducer producer = new TransactionMQProducer("transaction_" + this.groupName);
    producer.setNamesrvAddr(this.pNamesrvAddr);
    producer.setMaxMessageSize(this.maxMessageSize);
    producer.setSendMsgTimeout(this.sendMsgTimeout);
    producer.setRetryTimesWhenSendFailed(this.retryTimesWhenSendFailed);

    // 添加事务消息处理线程池
    producer.setExecutorService(executor);
    // 添加事务消息监听
    producer.setTransactionListener(mqTransactionListener);
    try {
        producer.start();
    } catch (MQClientException e) {
        System.out.println(e.getErrorMessage());
    }
    return producer;
}

消息类型

根据消息功能分类

  • 普通消息:最基本的发送类型。
  • 事务消息:用于保证多服务模块间的事务一致性。
    • 事务消息发送后会先生成一个半消息,进入事务消息监听器。
    • 确保事务提交成功后才会向 Broker 发送消息,消费者才能获取并消费。
  • 顺序消息:保证消息的顺序性。
  • 延时消息:可设置消息的延时发送时间。

根据发送方式分类

  • 同步消息:需要等待 Broker 响应,告知消息发送状态,常用于重要消息。
  • 异步消息:需要快速返回,通过回调代码块异步监听 Broker 响应。
  • 单向消息:对发送结果不敏感,无需监听 Broker 响应,常用于日志发送等。

消息优化建议

  • 尽量减小消息体积,选择轻量级协议。
  • 对于超过一定体积的消息,进行压缩处理。
  • 消息协议优先级:二进制协议 < 文本协议,文本协议中 JSON < XML。

生产者相关参数

参数名 参数说明
producerGroup 消息生产者组名,一个应用的消息生产者应归为同一个组
namesrvAddr 生产者 NameServer 地址
sendMsgTimeout 消息发送超时时间(单位:毫秒)
maxMessageSize 消息最大大小,默认为 4M
retryTimesWhenSendFailed 消息发送失败重试次数,默认为 2 次
executorService 事务消息处理线程池
transactionListener 事务消息监听器

消费者相关参数

参数名 参数说明
consumerGroup 消费者组名,一个应用的消息消费者应归为同一个组
namesrvAddr 消费者 NameServer 地址
consumeThreadMin 消费者线程最小线程数
consumeThreadMax 消费者线程最大线程数
subscribe 消费者订阅主题信息,* 表示订阅所有 Tag,指定 Tag 则使用具体值
consumeMessageBatchMaxSize 并发消费条数,默认为 1

消费模式

  • 集群消费模式(CLUSTERING):同组内多个实例均摊消费消息,一个实例消费后其他实例不再消费。适用于大部分消息业务。
  • 广播消费模式(BROADCASTING):同一消息会被同组内每个实例各自消费一次,ConsumerGroup 概念意义不大。适用于分发消息场景。

示例代码

  • 生产者发送消息示例

    Message message = new Message(MQ_CONFIG_TOPIC, MQ_CONFIG_TAG_PUSH, "KEY" + i, content.getBytes(RemotingHelper.DEFAULT_CHARSET));
    
  • 消费者订阅示例

    consumer.subscribe(MQ_CONFIG_TOPIC, MQ_CONFIG_TAG_PUSH);
    

RocketMQ 消费者默认配置

public DefaultMQPushConsumer(String consumerGroup, RPCHook rpcHook, AllocateMessageQueueStrategy allocateMessageQueueStrategy) {
    this.messageModel = MessageModel.CLUSTERING; // 默认为集群消费方式
    this.consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;
    this.consumeTimestamp = UtilAll.timeMillisToHumanString3(System.currentTimeMillis() - 1800000L);
    this.subscription = new HashMap<>();
    this.consumeThreadMin = 20; // 默认最小线程数
    this.consumeThreadMax = 64; // 默认最大线程数
    this.adjustThreadPoolNumsThreshold = 100000L;
    this.consumeConcurrentlyMaxSpan = 2000;
    this.pullThresholdForQueue = 1000;
    this.pullThresholdSizeForQueue = 100;
    this.pullThresholdForTopic = -1;
    this.pullThresholdSizeForTopic = -1;
    this.pullInterval = 0L;
    this.consumeMessageBatchMaxSize = 1; // 默认一次消费一条消息
    this.pullBatchSize = 32; // 默认批量拉取 32 条消息
    this.postSubscriptionWhenPull = false;
    this.unitMode = false;
    this.maxReconsumeTimes = -1;
    this.suspendCurrentQueueTimeMillis = 1000L;
    this.consumeTimeout = 15L;
    this.consumerGroup = consumerGroup;
    this.allocateMessageQueueStrategy = allocateMessageQueueStrategy;
    this.defaultMQPushConsumerImpl = new DefaultMQPushConsumerImpl(this, rpcHook);
}

关于RocketMQ的架构图
image
image

参考资料

RocketMQ的消费模式
image
生产者发的消息:
image
关于消费者的代码
image
偏移量的概念
image
各个消息模式
image
用countdownlatch控制异步发送和同步发送策略:
image
异步发送之前的代码
image
连续启动两个消费者
在每个消费者接收到的消息顺序都保持顺序
消息的重试:
image
就是这个消息没有被提交之后被重新提交到这个队列了.....
重新提交给这个队列去进行消费了
image
例如发送了0到9的消息
第一个消费者接收到了0,1,2,4。
第二个消费者接收到了其他的。
这就是顺序消费。
全局消息队列:
用一个broker,一个消息队列完成
image
rabbitmq中接收到延迟消息要通过死信队列实现。
通过一个特殊的类实现批量发送消息
image
批量消息的大小受到两个东西限制:
image
一个是broker的大小,一个本身官方的定义的消息大小
RocketMQ的死信队列的具体意义和思考角度
image

posted @ 2025-07-04 17:50  ruo_feng  阅读(23)  评论(0)    收藏  举报
-->