【RabbitMQ】事务机制、限流、负载均衡

RabbitMQ的事务机制

RabbitMQ的事务机制用于确保消息在生产、传输和消费过程中的可靠性。通过事务机制,可以确保消息在出现异常时不会丢失或重复消费。

事务机制的操作

在RabbitMQ中,事务机制的操作包括以下三个步骤:

  1. 开启事务channel.txSelect()

    开启事务模式,告知RabbitMQ接下来的操作需要事务控制。

  2. 提交事务channel.txCommit()

    提交事务,确认所有消息成功发布或处理。

  3. 回滚事务channel.txRollback()

    发生异常时回滚事务,撤销所有未提交的操作。


事务机制的优缺点

优点:

  • 可靠性高,确保消息不会丢失。

缺点:

  • 性能较低,每条消息都要等待事务提交或回滚,严重影响吞吐量。
  • 较少用于高并发场景,更多使用Confirm机制来替代事务机制。

Spring Boot中使用RabbitMQ事务

1. 引入依赖

pom.xml中添加RabbitMQ依赖:

复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. 配置文件(application.yml)

    spring:
    rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

3. 生产者代码

在生产者中使用事务控制:

java 复制代码
package com.example.rabbitmq.producer;

import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.TransactionCallback;
import org.springframework.amqp.rabbit.transaction.RabbitTransactionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.Transactional;

@Configuration
public class RabbitMQConfig {

    @Bean
    public RabbitTransactionManager rabbitTransactionManager(ConnectionFactory connectionFactory) {
        return new RabbitTransactionManager(connectionFactory);
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setChannelTransacted(true);  // 开启事务
        return template;
    }
}
  1. 生产消息
java 复制代码
package com.example.rabbitmq.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MessageProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Transactional  // 事务注解
    public void sendMessage(String exchange, String routingKey, String message) {
        try {
            rabbitTemplate.convertAndSend(exchange, routingKey, message);
            System.out.println("消息发送成功:" + message);
        } catch (Exception e) {
            System.err.println("消息发送失败:" + e.getMessage());
            throw e;  // 触发事务回滚
        }
    }
}
  1. 消费者代码
java 复制代码
package com.example.rabbitmq.consumer;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MessageConsumer {

    @Transactional  // 事务注解
    @RabbitListener(queues = "test-queue")
    public void receiveMessage(String message) {
        System.out.println("接收到消息:" + message);
        if ("error".equals(message)) {
            throw new RuntimeException("消费失败,触发事务回滚");
        }
    }
}

RabbitMQ的限流和负载均衡

在RabbitMQ中,限流负载均衡是确保系统在高并发和大流量场景下稳定运行的关键机制。以下是这两个机制的详细介绍:


一、限流(流量控制)

RabbitMQ中的限流机制通过**Qos(Quality of Service)**来实现。

核心方法是:

  • basicQos(int prefetchCount):用于限制消费者每次拉取的消息数量。
  • prefetchCount
    • 1:消费者一次只接收一条消息,处理完后才继续接收下一条。
    • n:消费者可以同时处理n条消息。
    • 0:没有限制(默认)。

作用

  1. 防止消费者压力过大导致消息堆积。
  2. 保证消费者逐条确认,避免消息丢失。

二、负载均衡

RabbitMQ的负载均衡是通过轮询分发公平分发来实现的:

  1. 轮询分发(Round-Robin)

    • 默认模式。
    • 消息均匀地分配给每个消费者。
    • 缺点:无法考虑消费者的消费能力差异,导致性能不均衡。
  2. 公平分发(Fair Dispatch)

    • 结合Qos机制实现。
    • 通过设置prefetchCount=1,使消费者处理完消息后才继续获取下一条,保证消息不会被堆积在性能较差的消费者上。

三、Spring Boot中实现限流和负载均衡

配置文件方式(application.yml)

我们可以直接在配置文件中进行消费者并发数、预取数量(限流)等配置:

示例配置文件(application.yml)
java 复制代码
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
        concurrency: 5            # 最小并发消费者数量
        max-concurrency: 10       # 最大并发消费者数量
        prefetch: 1               # 每个消费者每次只接收1条消息(限流)
        acknowledge-mode: manual  # 手动确认消息

二、生产者代码

java 复制代码
package com.example.rabbitmq.producer;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MessageProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMessage(String message) {
        rabbitTemplate.convertAndSend("test-queue", message);
        System.out.println("消息发送:" + message);
    }

    public void sendBatchMessages() {
        for (int i = 1; i <= 20; i++) {
            sendMessage("Message " + i);
        }
    }
}

三、消费者代码

java 复制代码
package com.example.rabbitmq.consumer;

import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class MessageConsumer {

    @RabbitListener(queues = "test-queue")
    public void receiveMessage(String message, Channel channel) throws Exception {
        try {
            System.out.println(Thread.currentThread().getName() + " 接收到消息:" + message);
            Thread.sleep(1000); // 模拟耗时操作
            channel.basicAck(channel.getNextPublishSeqNo(), false); // 手动确认
        } catch (Exception e) {
            channel.basicNack(channel.getNextPublishSeqNo(), false, true); // 失败重新入队
            System.err.println("消费失败:" + message);
        }
    }
}

四、配置解读

在配置文件中,我们通过以下几个参数来控制限流和负载均衡:

  1. concurrency:最小并发消费者数量。
  2. max-concurrency:最大并发消费者数量,动态调整消费者数量。
  3. prefetch:每次拉取的消息数量(限流)。
  4. acknowledge-mode:手动确认消息消费成功,防止消息丢失。
相关推荐
别说我什么都不会3 小时前
OpenHarmony源码分析之分布式软总线:trans_service模块(1)/认证通道管理
分布式·嵌入式·harmonyos
Pitayafruit4 小时前
【📕分布式锁通关指南 08】源码剖析redisson可重入锁之释放及阻塞与非阻塞获取
redis·分布式·后端
Pandaconda4 小时前
【后端开发面试题】每日 3 题(十二)
数据库·后端·面试·负载均衡·高并发·后端开发·acid
爱敲代码的三毛5 小时前
Java操作RabbitMQ
java·rabbitmq·java-rabbitmq
Cloud_.6 小时前
RabbitMQ 基本原理详解
spring boot·分布式·后端·rabbitmq
百锦再7 小时前
在 CentOS 上安装 Oracle 数据库
数据库·分布式·安全·oracle·centos·关系型
爱敲代码的三毛7 小时前
RabbitMQ可靠性进制
java·分布式·rabbitmq
落霞的思绪7 小时前
RabbitMQ:业务幂等、死信交换机
分布式·rabbitmq·ruby
Jeremy_10227 小时前
RocketMQ分布式场景篇
分布式·rocketmq