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

问题描述 投票:2回答:1

我有一个.NET Core可靠服务,它几乎是一个模板服务,可从Add> New Service Fabric Service> .NET Core Stateless Service获得。这意味着它包含ServiceEventSource,从Stateless1类继承的StatelessService类和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://docs.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被删除了。

我认为这就是为什么我们必须在运行时再次提供。这是由SFBinaryLoader.cs通过在AppDomain.CurrentDomain.AssemblyResolve上添加事件侦听器来执行的。此类应查看FabricCodePath环境变量(在运行时该变量似乎绑定到C:\SFFabricBin\目录),然后手动添加这些二进制文件。

我想说,要使程序运行,我还必须从容器中删除*.deps.json文件,因为在运行dotnet Stateless1.dll之前我就遇到了一个异常,该异常表明在[[找不到*.deps.json文件。

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

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

这将引发以下异常:

注册服务System.Fabric.FabricException时发生异常:服务类型已被注册。 ---> System.Runtime.InteropServices.COMException:来自HRESULT的异常:0x80071BD1在System.Fabric.Interop.NativeRuntime.IFabricRuntime.EndRegisterStatelessServiceFactory(IFabricAsyncOperationContext上下文)处在System.Fabric.Interop.Utility。<> c__DisplayClass22_0.b__0(IFabricAsyncOperationContext上下文)在System.Fabric.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取消令牌)在C:\ MyLocalPath \ StatelessService \ Program.cs:line 33

中的Eventellect.Fabric.TestDocker.Program.Main()处

您知道为什么会这样吗?我还觉得很奇怪,我的published服务结构完全不了解我的本地路径。

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

我可能会缺少一些东西吗?

c# docker .net-core azure-service-fabric
1个回答
1
投票

我遇到了同样的问题,但是我实现了以不同于Microsoft文档中所示方式的方式对无状态服务进行容器化。

  1. microsoft / service-fabric-reliableservices-windowsservercore:1803 docker映像已安装.Net Core runtime 2.0。如果您的无状态服务在更高版本上运行,则将无法使用。因此,我以这种方式构建了我的docker镜像docker image servicefabric-runtime
  2. 我意识到对于在容器内运行Service Fabric可靠服务或可靠Actor而言,SFBinaryLoader.cs类不是必需的。我没有将其添加到我的代码中。
  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中找到完整的示例,>

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.