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



我目前被这个问题困住了大约一个星期,真的找不到合适的解决方案。问题是,当我尝试连接到 dockerized 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:

我的应用设置字符串:

{
"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的工作方式:

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 的情况下在本地测试它时,一切都很完美,但是当我尝试对应用程序进行 dockerize 时,就会发生这种情况。

如果在本地测试,主机可能会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";

最新更新