Сервисная шина Azure - MessageLockLostException, когда приложение находится в контейнере Docker, в противном случае работает нормально - PullRequest
2 голосов
/ 07 марта 2019

У нас есть консольное приложение .NET Core, которое выполняет роль менеджера Saga / Process.

Это приложение Saga связывается с другими микросервисами через служебную шину Azure (с использованием MassTransit для абстракции обмена сообщениями - MassTransit.Azure.ServiceBus)

Приложение содержит конечный автомат (MassTransit / Automatonymous), который обрабатывает события, запускаемые сообщениями служебной шины.

В текущем сценарии начальное событие Saga запускается из приложения-функции Azure путем публикации сообщения через MassTransit:

busControl.Publish(createSearchPageLinkEvent);

СЕЙЧАС, когда:

a) приложение Saga запущено как есть (без контейнера) - все работает нормально, событие обрабатывается правильно.

b) приложение Saga помещается в Docker-контейнер, локально (с использованием docker-compose в VS2017) - возникает Exception . По сути - кажется, что после публикации сообщение действительно достигает приложения Saga, однако следующее исключение происходит мгновенно (отрывок):

Исключение получено на приемнике: sb: //***.servicebus.windows.net/link_provider_saga во время RenewLock, Microsoft.Azure.ServiceBus.MessageLockLostException: предоставленная блокировка является недействительным. Либо истек срок действия блокировки, либо сообщение уже было удалено из очереди

Вот код обработки сообщений в автомате состояний ( Automatonymous ), который никогда не будет достигнут, когда докеризован:

            Initially(
            When(CreateSearchPageLinkEvent)
                .Then(context =>
                {
                    //Exception occurs before we get here
                    _log.Information($"{context.Instance.CorrelationId} CreateSearchPageLinkEvent for ");
                    context.Instance.PropertyType = context.Data.PropertyType;
                    context.Instance.SideName = context.Data.SideName;
                    context.Instance.TransactionType = context.Data.TransactionType;
                    context.Instance.Url = context.Data.Url;
                })

Вот конфигурация docker-compose:

    version: '3.4'

services:
  saga.azure:
    image: ${DOCKER_REGISTRY-}sagaazure
    build:
      context: .
      dockerfile: AcquireLinkTaskTracking.Azure\Dockerfile
    ports:
      - "443:443"
      - "5671:5671"
      - "5672:5672"
      - "9350-9354:9350-9354"

Вот DockerFile приложения:

FROM microsoft/dotnet:2.1-runtime-nanoserver-1803 AS base
WORKDIR /app

FROM microsoft/dotnet:2.1-sdk-nanoserver-1803 AS build
WORKDIR /src

RUN dotnet restore AcquireLinkTaskTracking.Azure/Saga.Azure.csproj
//(...) Lots of dependendcy copying here
COPY . .
WORKDIR /src/AcquireLinkTaskTracking.Azure
RUN dotnet build Saga.Azure.csproj -c Debug -o /app

FROM build AS publish
RUN dotnet publish Saga.Azure.csproj -c Debug -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Saga.Azure.dll"]

Почему Docker вызывает проблемы со связью? Мои догадки:

a) неправильное сопоставление / публикация портов - однако запускающий микросервис, очевидно, каким-то образом достигает контейнера

b) Протокол / сертификат TLS (используемый служебной шиной Azure) настроены неправильно (это не тривиальная задача)

PS докернизированное приложение Saga запускается из VS2017 локально с помощью «Начать отладку» с помощью docker-compose

PS2, использующий EXPOSE для порта 80 в Dockerfile, не решил проблему

Ответы [ 2 ]

0 голосов
/ 11 марта 2019

Хорошо, это была простая проблема:

Мы просто использовали неверный базовый образ.Требуется образ времени выполнения ядра asp net.Различия с нашим докер-файлом выглядят так:

-FROM microsoft/dotnet:2.1-runtime-nanoserver-1803 AS base
+FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-sac2016 AS base

-FROM microsoft/dotnet:2.1-sdk-nanoserver-1803 AS build
+FROM microsoft/dotnet:2.1-sdk-nanoserver-sac2016 AS build

живи, учись.

0 голосов
/ 07 марта 2019

Почему Docker вызывает проблемы со связью?

Я подозреваю, что возникла проблема с сетью.Временные ошибки будут иметь место, и как пользователь вы должны повторить попытку.И это не просто Docker, где вы можете столкнуться с этой проблемой.

RenewLock - это инициируемая на стороне клиента операция, которая не гарантируется успешной.Таким образом, невозможность возобновить блокировку сообщения должна обрабатываться механизмом повторной попытки.Вам нужно будет подтвердить с MassTransit, если это реализовано или нет.Если нет, ваш код продолжит обрабатывать сообщение, предполагая, что блокировка была расширена, когда это не так.И когда попытка завершения входящего сообщения будет предпринята, вы получите исключение MessageLockLostException.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...