尝试在Service Fabric中容器化和发布StatelessService时发生异常



我有一个。NET核心可靠服务,它几乎是一个模板服务,从Add>NewServiceFabricService>获得。NET核心无状态服务。这意味着它包含ServiceEventSource、从StatelessService类继承的Stateless1类和Program.csProgram.cs的内容是默认的:

private static void Main()
{
try
{
ServiceRuntime.RegisterServiceAsync("Stateless1Type",
context => new Stateless1(context)).GetAwaiter().GetResult();                ServiceEventSource.Current.ServiceTypeRegistered(Process.GetCurrentProcess().Id, typeof(Stateless1).Name);
Thread.Sleep(Timeout.Infinite);
}
catch (Exception e)
{                ServiceEventSource.Current.ServiceHostInitializationFailed(e.ToString());
throw;
}
}

现在,这一切都很好,我可以正确启动Service Fabric应用程序并查看日志等。

根据下面的文章,我试图实现的是将此服务容器化:https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-services-inside-containers。这意味着我添加了SFBinaryLoader.cs,并将以下文件添加到我的Program.cs:

static Program()
{
SFBinaryLoader.Initialize();
}

然而,通过尝试,出现了许多文档中没有解决的问题。

我正在使用microsoft/service-fabric-reliableservices-windowsservercore:1803作为基本映像来构建我的容器。这是因为windows服务器主机的版本是1803。在运行CreateDockerPackage.ps1之后,我注意到Microsoft.ServiceFabric.Data.Interfaces.dllSystem.Fabric.*.dll正在被删除。

我认为这就是为什么我们必须在运行时再次提供。这是由CCD_ 10通过在CCD_。这个类应该查看FabricCodePath环境变量(在运行时它看起来绑定到C:SFFabricBin目录)并手动添加这些二进制文件。

我想说的是,为了让程序运行,我还必须从容器中删除*.deps.json文件,因为我甚至在运行dotnet Stateless1.dll之前就收到了一个异常,声明找不到*.deps.json文件上声明的一些丢失的二进制文件。

现在,看起来我的容器在结构上启动得很好,并且程序集正在正确加载。但是,每当尝试通过以下行将服务注册到结构时:

ServiceRuntime.RegisterServiceAsync("Stateless1Type",
context => new Stateless1(context)).GetAwaiter().GetResult();

这引发以下异常:

注册服务系统时发生异常。织物FabricException:服务类型已注册。--->系统运行时。InteropServices。COMException:HRESULT中的异常:0x80071BD1在系统中。织物Interop。NativeRuntime。IFabricRuntime。EndRegisterStatelessServiceFactory(IFabricAsyncOperationContext上下文)在系统中。织物Interop。实用程序<>c__DisplayClass22_0.b_0(IFabricAsyncOperationContext上下文)在系统中。织物Interop。AsyncCallOutAdapter21.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously) --- End of inner exception stack trace --- at Microsoft.ServiceFabric.Services.Runtime.ServiceRuntime.RegisterServiceAsync(String serviceTypeName, Func2 serviceFactory,TimeSpan超时,CancellationToken取消令牌)在Eventellect。织物TestDocker。程序C:\MyLocalPath\StatelessService\Program.cs:line 33中的Main()

你知道为什么会发生这种情况吗?我还发现非常奇怪的是,我的发布的服务结构对我的本地路径一无所知。

我已经在try...catch块中包围了RegisterServiceAsync调用,但是,即使线程成功进入睡眠状态,并且我的docker容器没有停止,我的Stateless1.cs类中的操作也永远不会执行。这意味着甚至没有调用构造函数。

我可能遗漏了什么吗?

我遇到了同样的问题,但我实现了以与微软文档中所示不同的方式容器化无状态服务。

  1. microsoft/servicefabric可靠服务windowsservercore:1803 docker镜像具有。已安装Net Core运行时2.0。如果您的无状态服务在更高版本上运行,它将不起作用。出于这个原因,我以这种方式构建了docker镜像servicefabric运行时
  2. 我意识到SFBinaryLoader.cs类对于在容器内运行Service Fabric Reliable Services或Reliable Actors不是必需的。我没有把它添加到我的代码中
  3. 我没有执行CreateDockerPackage.ps1来构建容器,我只修改了ServiceManifest.xml来更改EntryPoint部分,如下所示:
<EntryPoint>
<ContainerHost>
<ImageName>statelesscontainer:0.1</ImageName>
</ContainerHost>
</EntryPoint>
  1. 我将构建项目输出路径更改为pub/,并根据步骤1在无状态服务的根目录中手动添加Dockerfile,如下所示:
FROM edalx/servicefabric-runtime:dotnetcore-3.1.2
WORKDIR /app
ADD pub .
CMD ["ApiService.exe"]
  1. 此外,在ApplicationManifest.xml中还需要添加PortBinding标记
<ContainerHostPolicies CodePackageRef="Code" Isolation="process" ContainersRetentionCount="2">
<HealthConfig />
<PortBinding ContainerPort="0" EndpointRef="ServiceEndpoint" />
<ImageOverrides>
<Image Name="edalx.azurecr.io/statelesscontainer:0.1" />
</ImageOverrides>
</ContainerHostPolicies>
  1. 我使用的是Visual Studio Community 2019,为了进行部署,它会自动检测到它是一个容器,并将向导显示为非容器化服务,它将完成所有工作

我试过使用hyperv隔离,但对我来说没有用。

你可以在我的回购中找到一个完整的例子https://github.com/edalx/servicefabric-examples/tree/master/servicefabric-container

请检查容器化服务包的ServiceManifest.xml中的UseImplicitHost。UseImplicitHost需要设置为"False",可靠的用户进程才能向Runtime注册。对于GuestContainers和GuestExecutables,UseImplicitHost设置为true。

相关内容

  • 没有找到相关文章

最新更新