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,但没有用)
我创建了一个具有 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,但没有用)