Masstransit в докере с использованием модели запросов / ответов, исключение запроса потребителя, хост не найден при ответе - PullRequest
0 голосов
/ 04 октября 2018

Я довольно новичок в Masstransit / RabbitMq, и я столкнулся с проблемой, с которой невозможно справиться.У меня есть сервер Rabbitmq, работающий в Docker, также небольшой микросервис в Docker-контейнере, который принимает событие.Кроме того, я запускаю службу Windows на хост-машине, которая имеет задачу отправить событие через модель запроса / ответа masstransit в микросервис.Интересно то, что событие приходит к потребителю, как предполагалось, но когда я пытаюсь ответить на context.RespondAsync из метода потребления, я получаю исключение

R-FAULT rabbitmq://autbus/exi_bus 80c60000-eca5-3065-0093-08d62a09d168 HwExi.Extensions.Events.ReservationCreateOrUpdateEvent HwExi.Api.Consumers.ReservationCrateOrUpdateConsumer(00:00:07.8902444) The host was not found for the specified address: rabbitmq://127.0.0.1/bus-SI-GEPE-HwService.Api-oddyyy8cwwagkoscbdmnwncfrg?durable=false&autodelete=true, MassTransit.EndpointNotFoundException: The host was not found for the specified address: rabbitmq://127.0.0.1/bus-SI-GEPE-HwService.Api-oddyyy8cwwagkoscbdmnwncfrg?durable=false&autodelete=true

Я использую эту модель для обмена сообщениями между микросервисамибез проблем и нормально работает в другой очереди.

Вот пример микросервиса / шины

exiapi:
image: exiapi
build:
  context: .
  dockerfile: Service/HwExi.Api/Dockerfile
ports:
  - "54542:80"
environment:
  "BUS_USERNAME": "guest"
  "BUS_PASSWORD": "guest"
  "BUS_HOST": "rabbitmq://autbus"
  "BUS_URL": "exi_bus"
autbus:
image: rabbitmq:3-management
hostname: autbus
ports:
  - "15672:15672"
  - "5672:5672"
  - "5671:5671"
volumes:
  - ~/rabbitmq:/var/lib/rabbitmq/mnesia

Конфигурация службы Windows:

"Bus": {
"Username": "guest",
"Password": "guest",
"Host": "rabbitmq://127.0.0.1",
"Url": "exi_bus"

},

Служба Windows подключается так:

var builder = new ContainerBuilder();
        builder.Register(context =>
        {
            return Bus.Factory.CreateUsingRabbitMq(rmq =>
            {
                var host = rmq.Host(new Uri(options.Value.Bus.Host), "/", h =>
                {
                    h.Username(options.Value.Bus.Username);
                    h.Password(options.Value.Bus.Password);
                });
                rmq.ExchangeType = ExchangeType.Fanout;
            });
        }).As<IBusControl>().As<IBus>().As<IPublishEndpoint>().SingleInstance();

Микросервис внутри контейнера подключается так

 public static class BusExtension
{
    public static void InitializeBus(this ContainerBuilder builder, Assembly assembly)
    {
        builder.Register(context =>
        {
            return Bus.Factory.CreateUsingRabbitMq(rmq =>
            {
                var host = rmq.Host(new Uri(Constants.Bus.Host), "/", h =>
                {
                    h.Username(Constants.Bus.UserName);
                    h.Password(Constants.Bus.Password);
                });
                rmq.ExchangeType = ExchangeType.Fanout;
                rmq.ReceiveEndpoint(host, Constants.Bus.Url, configurator =>
                {
                    configurator.LoadFrom(context);
                });
            });
        }).As<IBusControl>().As<IBus>().As<IPublishEndpoint>().SingleInstance();
        builder.RegisterConsumers(assembly);
    }

    public static void StartBus(this IContainer container, IApplicationLifetime lifeTime)
    {
        var bus = container.Resolve<IBusControl>();
        var busHandler = TaskUtil.Await(() => bus.StartAsync());
        lifeTime.ApplicationStopped.Register(() => busHandler.Stop());
    }
}

, чем служба Windows запускает событие следующим образом:

var reservation = ReservationRepository.Get(message.KeyId, message.KeySource);
        var operation = await ReservationCreateOrUpdateClient.Request(new ReservationCreateOrUpdateEvent { Reservation = reservation });
        if (!operation.Success)
        {
            Logger.LogError("Fatal error while sending reservation create or update message to exi web service");
            return;
        }

Наконец, микросервис ловит событие следующим образом.

public class ReservationCrateOrUpdateConsumer : IConsumer<ReservationCreateOrUpdateEvent>
{
    public async Task Consume(ConsumeContext<ReservationCreateOrUpdateEvent> context)
    {
        await context.RespondAsync(new MessageOperationResult<bool>
        {
            Result = true,
            Success = true
        });
    }
}

Я использую автофак для регистрации запроса клиента в службе Windows:

        Timeout = TimeSpan.FromSeconds(20);
        ServiceAddress = new Uri($"{Configurarion.Bus.Host}/{Configurarion.Bus.Url}");

            builder.Register(c => new MessageRequestClient<ReservationCreateOrUpdateEvent, MessageOperationResult<bool>>(c.Resolve<IBus>(), ServiceAddress, Timeout))
            .As<IRequestClient<ReservationCreateOrUpdateEvent, MessageOperationResult<bool>>>().SingleInstance();

Может кто-нибудьпомочь отладить это?Также поделитесь мнением, если эта структура является правильной, может быть, мне следует использовать https для отправки сообщения с клиентского компьютера в мою микросервисную среду и преобразовать его в шину через шлюз или аналогичный подход, более подходящий?Спасибо

...