无法从Docker连接RabbitMQ到我的应用程序

3

我目前已经被这个问题困扰了一周,真的找不到合适的解决方案。问题在于当我尝试连接到docker化的RabbitMQ时,每次都会给我相同的错误:

wordofthedayapp-wordofthedayapp-1  | [40m[1m[33mwarn[39m[22m[49m: MassTransit[0]
wordofthedayapp-wordofthedayapp-1  |       Connection Failed: rabbitmq://localhost/
wordofthedayapp-wordofthedayapp-1  |       RabbitMQ.Client.Exceptions.BrokerUnreachableException: None of the specified endpoints were
 reachable
wordofthedayapp-wordofthedayapp-1  |        ---> System.AggregateException: One or more errors occurred. (Connection failed)
wordofthedayapp-wordofthedayapp-1  |        ---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed
wordofthedayapp-wordofthedayapp-1  |        ---> System.TimeoutException: The operation has timed out.
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.TaskExtensions.TimeoutAfter(Task task, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectOrFail(ITcpClient socket, AmqpTcpEndpo
int endpoint, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectOrFail(ITcpClient socket, AmqpTcpEndpo
int endpoint, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectUsingAddressFamily(AmqpTcpEndpoint end
point, Func`2 socketFactory, TimeSpan timeout, AddressFamily family)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler.ConnectUsingIPv4(AmqpTcpEndpoint endpoint, Fu
nc`2 socketFactory, TimeSpan timeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Impl.SocketFrameHandler..ctor(AmqpTcpEndpoint endpoint, Func`2 socket
Factory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.Framing.Impl.IProtocolExtensions.CreateFrameHandler(IProtocol protoco
l, AmqpTcpEndpoint endpoint, Func`2 socketFactory, TimeSpan connectionTimeout, TimeSpan readTimeout, TimeSpan writeTimeout)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateFrameHandler(AmqpTcpEndpoint endpoint)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, F
unc`2 selector)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.EndpointResolverExtensions.SelectOne[T](IEndpointResolver resolver, F
unc`2 selector)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver
, String clientProvidedName)
wordofthedayapp-wordofthedayapp-1  |          --- End of inner exception stack trace ---
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IEndpointResolver endpointResolver
, String clientProvidedName)
wordofthedayapp-wordofthedayapp-1  |          at RabbitMQ.Client.ConnectionFactory.CreateConnection(IList`1 hostnames, String clientPr
ovidedName)
wordofthedayapp-wordofthedayapp-1  |          at MassTransit.RabbitMqTransport.Integration.ConnectionContextFactory.CreateConnection(I
Supervisor supervisor)

在这里您可以找到我的docker-compose.yml文件:

version: '3.9'
services:
  rabbitmq:
    image: rabbitmq:3.9-management
    hostname: rabbitmq
    volumes:
      - "~/.docker-conf/rabbitmq/data/:/var/lib/rabbitmq/"
      - "~/.docker-conf/rabbitmq/log/:/var/log/rabbitmq"
    ports:
      - 5672:5672
      - 15672:15672
    expose:
     - 5672
     - 15672
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    healthcheck:
        test: [ "CMD", "rabbitmqctl", "status", "-f", "http://localhost:15672"]
        interval: 5s
        timeout: 20s
        retries: 5
    networks:
      - app

  ms-sql-server:
    container_name: ms-sql-server
    image: mcr.microsoft.com/mssql/server:2019-latest
    user: root
    volumes:
      - "appdb:/var/opt/mssql/data"
    environment:
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "Password123!"
      MSSQL_PID: Express
    ports:
      - 1433:1433
    healthcheck:
        test: ["CMD" ,"ping", "-h", "localhost"]
        timeout: 20s
        retries: 10
    networks:
      - app

  wordofthedayapp:
    build:
      dockerfile: WordOfTheDay.Api/Dockerfile
    image: wordofthedayapp
    environment:
      DbServer: "ms-sql-server"
      DbPort: "1433"
      DbUser: "sa"
      Password: "Password123!"
      Database: "appdb"
    ports:
      - 5001:80
    restart: on-failure
    depends_on:
      - rabbitmq
    networks:
      - app

volumes:
  appdb:

networks:
  app:

我的appsettings字符串:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "WordContext": "Server=ms-sql-server;Database=master;User=sa;Password=Password123!;MultipleActiveResultSets=true;Integrated Security=false;TrustServerCertificate=true",
    "RabbitMQHost": "amqp://elias:123456@localhost:5672"
  }
}

这是在使用MassTransit应用程序中的工作原理:
这是在使用MassTransit应用程序中的工作原理:
public static void AddConfiguredMassTransit(this IServiceCollection services, string host)
        {
            services.AddMassTransit(Configuration =>
            {
                Configuration.UsingRabbitMq((context, config) =>
                {
                    config.Host(host);
                });
            });

            services.AddMassTransitHostedService();
        }

services.AddConfiguredMassTransit(Configuration.GetConnectionString("RabbitMQHost"));

我希望至少有人知道这段代码的问题,因为我已经很累了,试图修复它并在互联网上寻找解决方案。提前谢谢你!

重要信息!当我在本地测试时,一切都运行得非常完美,但是当我尝试将应用程序放入docker中时,就会出现这种情况。


同样地,您需要使用Compose服务名称 rabbitmq 作为主机名来连接 RabbitMQHost 设置中的消息队列,就像您使用Compose服务名称ms-sql-server 作为主机名来连接数据库一样。在Docker中,localhost 通常表示“当前容器”。 - David Maze
1个回答

4
如果您在本地测试,则主机很可能是localhost,因为Docker正在将端口暴露给本地计算机。但是,在容器中运行时,虚拟网络应该具有rabbitmq的主机名,这需要在同一网络上运行的容器内部使用,而不是localhost
由于日志显示: Connection Failed: rabbitmq://localhost/ 我猜测您在容器内运行时没有更新主机名。
您可以轻松确定应用程序是否在容器中运行:
bool IsRunningInContainer => bool.TryParse(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"), out var inDocker) && inDocker;

然后,在您的配置中: var host = IsRunningInContainer ? "rabbitmq" : "localhost"; 如果正在容器中运行,则主机为“rabbitmq”,否则为“localhost”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接