C#/.NET 微服务架构:从入门到精通(八):RabbitMQ 异步通信

上一篇我们完成了微服务架构的核心通信基础设施:通过 Consul 实现了服务注册与发现,通过 Ocelot 实现了统一 API 网关,现在我们的服务已经能够通过 HTTP 进行同步通信。但在高并发、高可用的生产场景中,同步调用存在无法回避的致命缺陷—— 服务之间强耦合、性能瓶颈、雪崩效应风险。

本篇将引入微服务架构的另一种核心通信模式:异步消息通信。我们将深度集成RabbitMQ(.NET 生态最成熟、最稳定的开源消息队列),实现服务之间的解耦通信,解决同步调用的痛点,让我们的微服务架构具备更高的可用性、可扩展性和容错能力。

一、微服务架构下,为什么必须要有异步通信?

1. 同步 HTTP 调用的三大致命痛点

在之前的架构中,订单服务创建订单时,需要同步调用用户服务扣减积分、调用商品服务扣减库存:

客户端 → 网关 → 订单服务 → 用户服务(扣积分)
                    ↓
                  商品服务(扣库存)

这种同步调用模式存在以下问题:

  • 强耦合:订单服务依赖用户服务和库存服务,任何一个下游服务不可用,订单创建就会失败;
  • 性能差:整个请求的响应时间等于所有下游服务响应时间之和,用户体验差;
  • 雪崩风险:如果库存服务宕机,会导致订单服务线程池耗尽,进而拖垮整个系统;
  • 无法削峰填谷:秒杀等流量高峰场景下,同步调用会直接将压力传导到所有下游服务,容易导致系统崩溃。

2. 异步消息通信的核心价值

引入 RabbitMQ 后,通信模式变为:

客户端 → 网关 → 订单服务 → RabbitMQ → 用户服务(异步扣积分)
                                  ↓
                                商品服务(异步扣库存)

异步通信带来了质的提升:

  • 彻底解耦:订单服务只需要发送消息到 RabbitMQ,不需要关心谁来消费、什么时候消费,下游服务宕机不影响订单创建;
  • 性能提升:订单服务发送消息后立即返回,响应时间从几百毫秒缩短到几毫秒;
  • 削峰填谷:RabbitMQ 作为缓冲层,将高峰流量缓存起来,下游服务按照自己的处理能力慢慢消费,保护系统不被冲垮;
  • 异步处理:非实时操作(如发送邮件、短信、日志记录)可以全部异步化,提升主流程的响应速度。

 3. 为什么选择 RabbitMQ?

对比 Kafka、RocketMQ 等其他消息队列,RabbitMQ 是.NET 微服务的首选:

  • 生态成熟:.NET 官方客户端稳定可靠,社区活跃,文档完善;
  • 功能丰富:支持多种交换机类型、消息确认、死信队列、延迟队列等企业级功能;
  • 可靠性高:支持消息持久化、生产者确认、消费者确认,确保消息不丢失;
  • 轻量级易部署:Docker 一键部署,资源占用低,适合中小规模微服务架构。

二、RabbitMQ 核心概念快速入门

在实战之前,我们先快速了解 RabbitMQ 的几个核心概念:

概念 说明
生产者(Producer) 发送消息的服务(如订单服务)
消费者(Consumer) 接收并处理消息的服务(如用户服务、商品服务)
交换机(Exchange) 接收生产者发送的消息,根据路由规则将消息路由到对应的队列
队列(Queue) 存储消息的缓冲区,消费者从队列中获取消息
绑定(Binding) 建立交换机和队列之间的关联关系,指定路由键
路由键(Routing Key) 交换机根据路由键将消息路由到匹配的队列

RabbitMQ 最常用的四种交换机类型:

  • Direct(直连):消息路由到与路由键完全匹配的队列(最常用)
  • Fanout(广播):消息路由到所有绑定到该交换机的队列
  • Topic(主题):支持通配符匹配路由键,灵活路由
  • Headers(头):根据消息头属性路由,很少使用

三、环境准备(基于 Docker 部署体系)

所有组件全部采用 Docker 部署,与我们之前的微服务架构完全兼容。

在新加一个用户服务(UserApi)

image

 

image

 

image

 四、实战步骤 1:Docker 部署 RabbitMQ 服务端

1.标准安装

docker run -d \
  --hostname rabbitmq-node \
  --name rabbitmq \
  --restart=always \
  -p 5672:5672 \
  -p 15672:15672 \
  -e RABBITMQ_DEFAULT_USER=admin \
  -e RABBITMQ_DEFAULT_PASS=your_secure_password \
  -e RABBITMQ_VM_MEMORY_HIGH_WATERMARK=1024MB \
  -v rabbitmq_data:/var/lib/rabbitmq \
  --memory=2g \
  --memory-reservation=1g \
  rabbitmq:3-management

关键参数详解:

  • --hostname rabbitmq-node:设置固定主机名(RabbitMQ 数据存储依赖主机名,集群部署必须)
  • --restart=always:Docker 服务启动时自动重启容器
  • -e RABBITMQ_DEFAULT_USER/PASS:创建自定义管理员用户(避免使用默认 guest)
  • -e RABBITMQ_VM_MEMORY_HIGH_WATERMARK:设置内存使用上限
  • -v rabbitmq_data:/var/lib/rabbitmq:使用 Docker 命名卷持久化数据
  • --memory=2g:限制容器最大使用 2GB 内存
  • --memory-reservation=1g:预留 1GB 内存给容器

2.检查容器运行状态

docker ps | grep rabbitmq

3.访问 Web 管理界面

浏览器打开:http://你的服务器IP:15672

使用上面设置的admin/your_secure_password登录

image

 五、实战步骤 2:封装通用 RabbitMQ 客户端

为了让所有服务能够复用 RabbitMQ 能力,我们将客户端封装在Commerce.Share共享类库中,通过依赖注入的方式使用。

image

1. 添加 RabbitMQ 配置选项

namespace Commerce.Share.RabbitMq;

/// <summary>
/// RabbitMQ配置选项
/// </summary>
public class RabbitMQOptions
{
    /// <summary>
    /// 服务名称
    /// </summary>
    public string HostName { get; set; } = "rabbitmq"; // Docker网络内通过服务名访问

    /// <summary>
    /// RabbitMQ服务器端口
    /// </summary>
    public int Port { get; set; } = 5672;

    /// <summary>
    /// 用户名
    /// </summary>
    public string UserName { get; set; } = "admin";

    /// <summary>
    /// 密码
    /// </summary>
    public string Password { get; set; } = "Admin@123456";

    /// <summary>
    /// 虚拟主机
    /// </summary>
    public string VirtualHost { get; set; } = "/";

    /// <summary>
    /// 连接超时时间
    /// </summary>
    public int ConnectionTimeout { get; set; } = 30000;

    /// <summary>
    /// 消息发送重试次数
    /// </summary>
    public int RetryCount { get; set; } = 3; // 消息发送重试次数
}

2. 定义消息生产者和消费者接口

namespace Commerce.Share.RabbitMq;

/// <summary>
/// 消息消费者接口
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IMessageConsumer<in T> where T : class
{
    /// <summary>
    /// 处理消息
    /// </summary>
    /// <param name="message">消息内容</param>
    Task HandleAsync(T message);
}
namespace Commerce.Share.RabbitMq;

/// <summary>
/// 消息生产者接口
/// </summary>
public interface IMessageProducer
{
    /// <summary>
    /// 发送消息
    /// </summary>
    /// <typeparam name="T">消息类型</typeparam>
    /// <param name="exchange">交换机名称</param>
    /// <param name="routingKey">路由键</param>
    /// <param name="message">消息内容</param>
    Task PublishAsync<T>(string exchange, string routingKey, T message) where T : class;
}

3. 实现 RabbitMQ 消息总线

using Microsoft.Extensions.Options;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System.Text;
using System.Text.Json;

namespace Commerce.Share.RabbitMq;

/// <summary>
/// RabbitMQ消息总线
/// </summary>
public class RabbitMQMessageBus : IMessageProducer, IDisposable
{
    private readonly IConnection _connection;
    private readonly IModel _channel;
    private readonly RabbitMQOptions _options;

    public RabbitMQMessageBus(IOptions<RabbitMQOptions> options)
    {
        _options = options.Value;

        // 创建连接工厂
        var factory = new ConnectionFactory
        {
            HostName = _options.HostName,
            Port = _options.Port,
            UserName = _options.UserName,
            Password = _options.Password,
            VirtualHost = _options.VirtualHost,
            RequestedConnectionTimeout = TimeSpan.FromMilliseconds(_options.ConnectionTimeout)
        };

        // 创建连接和通道
        _connection = factory.CreateConnection();
        _channel = _connection.CreateModel();

        Console.WriteLine("✅ RabbitMQ连接成功");
    }

    /// <summary>
    /// 发布消息到指定交换机和路由键
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="exchange"></param>
    /// <param name="routingKey"></param>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task PublishAsync<T>(string exchange, string routingKey, T message) where T : class
    {
        // 声明交换机(不存在则创建)
        _channel.ExchangeDeclare(exchange: exchange, type: ExchangeType.Direct, durable: true);

        // 序列化消息
        var json = JsonSerializer.Serialize(message);
        var body = Encoding.UTF8.GetBytes(json);

        // 发送消息(持久化消息)
        var properties = _channel.CreateBasicProperties();
        properties.Persistent = true; // 消息持久化,防止RabbitMQ重启后消息丢失

        _channel.BasicPublish(
            exchange: exchange,
            routingKey: routingKey,
            basicProperties: properties,
            body: body);

        await Task.CompletedTask;
        Console.WriteLine($"✅ 消息发送成功:Exchange={exchange}, RoutingKey={routingKey}");
    }

    /// <summary>
    /// 注册消费者
    /// </summary>
    public void RegisterConsumer<T>(string exchange, string queue, string routingKey, IMessageConsumer<T> consumer) where T : class
    {
        // ✅ 新增:先声明交换机(与生产者保持完全一致的参数)
        _channel.ExchangeDeclare(
        exchange: exchange,
        type: ExchangeType.Direct,
        durable: true,      // 持久化
        autoDelete: false,
        arguments: null);

        // 声明队列(不存在则创建,持久化)
        _channel.QueueDeclare(queue: queue, durable: true, exclusive: false, autoDelete: false);

        // 绑定队列到交换机
        _channel.QueueBind(queue: queue, exchange: exchange, routingKey: routingKey);

        // 创建消费者
        var consumerEvent = new EventingBasicConsumer(_channel);
        consumerEvent.Received += async (model, ea) =>
        {
            try
            {
                // 反序列化消息
                var body = ea.Body.ToArray();
                var json = Encoding.UTF8.GetString(body);
                var message = JsonSerializer.Deserialize<T>(json);

                if (message != null)
                {
                    Console.WriteLine($"📥 收到消息:Queue={queue}, Message={json}");
                    await consumer.HandleAsync(message);
                }

                // 手动确认消息(处理成功后确认)
                _channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"❌ 消息处理失败:{ex.Message}");
                // 处理失败,拒绝消息并重新入队(重试)
                _channel.BasicNack(deliveryTag: ea.DeliveryTag, multiple: false, requeue: true);
            }
        };

        // 启动消费者(手动确认模式)
        _channel.BasicConsume(queue: queue, autoAck: false, consumer: consumerEvent);
        Console.WriteLine($"✅ 消费者注册成功:Queue={queue}, Exchange={exchange}, RoutingKey={routingKey}");
    }

    public void Dispose()
    {
        _channel?.Close();
        _connection?.Close();
        _channel?.Dispose();
        _connection?.Dispose();
    }
}

4. 编写依赖注入扩展方法

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace Commerce.Share.RabbitMq;

/// <summary>
/// 通用消费者后台服务
/// 负责在应用启动时自动注册RabbitMQ消费者
/// </summary>
/// <typeparam name="T">消息类型</typeparam>
/// <typeparam name="TConsumer">消费者类型</typeparam>
public class ConsumerHostedService<T, TConsumer> : IHostedService
    where T : class
    where TConsumer : class, IMessageConsumer<T>
{
    private readonly RabbitMQMessageBus _messageBus;
    private readonly IServiceProvider _serviceProvider;
    private readonly string _exchange;
    private readonly string _queue;
    private readonly string _routingKey;

    public ConsumerHostedService(
        RabbitMQMessageBus messageBus,
        IServiceProvider serviceProvider,
        string exchange,
        string queue,
        string routingKey)
    {
        _messageBus = messageBus;
        _serviceProvider = serviceProvider;
        _exchange = exchange;
        _queue = queue;
        _routingKey = routingKey;
    }

    /// <summary>
    /// 应用启动时执行
    /// </summary>
    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 创建消费者作用域(解决Scoped服务依赖问题)
        using var scope = _serviceProvider.CreateScope();
        var consumer = scope.ServiceProvider.GetRequiredService<IMessageConsumer<T>>();

        // 注册消费者到RabbitMQ
        _messageBus.RegisterConsumer(_exchange, _queue, _routingKey, consumer);

        return Task.CompletedTask;
    }

    /// <summary>
    /// 应用停止时执行
    /// </summary>
    public Task StopAsync(CancellationToken cancellationToken)
    {
        // 这里可以添加消费者优雅关闭逻辑
        return Task.CompletedTask;
    }
}
using Microsoft.Extensions.DependencyInjection;

namespace Commerce.Share.RabbitMq;

public static class RabbitMQExtensions
{
    /// <summary>
    /// 添加RabbitMQ消息总线
    /// </summary>
    public static IServiceCollection AddRabbitMQ(this IServiceCollection services)
    {
        // 配置选项
        services.AddOptions<RabbitMQOptions>()
                .BindConfiguration("RabbitMQ");

        // 注册单例消息总线
        services.AddSingleton<RabbitMQMessageBus>();
        services.AddSingleton<IMessageProducer>(sp => sp.GetRequiredService<RabbitMQMessageBus>());

        return services;
    }

    /// <summary>
    /// 注册消息消费者(修正版,.NET 8兼容)
    /// </summary>
    /// <typeparam name="T">消息类型</typeparam>
    /// <typeparam name="TConsumer">消费者实现类</typeparam>
    /// <param name="exchange">交换机名称</param>
    /// <param name="queue">队列名称</param>
    /// <param name="routingKey">路由键</param>
    public static IServiceCollection AddConsumer<T, TConsumer>(this IServiceCollection services,
        string exchange, string queue, string routingKey)
        where T : class
        where TConsumer : class, IMessageConsumer<T>
    {
        // 1. 注册消费者(Scoped生命周期,支持依赖注入)
        services.AddScoped<IMessageConsumer<T>, TConsumer>();

        // 2. 注册后台服务,应用启动时自动注册消费者
        services.AddHostedService(sp =>
        {
            var messageBus = sp.GetRequiredService<RabbitMQMessageBus>();
            return new ConsumerHostedService<T, TConsumer>(
                messageBus,
                sp,
                exchange,
                queue,
                routingKey);
        });

        return services;
    }
}

六、实战步骤 3:实现生产者(订单服务)

我们以 "创建订单后发送消息通知用户服务更新积分" 为例,实现消息生产者。

1. 定义消息模型

在Commerce.Share中创建通用消息模型:

namespace Commerce.Share.Common;

/// <summary>
/// 订单创建消息
/// </summary>
public class OrderCreatedMessage
{
    /// <summary>
    /// 订单ID
    /// </summary>
    public int OrderId { get; set; }

    /// <summary>
    /// 用户ID
    /// </summary>
    public int UserId { get; set; }

    /// <summary>
    /// 订单金额
    /// </summary>
    public decimal Amount { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime CreatedAt { get; set; } = DateTime.Now;
}

2. 订单服务集成 RabbitMQ

在订单服务的Program.cs中添加 RabbitMQ:

// 1. 添加RabbitMQ
builder.Services.AddRabbitMQ();

image

 3. 添加 RabbitMQ 配置

{
  "RabbitMQ": {
    "HostName": "rabbitmq",
    "UserName": "admin",
    "Password": "密码"
  }
}

image

 4. 修改订单控制器,发送消息

using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using OrderApi.DbContexts;
using OrderApi.Entities;
using Microsoft.EntityFrameworkCore;
using Commerce.Share.RabbitMq;
using Commerce.Share.Common;

namespace OrderApi.Controllers.V1;

/// <summary>
/// 订单控制器
/// </summary>
[ApiVersion(1.0)] // 标记版本v2.0
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[ApiController]
public class OrderController : ControllerBase
{
    private readonly OrderDbContext _context;
    private readonly IMessageProducer _messageProducer;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="context"></param>
    public OrderController(OrderDbContext context, IMessageProducer messageProducer)
    {
        _context = context;
        _messageProducer = messageProducer;
    }

    /// <summary>
    /// 获取所有订单
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Order>>> GetOrders()
    {
        // AsNoTracking:查询优化,不跟踪实体状态(微服务读多写少场景推荐)
        return await _context.Orders.AsNoTracking().ToListAsync();
    }

    /// <summary>
    /// 创建订单
    /// </summary>
    [HttpPost]
    public async Task<IActionResult> CreateOrder(int userId, decimal amount)
    {
        // 1. 本地创建订单(保存到数据库)
        var orderId = new Random().Next(1000, 9999);
        Console.WriteLine($"✅ 订单创建成功:OrderId={orderId}, UserId={userId}, Amount={amount}");

        // 2. 发送订单创建消息到RabbitMQ
        var message = new OrderCreatedMessage
        {
            OrderId = orderId,
            UserId = userId,
            Amount = amount
        };

        // 交换机名称:order-exchange,路由键:order.created
        await _messageProducer.PublishAsync("order-exchange", "order.created", message);

        // 3. 立即返回结果,不需要等待下游服务处理
        return Ok(new
        {
            OrderId = orderId,
            Message = "订单创建成功,积分将在稍后更新"
        });
    }
}

七、实战步骤 4:实现消费者(用户服务)

用户服务作为消费者,监听订单创建消息,异步更新用户积分。

1. 用户服务集成 RabbitMQ

与订单服务完全相同,在Program.cs中添加builder.Services.AddRabbitMQ(),并在appsettings.json中添加 RabbitMQ 配置。

2. 实现消息消费者

using Commerce.Share.Common;
using Commerce.Share.RabbitMq;

namespace UserApi.Consumers;

/// <summary>
/// 消息消费者
/// </summary>
public class OrderCreatedConsumer : IMessageConsumer<OrderCreatedMessage>
{
    /// <summary>
    /// 处理订单创建消息
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public async Task HandleAsync(OrderCreatedMessage message)
    {
        // 模拟更新用户积分:消费1元获得1积分
        var points = (int)message.Amount;
        Console.WriteLine($"🎁 更新用户积分:UserId={message.UserId}, 增加积分={points}, 订单号={message.OrderId}");

        // 实际项目中这里会调用数据库更新用户积分
        await Task.Delay(100); // 模拟数据库操作
    }
}

3. 注册消费者

在用户服务的Program.cs中注册消费者:

// 2. 注册订单创建消息消费者
// 交换机:order-exchange,队列:user-order-queue,路由键:order.created
builder.Services.AddConsumer<OrderCreatedMessage, OrderCreatedConsumer>(
    exchange: "order-exchange",
    queue: "user-order-queue",
    routingKey: "order.created");

image

 八、实战步骤 5:全链路验证

现在我们已经完成了所有代码开发,来验证整个异步通信流程是否正常工作。

1. 重新构建并部署服务

提交代码到 Git,触发 Jenkins 流水线,自动构建并部署更新后的订单服务和用户服务。

2. 验证 RabbitMQ 连接

访问 RabbitMQ 管理界面 http://你的服务器IP:15672,在「Connections」页面可以看到订单服务和用户服务已经建立了连接。

image

 3. 测试消息发送与消费

通过网关调用订单创建接口:

image

 预期结果:

  • 订单服务立即返回响应,响应时间 < 10ms;
  • 订单服务控制台输出:✅ 消息发送成功:Exchange=order-exchange, RoutingKey=order.created

    image

  • 用户服务控制台输出:📥 收到消息:Queue=user-order-queue...🎁 更新用户积分:UserId=1, 增加积分=100

    image

  • RabbitMQ 管理界面的「Queues」页面可以看到user-order-queue的消息数为 0,说明消息已被成功消费。

    image

 

4. 验证服务解耦

手动停止用户服务,再次调用订单创建接口:

  • 订单服务仍然能够正常创建订单并返回结果;

    image

  • RabbitMQ 管理界面可以看到消息被缓存到user-order-queue中;

    image

  • 重新启动用户服务后,会自动消费队列中的所有消息,更新用户积分。

    image

这完美体现了异步通信的解耦优势:下游服务宕机不影响主流程,服务恢复后自动处理积压的消息。

九、进阶实战:生产级可靠性保障

1. 消息持久化

我们已经在代码中开启了三层持久化,确保消息不丢失:

  • 交换机持久化:ExchangeDeclare时设置durable: true
  • 队列持久化:QueueDeclare时设置durable: true
  • 消息持久化:发送消息时设置properties.Persistent = true

2. 死信队列处理失败消息

当消息处理失败多次后,会进入死信队列,避免无限重试导致系统卡死:

// 声明死信交换机和队列
_channel.ExchangeDeclare("dead-letter-exchange", ExchangeType.Direct, durable: true);
_channel.QueueDeclare("dead-letter-queue", durable: true, exclusive: false, autoDelete: false);
_channel.QueueBind("dead-letter-queue", "dead-letter-exchange", "dead-letter");

// 声明业务队列时指定死信交换机
var arguments = new Dictionary<string, object>
{
    { "x-dead-letter-exchange", "dead-letter-exchange" },
    { "x-dead-letter-routing-key", "dead-letter" },
    { "x-max-retry-count", 3 } // 最多重试3次
};

_channel.QueueDeclare(queue: "user-order-queue", 
                     durable: true, 
                     exclusive: false, 
                     autoDelete: false,
                     arguments: arguments);

3. 消息幂等性

由于网络问题,消息可能会被重复投递,因此必须保证消费者的操作是幂等的:

  • 使用消息 ID 作为唯一标识,在数据库中记录已处理的消息 ID;
  • 处理消息前先检查是否已处理过,已处理则直接返回;
  • 使用业务主键(如订单 ID)作为幂等键。

十、最佳实践

1. 命名规范

  • 交换机命名:业务域-exchange(如order-exchangeuser-exchange);
  • 队列命名:消费者服务-业务-queue(如user-order-queueinventory-order-queue);
  • 路由键命名:业务.动作(如order.createdorder.paid)。

2. 消息设计

  • 消息大小不要超过 1MB,过大的消息会影响性能;
  • 消息只包含必要的信息,不要传递整个对象;
  • 使用 JSON 序列化,方便调试和跨语言通信。

3. 监控与告警

  • 监控 RabbitMQ 的连接数、队列长度、消息消费速度;
  • 设置队列长度告警,当队列堆积超过阈值时及时通知;
  • 监控消息处理失败率,及时发现异常。

十一、常见问题解决

1. 消息丢失

  • 检查是否开启了交换机、队列、消息的持久化;
  • 检查生产者是否开启了确认模式;
  • 检查消费者是否使用手动确认模式,处理成功后再 Ack。

2. 重复消费

  • 实现消息幂等性,这是解决重复消费的根本方法;
  • 避免使用自动确认模式,防止消费者处理过程中崩溃导致消息重复。

3. 队列堆积

  • 增加消费者实例数量,提升消费能力;
  • 优化消费者处理逻辑,缩短单条消息的处理时间;
  • 对非核心业务进行降级,优先处理核心消息。

十二、总结

本篇我们完成了RabbitMQ 异步通信的深度集成,为我们的微服务架构增加了异步通信能力:
  1. 理解了同步调用的痛点和异步通信的核心价值;
  2. 用 Docker 部署了 RabbitMQ 服务端,开启了持久化和管理界面;
  3. 在共享类库中封装了通用的 RabbitMQ 客户端,支持依赖注入;
  4. 实现了订单服务作为生产者发送消息,用户服务作为消费者消费消息;
  5. 掌握了消息持久化、死信队列、幂等性等生产级可靠性保障技术。
异步通信是微服务架构的重要组成部分,它让我们的系统更加解耦、更加可靠、更加可扩展。现在我们的微服务架构已经具备了同步和异步两种通信模式,可以根据不同的业务场景选择合适的通信方式。
posted @ 2026-05-25 15:23  挺秃然的i  阅读(26)  评论(0)    收藏  举报