Masstransit 无法从 docker 容器访问主机 RabbitMQ

Masstransit cannot access host machine RabbitMQ from a docker container

我创建了一个具有 docker 支持的简单 .net 核心控制台应用程序。正在关注
Masstransit 代码无法连接到主机上的 RabbitMQ 实例。但是使用 RabitMq.Client 的类似实现能够连接到主机 RabbitMQ 实例。

地铁抛出

MassTransit.RabbitMqTransport.RabbitMqConnectionException: Connect failed: ctas@192.168.0.9:5672/ ---> RabbitMQ.Client.Exceptions.BrokerUnreachableException:

主机ip : 192.168.0.9

使用公共交通

        string rabbitMqUri = "rabbitmq://192.168.0.9/";
        string userName = "ctas";
        string password = "ctas@123";
        string assetServiceQueue = "hello";


       var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
       {
           var host = cfg.Host(new Uri(rabbitMqUri), hst =>
           {
               hst.Username(userName);
               hst.Password(password);
           });

           cfg.ReceiveEndpoint(host,
                assetServiceQueue, e =>
                {
                    e.Consumer<AddNewAssetReceivedConsumer>();

                });

       });


        bus.Start();
        Console.WriteLine("Service Running.... Press enter to exit");
        Console.ReadLine();
        bus.Stop();

使用 RabbitMQ 客户端

        public static void Main()
    {
        var factory = new ConnectionFactory();
        factory.UserName = "ctas";
        factory.Password = "ctas@123";
        factory.VirtualHost = "watcherindustry";
        factory.HostName = "192.168.0.9";
        using (var connection = factory.CreateConnection())
        using (var channel = connection.CreateModel())
        {
            channel.QueueDeclare(queue: "hello",
                                 durable: false,
                                 exclusive: false,
                                 autoDelete: false,
                                 arguments: null);

            var consumer = new EventingBasicConsumer(channel);
            consumer.Received += (model, ea) =>
            {
                var body = ea.Body;
                var message = Encoding.UTF8.GetString(body);
                Console.WriteLine(" [x] Received {0}", message);
            };
            channel.BasicConsume(queue: "hello",
                                 autoAck: true,
                                 consumer: consumer);

            Console.WriteLine(" Press [enter] to exit.");
            Console.ReadLine();
        }
    }

Docker 文件

FROM microsoft/dotnet:1.1-runtime
ARG source
WORKDIR /app
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "TestClient.dll"]

也尝试在 MassTransit 配置中使用虚拟主机,不确定您为什么决定忽略它。

var host = cfg.Host("192.168.0.9", "watcherindustry", hst =>
{
     hst.Username(userName);
     hst.Password(password);
});

查看 Alexey Zimarev 对您问题的评论,如果您的兔子在容器上运行,那么它应该在您的 docker-compese 文件中,然后在您的端点定义中使用该条目连接到兔子,因为 docker 创建一个内部网络,你无法从源代码中获知...

rabbitmq:
     container_name: "rabbitmq-yournode01"
     hostname: rabbit
     image: rabbitmq:3.6.6-management
     environment:
        - RABBITMQ_DEFAULT_USER=yourusergoeshere
        - RABBITMQ_DEFAULT_PASS=yourpasswordgoeshere
        - RABBITMQ_DEFAULT_VHOST=vhost
     volumes:
        - rabbit-volume:/var/lib/rabbitmq
     ports:
        - "5672:5672"
        - "15672:15672"

在你的应用程序设置中你应该有一些谎言:

 "ConnectionString": "host=rabbitmq:5672;virtualHost=vhost;username=yourusergoeshere;password=yourpasswordgoeshere;timeout=0;prefetchcount=1",

如果您使用 EasyNEtQ,您可以:

 _bus = RabbitHutch.CreateBus(_connectionString); // The one above

希望对你有帮助,

胡安

我创建了一个 example,并且能够使用来自 masstransit 的预览包连接我的主机。

在docker中启动rabbitmq并在主机上公开端口

docker run -d -p 5672:5672 -p 15672:15672 --hostname my-rabbit --name some-rabbit rabbitmq:3-management

构建和 运行 控制台应用程序。

docker build -t dotnetapp .
docker run -d -e RABBITMQ_URI=rabbitmq://guest:guest@172.17.0.2:5672 --name some-dotnetapp dotnetapp

验证您收到的消息运行

docker logs some-dotnetapp --follow

您应该看到以下输出

Application is starting...
Connecting to rabbitmq://guest:guest@172.17.0.2:5672
Received: Hello, World [08/12/2017 04:35:53]
Received: Hello, World [08/12/2017 04:35:58]
Received: Hello, World [08/12/2017 04:36:03]
Received: Hello, World [08/12/2017 04:36:08]
Received: Hello, World [08/12/2017 04:36:13]
...

备注:

172.17.0.2 是我的兔子容器 ip 地址,但你可以用你的机器 ip 地址替换它 http://localhost:15672是rabbitmq管理控制台,用guest作为用户名和密码登录。

最后 portainer.io 是一个非常有用的应用程序,可以直观地查看您的本地 docker 环境。

感谢您的回复。我设法解决了这个问题。我的发现如下。

要连接到另一个 docker 容器上的 rabbitmq 实例,它们必须 moved/connected 到同一网络。去做这个 创建一个 newtork

   docker network create -d bridge my_bridge

将应用程序和 rabbitmq 容器连接到同一个网络

   docker network connect my_bridge <container name>

对于公共交通 uri 使用 rabbitmq 容器 该网络上的 IP 或容器名称

从 docker 容器上的应用程序连接主机的 rabbitmq 实例。 masstransit uri 应该包括 机器名称(我试过 IP,但没有用)