Я пытаюсь настроить сценарий docker-compose - для запуска фиктивного: веб-сайт, API, Gateway и RabbitMQ. (микро сервис)
Запрос конвейера:
Веб >> Шлюз >> API >> RabbitMQ
Мой docker-compose выглядит так:
version: "3.4"
services:
web:
image: webclient
build:
context: ./WebClient
dockerfile: dockerfile
ports:
- "4000:4000"
depends_on:
- gateway
gateway:
image: gatewayapi
build:
context: ./GateWayApi
dockerfile: dockerfile
ports:
- "5000:5000"
depends_on:
- ordersapi
ordersapi:
image: ordersapi
build:
context: ./ExampleOrders
dockerfile: dockerfile
ports:
- "6002:6002"
depends_on:
- rabbitmq
rabbitmq:
image: rabbitmq:3.7-management
container_name: rabbitmq
hostname: rabbitmq
volumes:
- rabbitmqdata:/var/lib/rabbitmq
ports:
- "7000:15672"
- "7001:5672"
environment:
- RABBITMQ_DEFAULT_USER=rabbitmquser
- RABBITMQ_DEFAULT_PASS=some_password
Эта труба работает:
Интернет >> Шлюз >> API
Я получаю ответ от API на веб-сайте.
Но когда я пытаюсь отправить сообщение rabbitmq из API, я получаю следующую ошибку:
System.AggregateException: One or more errors occurred. (Connection failed) ---> RabbitMQ.Client.Exceptions.ConnectFailureException: Connection failed ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Connection refused 127.0.0.1:7001
GUI управления RabbitMQ по-прежнему работает на заданном порту 7000.
Запросы к порту 7001 нет.
Однако, если я запускаю API и RabbitMQ вручную, это работает как шарм. API, который я просто запускаю с помощью отладчика (.Net core + IIS - настройки по умолчанию для F5 в VS), и эту команду я использую для запуска образа докера вручную:
docker run -p 7001:5672 -p 7000:15672 --hostname localhost -e RABBITMQ_DEFAULT_USER=rabbitmquser -e RABBITMQ_DEFAULT_PASS=some_password rabbitmq:3.7-management
Обновление
Вот так я внедряю конфиг в основной канал .Net.
startup.cs
public void ConfigureServices(IServiceCollection services)
{
// setup RabbitMQ
var configSection = Configuration.GetSection("RabbitMQ");
string host = configSection["Host"];
int.TryParse(configSection["Port"], out int port);
string userName = configSection["UserName"];
string password = configSection["Password"];
services.AddTransient<IConnectionFactory>(_ => new ConnectionFactory()
{
HostName = host,
Port = port,
UserName = userName,
Password = password
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
controller.cs
private readonly IConnectionFactory _rabbitFactory;
public ValuesController(IConnectionFactory rabbitFactory)
{
_rabbitFactory = rabbitFactory;
}
public void PublishMessage()
{
try
{
using (var connection = _rabbitFactory.CreateConnection())
using (var channel = connection.CreateModel())
{
string exchangeName = "ExampleApiController";
string routingKey = "MyCustomRoutingKey";
channel.ExchangeDeclare(exchange: exchangeName, type: "direct", durable: true);
SendMessage("Payload to queue 1", channel, exchangeName, routingKey);
}
}
catch (Exception e)
{
Console.WriteLine(e.InnerException);
}
}
private static void SendMessage(string message, IModel channel, string exchangeName, string routingKey)
{
byte[] body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: exchangeName,
routingKey: routingKey,
basicProperties: null,
body: body);
Console.WriteLine($" Sending --> Exchange: { exchangeName } Queue: { routingKey } Message: {message}");
}