欢迎光临
我们一直在努力

基于 RabbitMQ 实现高性能可靠的 RPC 远程调用(.NET 完整实战 + 最佳实践)

在分布式系统开发中,RPC(远程过程调用) 是实现服务间通信的核心方式之一,而 RabbitMQ 作为一款成熟的消息队列中间件,不仅能实现异步消息投递,也能完美实现标准的 RPC 调用模式。

与传统的 HTTP RPC、gRPC 相比,基于 RabbitMQ 实现的 RPC 具备解耦、高可用、天然重试、负载均衡、异步非阻塞等核心优势,非常适合在分布式服务、跨进程通信、物联网设备指令调用等场景中落地。

本文将从原理到实战,完整讲解 RabbitMQ 实现 RPC 的核心机制,同时提供一套 符合 C# 编码规范、基于.NET 异步编程模型、可直接上生产环境 的完整 RabbitMQ RPC 封装代码,包含客户端 + 服务端全量实现,以及最佳实践和避坑指南。

一、RabbitMQ 实现 RPC 的核心原理

RabbitMQ 本身是异步的消息队列,但通过三大核心机制的组合,就能完美实现「客户端发起请求、同步等待响应、服务端处理并返回结果」的 RPC 核心诉求,这也是 RabbitMQ 官方文档中推荐的标准 RPC 实现方案。

✅ 核心实现三要素

1. CorrelationId(唯一请求标识,核心中的核心)

客户端发起每次 RPC 请求时,生成一个全局唯一的CorrelationId(通常用 Guid)并随消息一起发送;服务端处理完成后,原样带回该 ID 到响应消息中。客户端通过这个 ID 可以精准匹配「当前响应对应哪一次请求」,彻底解决响应错乱的问题,是实现 RPC 的基石。

2. ReplyTo(指定响应回调地址)

客户端发送请求时,通过消息属性ReplyTo指定「服务端处理完成后,将响应消息发送到哪个队列 / 路由键」;服务端从请求消息中读取该地址,处理完业务逻辑后,将响应结果发送到这个地址即可。

3. TaskCompletionSource(异步转同步等待)

这是.NET 中实现「异步等待结果」的核心类,客户端发送请求后,创建TaskCompletionSource对象并缓存,随后进入异步等待状态;当监听到对应CorrelationId的响应消息时,通过该对象唤醒等待并返回结果,全程无同步线程阻塞,高并发友好。

✅ RabbitMQ RPC 完整调用流程

  • 客户端生成唯一CorrelationId,创建TaskCompletionSource并缓存,封装请求消息(参数 + CorrelationId+ReplyTo)发送到请求队列;
  • 服务端监听请求队列,收到消息后执行业务处理逻辑,得到返回结果;
  • 服务端从请求消息中读取ReplyTo和CorrelationId,封装响应消息发送到指定的响应队列;
  • 客户端监听响应队列,匹配到对应CorrelationId的响应消息后,唤醒等待的请求并返回结果;
  • 客户端清理本次请求的缓存对象,完成一次 RPC 调用。
  • 二、核心特性说明(本次封装的 RPC 组件)

    本次封装的RabbitMqRpcService是一套生产级的 RabbitMQ RPC 完整实现,基于.NET6 + 异步编程模型开发,完全遵循 C# 编码规范和 RabbitMQ 最佳实践,具备以下核心特性,开箱即用:✅ 客户端 + 服务端一体化封装,一套代码支持 RPC 调用与服务提供;✅ 基于业务编码businessCode实现多业务隔离,不同业务独立队列,互不干扰;✅ 完全异步编程模型,无同步阻塞,支持超高并发调用;✅ 完善的超时控制、异常捕获、日志记录,生产环境可追溯;✅ 通道 / 消费者复用机制,避免重复创建 RabbitMQ 资源,提升性能;✅ 严格实现 IDisposable 接口,资源自动释放,杜绝内存泄漏;✅ 支持 RabbitMQ 连接自动恢复、网络重连,高可用保障;✅ 手动 ACK 确认机制,消息零丢失,可靠性拉满;✅ 无侵入式设计,调用简单,耦合度极低。

    三、完整封装代码(生产级可直接复制)

    3.1 代码结构说明

    • 命名空间:SPC.AbpComponets.RPC.RabbitMQ
    • 核心类:RabbitMqRpcService 密封类,实现IRabbitMqRpcService接口,包含客户端 + 服务端全部逻辑;
    • 配置基类:RabbitMqRpcConfigBase 抽离 RabbitMQ 连接工厂配置,解耦配置逻辑;
    • 接口约束:IRabbitMqRpcService 规范对外暴露的 RPC 调用和服务启动方法。

    3.2 全量完整代码

    using System;
    using System.Collections.Concurrent;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;
    using RabbitMQ.Client;
    using RabbitMQ.Client.Events;
    using RabbitMQ.Client.Exceptions;

    namespace SPC.AbpComponets.RPC.RabbitMQ
    {
    /// <summary>
    /// RabbitMQ 实现的RPC远程调用服务(客户端+服务端一体化)
    /// 遵循RabbitMQ官方RPC规范:CorrelationId+ReplyTo 实现请求响应绑定
    /// 完全异步编程模型,支持业务隔离、自动重连、资源自动释放、超时控制、消息可靠投递
    /// </summary>
    public sealed class RabbitMqRpcService : RabbitMqRpcConfigBase, IRabbitMqRpcService, IDisposable
    {
    #region 常量定义 – 杜绝魔法字符串/魔法值,规范核心
    private const string ExchangeRpcName = "rpc";
    private const string RequestQueuePrefix = "rpc_request_queue_";
    private const string ResponseQueuePrefix = "rpc_response_queue_";
    private const string RequestRoutingKeyPrefix = "rpc_request_key_";
    private const string ResponseRoutingKeyPrefix = "rpc_response_key_";
    private const string DefaultBusinessCode = "DEFAULT";
    private const int MinTimeoutSeconds = 1;
    private const int MaxTimeoutSeconds = 300;
    private const int ResponseMessageExpirationSeconds = 600;
    private const int ResourceReleaseTimeoutMs = 1000;
    #endregion

    #region 私有字段 – 只读化+命名规范+按需私有化
    private readonly IConnection _rabbitConnection;
    private readonly ILogger<RabbitMqRpcService> _logger;
    private readonly ConcurrentDictionary<string, IChannel> _channelCache = new ConcurrentDictionary<string, IChannel>();
    private readonly ConcurrentDictionary<string, AsyncEventingBasicConsumer> _responseConsumerCache = new ConcurrentDictionary<string, AsyncEventingBasicConsumer>();
    private readonly ConcurrentDictionary<string, AsyncEventingBasicConsumer> _serverConsumerCache = new ConcurrentDictionary<string, AsyncEventingBasicConsumer>();
    private static readonly ConcurrentDictionary<string, TaskCompletionSource<string>> _pendingRequests = new ConcurrentDictionary<string, TaskCompletionSource<string>>();

    private bool _isDisposed;
    #endregion

    /// <summary>
    /// 构造函数 – 依赖注入初始化,禁止手动实例化
    /// </summary>
    /// <param name="configuration">配置文件</param>
    /// <param name="logger">日志对象</param>
    public RabbitMqRpcService(IConfiguration configuration, ILogger<RabbitMqRpcService> logger = null)
    {
    _logger = logger;
    var connectionFactory = CreateConnectionFactory(configuration);
    _rabbitConnection = CreateRabbitConnection(connectionFactory);

    // 注册连接生命周期事件,主动释放资源
    _rabbitConnection.ConnectionShutdown += (sender, args) => ReleaseAllResources();
    _rabbitConnection.CallbackException += (sender, args) => _logger?.LogError(args.Exception, "RabbitMQ连接回调异常");
    _rabbitConnection.ConnectionBlocked += (sender, args) => _logger?.LogWarning("RabbitMQ连接被阻塞:{0}", args.Reason);
    }

    #region 核心规范:严格实现IDisposable接口 – 资源释放标准写法
    /// <inheritdoc />
    public void Dispose()
    {
    if (_isDisposed) return;

    ReleaseAllResources();
    _isDisposed = true;
    GC.SuppressFinalize(this);
    }

    /// <summary>
    /// 释放所有RabbitMQ相关资源(连接、通道、消费者、等待任务)
    /// 线程安全,幂等调用,可重复执行,无副作用
    /// </summary>
    private void ReleaseAllResources()
    {
    try
    {
    // 1. 释放所有缓存的通道
    if (_channelCache.Count > 0)
    {
    foreach (var (cacheKey, channel) in _channelCache)
    {
    if (channel is not null && channel.IsOpen)
    {
    _ = channel.CloseAsync().WaitAsync(TimeSpan.FromMilliseconds(ResourceReleaseTimeoutMs));
    _ = channel.DisposeAsync().AsTask().WaitAsync(TimeSpan.FromMilliseconds(ResourceReleaseTimeoutMs));
    }
    }
    _channelCache.Clear();
    }

    // 2. 取消所有待处理的RPC请求,避免内存泄漏
    if (_pendingRequests.Count > 0)
    {
    foreach (var tcs in _pendingRequests.Values)
    {
    _ = tcs.TrySetCanceled();
    }
    _pendingRequests.Clear();
    }

    // 3. 释放RabbitMQ主连接
    if (_rabbitConnection is not null && _rabbitConnection.IsOpen)
    {
    _ = _rabbitConnection.CloseAsync().WaitAsync(TimeSpan.FromMilliseconds(ResourceReleaseTimeoutMs));
    _rabbitConnection.Dispose();
    }

    _logger?.LogInformation("RabbitMQ RPC所有资源释放完成");
    }
    catch (Exception ex)
    {
    _logger?.LogError(ex, "RabbitMQ RPC资源释放过程中发生异常");
    }
    }
    #endregion

    #region 私有核心方法:获取RabbitMQ通道 – 复用+创建+队列交换机声明
    /// <summary>
    /// 获取指定业务编码的RabbitMQ通道,通道复用机制,不存在则创建并声明交换机/队列/绑定关系
    /// </summary>
    /// <param name="connection">RabbitMQ连接</param>
    /// <param name="businessCode">业务隔离编码</param>
    /// <returns>可用的RabbitMQ通道</returns>
    private async Task<IChannel> GetChannelAsync(IConnection connection, string businessCode = "")
    {
    if (connection is null || !connection.IsOpen)
    {
    _logger?.LogError("RabbitMQ连接已关闭或为空,无法获取通道");
    return null;
    }

    var cacheKey = string.IsNullOrWhiteSpace(businessCode) ? DefaultBusinessCode : businessCode;

    // 通道复用:存在且可用则直接返回,提升性能
    if (_channelCache.TryGetValue(cacheKey, out var existChannel) && existChannel.IsOpen)
    {
    return existChannel;
    }

    try
    {
    var channel = await connection.CreateChannelAsync();

    // 声明持久化交换机:direct类型,RPC专用
    await channel.ExchangeDeclareAsync(
    exchange: ExchangeRpcName,
    type: ExchangeType.Direct,
    durable: true,
    autoDelete: false);

    // 声明请求队列+绑定路由键
    var requestQueueName = $"{RequestQueuePrefix}{cacheKey}";
    var requestRoutingKey = $"{RequestRoutingKeyPrefix}{cacheKey}";
    await channel.QueueDeclareAsync(
    queue: requestQueueName,
    durable: true,
    exclusive: false,
    autoDelete: false,
    arguments: null);
    await channel.QueueBindAsync(requestQueueName, ExchangeRpcName, requestRoutingKey);

    // 声明响应队列+绑定路由键
    var responseQueueName = $"{ResponseQueuePrefix}{cacheKey}";
    var responseRoutingKey = $"{ResponseRoutingKeyPrefix}{cacheKey}";
    await channel.QueueDeclareAsync(
    queue: responseQueueName,
    durable: true,
    exclusive: false,
    autoDelete: false,
    arguments: null);
    await channel.QueueBindAsync(responseQueueName, ExchangeRpcName, responseRoutingKey);

    // 缓存通道
    _channelCache[cacheKey] = channel;
    _logger?.LogDebug("RabbitMQ通道创建并缓存成功,业务编码:{0}", businessCode);

    return channel;
    }
    catch (Exception ex)
    {
    _logger?.LogError(ex, "RabbitMQ通道创建失败,业务编码:{0}", businessCode);
    return null;
    }
    }
    #endregion

    #region 私有核心方法:创建响应消息消费者 – 监听响应队列,匹配并唤醒RPC请求
    /// <summary>
    /// 创建并初始化响应消息消费者,持续监听指定队列的响应消息
    /// </summary>
    private async Task<AsyncEventingBasicConsumer> CreateResponseConsumerAsync(IChannel channel, string queueName)
    {
    if (channel is null || !channel.IsOpen || string.IsNullOrWhiteSpace(queueName))
    {
    _logger?.LogWarning("创建响应消费者失败:通道不可用或队列为空");
    return null;
    }

    var consumer = new AsyncEventingBasicConsumer(channel);
    consumer.ReceivedAsync += async (sender, eventArgs) => await HandleResponseMessageAsync(channel, eventArgs);

    // 启动消费:手动确认模式,确保消息可靠消费
    await channel.BasicConsumeAsync(queue: queueName, autoAck: false, consumer: consumer);
    return consumer;
    }

    /// <summary>
    /// 处理响应队列的消息,匹配CorrelationId并唤醒对应的RPC请求
    /// </summary>
    private async Task HandleResponseMessageAsync(IChannel channel, BasicDeliverEventArgs eventArgs)
    {
    try
    {
    var messageBody = Encoding.UTF8.GetString(eventArgs.Body.ToArray());
    var messageProps = eventArgs.BasicProperties;
    var correlationId = messageProps.CorrelationId;

    // 匹配并唤醒对应的RPC请求
    if (!string.IsNullOrWhiteSpace(correlationId) && _pendingRequests.TryRemove(correlationId, out var tcs))
    {
    _ = tcs.TrySetResult(messageBody);
    await channel.BasicAckAsync(eventArgs.DeliveryTag, multiple: false);
    _logger?.LogDebug("RPC响应消息处理成功,CorrelationId:{0},响应内容:{1}", correlationId, messageBody);
    }
    else
    {
    // 无法匹配的消息,重新放回队列
    await channel.BasicNackAsync(eventArgs.DeliveryTag, multiple: false, requeue: true);
    _logger?.LogWarning("收到无法匹配的RPC响应消息,CorrelationId:{0}", correlationId);
    }
    }
    catch (Exception ex)
    {
    // 消费异常,消息重新入队,避免丢失
    await channel.BasicNackAsync(eventArgs.DeliveryTag, multiple: false, requeue: true);
    _logger?.LogError(ex, "处理RPC响应消息时发生异常");
    }
    }
    #endregion

    #region 对外实现:RPC客户端调用 – 发送请求并异步等待响应(核心业务)
    /// <inheritdoc />
    public async Task<string> RpcClientAsync(string requestMessage, string businessCode = "", int timeoutSeconds = 60)
    {
    // 1. 入参合法性校验
    if (string.IsNullOrWhiteSpace(requestMessage))
    {
    const string errorMsg = "RPC请求消息不能为空";
    _logger?.LogWarning(errorMsg);
    return $"error:{errorMsg}";
    }

    // 2. 超时参数兜底,防止非法值
    timeoutSeconds = Math.Clamp(timeoutSeconds, MinTimeoutSeconds, MaxTimeoutSeconds);
    var messageExpirationMs = timeoutSeconds * 1000;
    var correlationId = Guid.NewGuid().ToString("N");
    var cacheKey = string.IsNullOrWhiteSpace(businessCode) ? DefaultBusinessCode : businessCode;
    var responseResult = string.Empty;

    try
    {
    // 3. 获取可用通道
    var channel = await GetChannelAsync(_rabbitConnection, businessCode);
    if (channel is null || !channel.IsOpen)
    {
    const string errorMsg = "获取RabbitMQ通道失败,无法发送RPC请求";
    _logger?.LogError(errorMsg);
    return $"error:{errorMsg}";
    }

    // 4. 初始化响应消费者(单例,只创建一次)
    if (!_responseConsumerCache.TryGetValue(cacheKey, out var consumer) || consumer.Model is null || !consumer.Model.IsOpen)
    {
    var responseQueueName = $"{ResponseQueuePrefix}{cacheKey}";
    consumer = await CreateResponseConsumerAsync(channel, responseQueueName);
    _responseConsumerCache[cacheKey] = consumer;
    }

    // 5. 构建请求消息属性
    var requestProps = channel.CreateBasicProperties();
    requestProps.Persistent = true;
    requestProps.CorrelationId = correlationId;
    requestProps.ReplyTo = $"{ResponseRoutingKeyPrefix}{cacheKey}";
    requestProps.Expiration = messageExpirationMs.ToString();

    // 6. 创建异步等待任务并缓存
    var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
    if (!_pendingRequests.TryAdd(correlationId, tcs))
    {
    var errorMsg = $"RPC请求ID重复,创建等待任务失败,CorrelationId:{correlationId}";
    _logger?.LogError(errorMsg);
    return $"error:{errorMsg}";
    }

    // 7. 发送RPC请求消息
    var requestRoutingKey = $"{RequestRoutingKeyPrefix}{cacheKey}";
    var requestBody = Encoding.UTF8.GetBytes(requestMessage);
    await channel.BasicPublishAsync(ExchangeRpcName, requestRoutingKey, mandatory: false, requestProps, requestBody);

    _logger?.LogDebug("RPC请求发送成功,业务编码:{0},超时时间:{1}秒,CorrelationId:{2}", businessCode, timeoutSeconds, correlationId);

    // 8. 异步等待响应,带超时控制
    using var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(timeoutSeconds));
    var responseTask = tcs.Task;
    await responseTask.WaitAsync(cancellationTokenSource.Token);
    responseResult = responseTask.Result;
    }
    catch (OperationCanceledException)
    {
    var errorMsg = $"RPC请求超时,{timeoutSeconds}秒内未收到响应";
    _logger?.LogWarning("{0},业务编码:{1},CorrelationId:{2}", errorMsg, businessCode, correlationId);
    responseResult = $"timeout:{errorMsg}";
    }
    catch (BrokerUnreachableException ex)
    {
    var errorMsg = $"RabbitMQ服务不可达:{ex.Message}";
    _logger?.LogError(ex, errorMsg);
    responseResult = $"error:{errorMsg}";
    }
    catch (AlreadyClosedException ex)
    {
    var errorMsg = $"RabbitMQ通道已关闭:{ex.Message}";
    _logger?.LogError(ex, errorMsg);
    responseResult = $"error:{errorMsg}";
    }
    catch (Exception ex)
    {
    var errorMsg = $"RPC请求处理异常:{ex.Message}";
    _logger?.LogError(ex, "{0},业务编码:{1}", errorMsg, businessCode);
    responseResult = $"exception:{errorMsg}";
    }
    finally
    {
    // 无论成败,必须移除等待任务,杜绝内存泄漏
    if (_pendingRequests.TryRemove(correlationId, out _))
    {
    _logger?.LogDebug("RPC请求任务已释放,CorrelationId:{0}", correlationId);
    }
    }

    return responseResult;
    }
    #endregion

    #region 对外实现:RPC服务端启动 – 监听请求队列并处理业务逻辑(核心业务)
    /// <inheritdoc />
    public async Task RpcServerAsync(Func<string, string> businessHandler, string businessCode = "")
    {
    // 入参校验:业务处理委托不能为空
    if (businessHandler is null)
    {
    const string errorMsg = "RPC服务端业务处理委托不能为空";
    _logger?.LogError(errorMsg);
    throw new ArgumentNullException(nameof(businessHandler), errorMsg);
    }

    var cacheKey = string.IsNullOrWhiteSpace(businessCode) ? DefaultBusinessCode : businessCode;

    // 服务端消费者复用:已存在则直接返回,避免重复创建
    if (_serverConsumerCache.TryGetValue(cacheKey, out var existConsumer)
    && existConsumer.Model is not null
    && existConsumer.Model.IsOpen)
    {
    _logger?.LogDebug("RPC服务端消费者已存在,无需重复创建,业务编码:{0}", businessCode);
    return;
    }

    // 获取可用通道
    var channel = await GetChannelAsync(_rabbitConnection, businessCode);
    if (channel is null || !channel.IsOpen)
    {
    _logger?.LogError("RPC服务端启动失败:获取RabbitMQ通道失败,业务编码:{0}", businessCode);
    return;
    }

    var requestQueueName = $"{RequestQueuePrefix}{cacheKey}";
    var consumer = new AsyncEventingBasicConsumer(channel);

    // 注册请求消息处理事件
    consumer.ReceivedAsync += async (sender, eventArgs) =>
    await HandleRequestMessageAsync(channel, eventArgs, businessHandler);

    // 启动消费:手动确认模式,确保消息可靠消费
    await channel.BasicConsumeAsync(queue: requestQueueName, autoAck: false, consumer: consumer);
    _serverConsumerCache[cacheKey] = consumer;

    _logger?.LogInformation("RPC服务端启动成功,业务编码:{0},监听队列:{1}", businessCode, requestQueueName);
    }

    /// <summary>
    /// 处理请求队列的消息,执行业务逻辑并返回响应结果
    /// </summary>
    private async Task HandleRequestMessageAsync(IChannel channel, BasicDeliverEventArgs eventArgs, Func<string, string> businessHandler)
    {
    try
    {
    var requestMessage = Encoding.UTF8.GetString(eventArgs.Body.ToArray());
    var requestProps = eventArgs.BasicProperties;
    var replyToRoutingKey = requestProps.ReplyTo;
    var correlationId = requestProps.CorrelationId;

    // 无回调地址,直接确认消息并丢弃
    if (string.IsNullOrWhiteSpace(replyToRoutingKey))
    {
    await channel.BasicAckAsync(eventArgs.DeliveryTag, multiple: false);
    _logger?.LogWarning("RPC请求无回调地址,已丢弃,CorrelationId:{0}", correlationId);
    return;
    }

    // 执行业务逻辑
    var responseMessage = businessHandler.Invoke(requestMessage);
    _logger?.LogDebug("RPC请求处理完成,CorrelationId:{0},请求内容:{1},响应内容:{2}", correlationId, requestMessage, responseMessage);

    // 构建响应消息属性
    var responseProps = channel.CreateBasicProperties();
    responseProps.Persistent = true;
    responseProps.CorrelationId = correlationId;
    responseProps.Expiration = ResponseMessageExpirationSeconds.ToString();

    // 发送响应消息
    var responseBody = Encoding.UTF8.GetBytes(responseMessage);
    await channel.BasicPublishAsync(ExchangeRpcName, replyToRoutingKey, mandatory: false, responseProps, responseBody);

    // 手动确认消息消费完成
    await channel.BasicAckAsync(eventArgs.DeliveryTag, multiple: false);
    }
    catch (Exception ex)
    {
    // 业务处理异常,消息重新入队重试
    await channel.BasicNackAsync(eventArgs.DeliveryTag, multiple: false, requeue: true);
    _logger?.LogError(ex, "处理RPC请求消息时发生异常");
    }
    }
    #endregion

    #region 私有辅助方法:创建RabbitMQ连接 – 同步安全创建
    /// <summary>
    /// 安全创建RabbitMQ连接,异步转同步无死锁
    /// </summary>
    private IConnection CreateRabbitConnection(IConnectionFactory factory)
    {
    try
    {
    return Task.Run(async () => await factory.CreateConnectionAsync()).GetAwaiter().GetResult();
    }
    catch (Exception ex)
    {
    _logger?.LogError(ex, "RabbitMQ连接创建失败");
    throw new InvalidOperationException("RabbitMQ连接初始化失败,请检查配置", ex);
    }
    }
    #endregion
    }

    /// <summary>
    /// RabbitMQ连接配置基类
    /// </summary>
    public abstract class RabbitMqRpcConfigBase
    {
    /// <summary>
    /// 创建RabbitMQ连接工厂,配置自动重连、心跳等核心参数
    /// </summary>
    protected IConnectionFactory CreateConnectionFactory(IConfiguration configuration)
    {
    return new ConnectionFactory
    {
    HostName = configuration["RabbitMQ:HostName"] ?? "localhost",
    Port = int.Parse(configuration["RabbitMQ:Port"] ?? "5672"),
    UserName = configuration["RabbitMQ:UserName"] ?? "guest",
    Password = configuration["RabbitMQ:Password"] ?? "guest",
    VirtualHost = configuration["RabbitMQ:VirtualHost"] ?? "/",
    DispatchConsumersAsync = true, // 必须开启:支持异步消费者
    AutomaticRecoveryEnabled = true, // 自动恢复连接,高可用核心
    NetworkRecoveryInterval = TimeSpan.FromSeconds(5), // 网络恢复间隔
    RequestedHeartbeat = TimeSpan.FromSeconds(60) // 心跳检测,防止连接断开
    };
    }
    }

    /// <summary>
    /// RabbitMQ RPC服务接口规范
    /// </summary>
    public interface IRabbitMqRpcService
    {
    /// <summary>
    /// RPC客户端调用,发送请求并异步等待响应
    /// </summary>
    /// <param name="requestMessage">请求消息内容</param>
    /// <param name="businessCode">业务隔离编码</param>
    /// <param name="timeoutSeconds">超时时间(秒)</param>
    /// <returns>响应消息内容</returns>
    Task<string> RpcClientAsync(string requestMessage, string businessCode = "", int timeoutSeconds = 60);

    /// <summary>
    /// RPC服务端启动,监听指定业务的请求队列
    /// </summary>
    /// <param name="businessHandler">业务处理委托</param>
    /// <param name="businessCode">业务隔离编码</param>
    Task RpcServerAsync(Func<string, string> businessHandler, string businessCode = "");
    }
    }

    赞(0)
    未经允许不得转载:171主机测评 » 基于 RabbitMQ 实现高性能可靠的 RPC 远程调用(.NET 完整实战 + 最佳实践)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址