Azure 服务总线 - 当应用程序位于 Docker 容器中时出现 MessageLockLostException,否则工作正常
Azure Service Bus - MessageLockLostException when app is in Docker container, works fine otherwise
我们有一个 .NET Core 控制台应用程序充当 Saga/Process 管理员的角色。
此 Saga 应用程序通过 Azure 服务总线 与其他微服务通信(使用 MassT运行sit 进行消息传递抽象 - MassTransit.Azure.ServiceBus)
该应用程序包含一个状态机 (MassTransit/Automatonymous),用于处理由服务总线消息触发的事件。
在当前场景中,初始 Saga 事件是通过 MassT 发布消息从 Azure Function App 触发的运行sit:
busControl.Publish(createSearchPageLinkEvent);
现在,时间:
a) Saga 应用 运行 按原样,(没有容器化)- 一切正常,事件处理正确。
b) Saga 应用程序被放入 Docker 容器中,本地(在 VS2017 中使用 docker-compose)- 异常发生。本质上 - 似乎在发布消息后确实到达了 Saga 应用程序,但是立即发生以下异常(摘录):
Exception received on receiver:
sb://***.servicebus.windows.net/link_provider_saga during RenewLock,
Microsoft.Azure.ServiceBus.MessageLockLostException: The lock supplied
is invalid. Either the lock expired, or the message has already been
removed from the queue
这是状态机 (Automatonymous) 中的消息处理代码,在 dockerized:
时永远不会到达
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"
这是应用程序的Docker文件:
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) 不正确的端口 mapping/publishing - 然而触发微服务显然以某种方式到达容器
b) TLS protocol/certificate(由 Azure 服务总线使用)设置不正确(这不是一件小事)
PS dockerized Saga 应用程序由 "Start Debugging" 和 docker-compose
在本地从 VS2017 启动
PS2 在 Docker 文件中对端口 80 使用 EXPOSE 未解决问题
Why would Docker cause communication issue?
我怀疑是网络问题。间歇性错误将发生,作为用户,您必须重试。而且不只是 Docker 你可以 运行 解决这个问题。
RenewLock
是客户端发起的操作,不保证一定会成功。因此,更新消息锁失败应该由重试机制处理。您需要与 MassTransit 确认是否已实施。如果没有,您的代码将继续处理消息,假设锁定在未扩展时被扩展。当尝试完成传入消息时,您将收到 MessageLockLostException
异常。
好的,这是一个简单的问题:
我们只是使用了错误的基础图像。需要 asp 网络核心运行时映像。我们的 dockerfile 的差异是这样的:
-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
你生活,你学习。
我们有一个 .NET Core 控制台应用程序充当 Saga/Process 管理员的角色。
此 Saga 应用程序通过 Azure 服务总线 与其他微服务通信(使用 MassT运行sit 进行消息传递抽象 - MassTransit.Azure.ServiceBus)
该应用程序包含一个状态机 (MassTransit/Automatonymous),用于处理由服务总线消息触发的事件。
在当前场景中,初始 Saga 事件是通过 MassT 发布消息从 Azure Function App 触发的运行sit:
busControl.Publish(createSearchPageLinkEvent);
现在,时间:
a) Saga 应用 运行 按原样,(没有容器化)- 一切正常,事件处理正确。
b) Saga 应用程序被放入 Docker 容器中,本地(在 VS2017 中使用 docker-compose)- 异常发生。本质上 - 似乎在发布消息后确实到达了 Saga 应用程序,但是立即发生以下异常(摘录):
Exception received on receiver: sb://***.servicebus.windows.net/link_provider_saga during RenewLock, Microsoft.Azure.ServiceBus.MessageLockLostException: The lock supplied is invalid. Either the lock expired, or the message has already been removed from the queue
这是状态机 (Automatonymous) 中的消息处理代码,在 dockerized:
时永远不会到达 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"
这是应用程序的Docker文件:
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) 不正确的端口 mapping/publishing - 然而触发微服务显然以某种方式到达容器
b) TLS protocol/certificate(由 Azure 服务总线使用)设置不正确(这不是一件小事)
PS dockerized Saga 应用程序由 "Start Debugging" 和 docker-compose
在本地从 VS2017 启动PS2 在 Docker 文件中对端口 80 使用 EXPOSE 未解决问题
Why would Docker cause communication issue?
我怀疑是网络问题。间歇性错误将发生,作为用户,您必须重试。而且不只是 Docker 你可以 运行 解决这个问题。
RenewLock
是客户端发起的操作,不保证一定会成功。因此,更新消息锁失败应该由重试机制处理。您需要与 MassTransit 确认是否已实施。如果没有,您的代码将继续处理消息,假设锁定在未扩展时被扩展。当尝试完成传入消息时,您将收到 MessageLockLostException
异常。
好的,这是一个简单的问题:
我们只是使用了错误的基础图像。需要 asp 网络核心运行时映像。我们的 dockerfile 的差异是这样的:
-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
你生活,你学习。