You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Swarm环境下.Net WebAPI连接RabbitMQ/MassTransit报错求助

Docker Swarm栈内WebAPI无法连接RabbitMQ问题排查

问题现象

我是Docker Swarm结合RabbitMQ/MassTransit的新手,目前遇到一个问题:栈内的C# .NET WebAPI服务无法连接同栈的RabbitMQ服务,但从栈外(比如本地机器)连接RabbitMQ完全正常。

报错信息:

Unhandled exception. System.UriFormatException: Invalid URI: The hostname could not be parsed.

相关配置与代码

RabbitMQ服务的Compose配置

rabbitmq:
  image: docker.io/masstransit/rabbitmq:latest
  ports:
    - "5672:5672"
    - "15672:15672"
  deploy:
    mode: replicated
    replicas: 1
  networks: 
  - smartflow_default

WebAPI服务的Compose配置

apiexports:
  image: docker.io/renegisbertzdareit/padex.smartflow.exports:1.0.1
  ports:
    - "41003:443"
    - "42003:80"
  deploy:
    mode: replicated
    replicas: 3
  environment:
    - ASPNETCORE_Kestrel__Certificates__Default__Password=********
    - ASPNETCORE_Kestrel__Certificates__Default__Path=/run/secrets/padex_solution_nl_wildcard_certificate
    - ASPNETCORE_URLS=https://+;http://+
    - LOGGING_DEFAULT_LANGUAGE="en-us"
    - LOGGING_MINIMUM_LEVEL="Debug"
    - LOGGING_FILE_PATH="/var/log/log-.json"
    - RMQ_ADDRESS="rabbitmq:5672"
    - RMQ_USERNAME="guest"
    - RMQ_PASSWORD="guest"
  networks:
    - smartflow_default
  secrets:
    - padex_solution_nl_wildcard_certificate 

WebAPI中MassTransit连接代码

builder.Services.AddMassTransit(x =>
{
    x.UsingRabbitMq((context, cfg) =>
    {
        cfg.Host(new Uri($"amqp://{Environment.GetEnvironmentVariable("RMQ_USERNAME")}:{Environment.GetEnvironmentVariable("RMQ_PASSWORD")}@{Environment.GetEnvironmentVariable("RMQ_ADDRESS")}"));
        cfg.ConfigureEndpoints(context);
    });
});

已尝试过的连接地址

rabbitmq:15672
rabbitmq
10.203.1.30:15672
10.203.1.30:5672
10.203.1.30

问题原因与解决方案

核心问题:环境变量值包含多余双引号

在Compose配置的环境变量中,RMQ_ADDRESS="rabbitmq:5672"这类赋值带了双引号,Docker会把双引号也作为环境变量值的一部分传递给容器。当代码读取RMQ_ADDRESS时,实际拿到的是"rabbitmq:5672"(包含引号),拼接成Uri后变成amqp://guest:guest@"rabbitmq:5672",这种格式会导致URI解析失败,触发UriFormatException。

解决步骤

  1. 修正Compose环境变量配置:去掉所有环境变量值的双引号,比如:

    - RMQ_ADDRESS=rabbitmq:5672
    - RMQ_USERNAME=guest
    - RMQ_PASSWORD=guest
    - LOGGING_DEFAULT_LANGUAGE=en-us
    - LOGGING_MINIMUM_LEVEL=Debug
    - LOGGING_FILE_PATH=/var/log/log-.json
    

    Docker Compose中环境变量赋值不需要加引号,加引号反而会把引号带入值中。

  2. 优化MassTransit连接代码(可选但推荐):避免手动拼接Uri,改用MassTransit提供的分步配置方式,更安全且易维护:

    builder.Services.AddMassTransit(x =>
    {
        x.UsingRabbitMq((context, cfg) =>
        {
            var addressParts = Environment.GetEnvironmentVariable("RMQ_ADDRESS")?.Split(':') ?? new[] {"rabbitmq", "5672"};
            var host = addressParts[0];
            var port = addressParts.Length > 1 && int.TryParse(addressParts[1], out var p) ? p : 5672;
            
            cfg.Host(host, port, "/", h =>
            {
                h.Username(Environment.GetEnvironmentVariable("RMQ_USERNAME"));
                h.Password(Environment.GetEnvironmentVariable("RMQ_PASSWORD"));
            });
            
            cfg.ConfigureEndpoints(context);
        });
    });
    

    这种方式不需要拼接Uri,直接拆分地址和端口,避免格式错误。

  3. 验证环境变量值:可以在代码中添加日志输出,确认读取到的环境变量没有多余字符:

    var rmqAddress = Environment.GetEnvironmentVariable("RMQ_ADDRESS");
    Console.WriteLine($"RMQ_ADDRESS value: '{rmqAddress}'");
    

    如果输出带引号,说明Compose配置的问题还没解决。

补充说明

栈外连接正常是因为你用的是宿主机IP和端口,没有经过环境变量传递,自然不会有引号问题,所以能成功连接。

内容的提问来源于stack exchange,提问作者René

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 07:02:53