2

我们有一个包含多种服务的 Service Fabric 服务项目:Actor、有状态服务和无状态服务组合成一个 ServiceManifest。

两个有状态服务不起作用:调用了构造函数,创建了通信侦听器(通过远程处理),但没有调用 RunAsync 方法。

从 ServiceManifest.xml 中删除端点列表后,服务再次开始工作。但是现在我们想知道为什么以及如何工作。有人可以解释一下吗?

为了说明,相关部分是

  <Resources>
    <Endpoints>
      <Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
      <Endpoint Name="StatelessServiceEndpoint1" Type="Input" Protocol="http" Port="10101" />
      <Endpoint Name="ActorServiceEndpoint1" />
      <Endpoint Name="ActorServiceReplicatorEndpoint1" />
      <Endpoint Name="ActorServiceEndpoint2" />
      <Endpoint Name="ActorServiceReplicatorEndpoint2" />
      <Endpoint Name="ActorServiceEndpoint3" />
      <Endpoint Name="ActorServiceReplicatorEndpoint3" />
      <Endpoint Name="ActorServiceEndpoint4" />
      <Endpoint Name="ActorServiceReplicatorEndpoint4" />
      <Endpoint Name="StatefulServiceEndpoint1" Type="Input" Protocol="http" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint1" />
      <Endpoint Name="StatefulServiceEndpoint2" Type="Input" Protocol="http" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint2" />
      <Endpoint Name="StatelessServiceEndPoint2" Type="Input" Protocol="http" />
    </Endpoints>
  </Resources>

改成这个后

  <Resources>
    <Endpoints>
      <Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
      <Endpoint Name="StatelessServiceEndpoint1" Protocol="http" />
      <Endpoint Name="ActorServiceReplicatorEndpoint1" />
      <Endpoint Name="ActorServiceReplicatorEndpoint2" />
      <Endpoint Name="ActorServiceReplicatorEndpoint3" />
      <Endpoint Name="ActorServiceReplicatorEndpoint4" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint1" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint2" />
    </Endpoints>
  </Resources>

一切正常。但为什么?

编辑 完整的 ServiceManifest 是这样的:

<?xml version="1.0" encoding="utf-8"?>
<ServiceManifest Name="Service" Version="1.0.0"
                 xmlns="http://schemas.microsoft.com/2011/01/fabric"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ServiceTypes>
    <StatefulServiceType ServiceTypeName="ActorService1Type" />
    <StatefulServiceType ServiceTypeName="ActorService1Type" HasPersistedState="true" />
    <StatefulServiceType ServiceTypeName="ActorService3Type" />
    <StatefulServiceType ServiceTypeName="ActorService4Type" HasPersistedState="true" />
    <StatefulServiceType ServiceTypeName="StatefulService1Type" HasPersistedState="true" />
    <StatefulServiceType ServiceTypeName="StatefulService2Type" HasPersistedState="true" />
    <StatelessServiceType ServiceTypeName="StatelessService1Type" />
    <StatelessServiceType ServiceTypeName="StatelessService2Type" />
    <StatelessServiceType ServiceTypeName="WebServiceType" />
  </ServiceTypes>
  <CodePackage Name="Code" Version="1.0.0">
    <SetupEntryPoint>
      <ExeHost>
        <Program>Setup.exe</Program>
      </ExeHost>
    </SetupEntryPoint>
    <EntryPoint>
      <ExeHost>
        <Program>Service.exe</Program>
      </ExeHost>
    </EntryPoint>
  </CodePackage>
  <ConfigPackage Name="Config" Version="1.0.0" />
  <Resources>
    <Endpoints>
      <Endpoint Name="WebServiceEndpoint" Type="Input" Protocol="http" Port="80" />
      <Endpoint Name="StatelessServiceEndpoint1" Protocol="http" />
      <Endpoint Name="ActorServiceReplicatorEndpoint1" />
      <Endpoint Name="ActorServiceReplicatorEndpoint2" />
      <Endpoint Name="ActorServiceReplicatorEndpoint3" />
      <Endpoint Name="ActorServiceReplicatorEndpoint4" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint1" />
      <Endpoint Name="StatefulServiceReplicatorEndpoint2" />
    </Endpoints>
  </Resources>
</ServiceManifest>
4

1 回答 1

3

很难知道在您最初报告的案例中发生了什么,因为没有具体的错误或错误消息可以解决,但通常这是端口冲突,当您最终共享您并不真正想要或无法共享的端口时,或端口耗尽。

服务清单中的端点资源主要用于以下情况:

  • 您希望 SF 帮助为您的服务分配通信资源,例如端口
  • 您希望 SF 帮助配置这些资源:
    • 分配一些端口并始终将其分配给一些工作负载
    • 在本地防火墙上打一个洞
    • 设置 URLACL(仅通过 http.sys 与 windows 上的 http 相关)
    • 设置和配置证书以启用安全通信(同样的警告)

一般来说,如果您不需要/不想要帮助,您可以随意忽略端点资源,因为 SF 确实希望服务代码来完成它的设置。在您没有真正使用 SF 的编程模型的情况下,端点资源更为重要,因为它是您与 SF 沟通端点是什么的方式。

您获得的行为实际上取决于您使用的传输方式,以及操作系统的动态端口范围和您定义的应用程序端口范围,以及服务代码实际执行的操作。

https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-fabric-settings#section-name-fabricnode

假设您正在像这样在您的服务中设置一个 http 通信侦听器,并通过一些示例来说明当您在清单中定义和终结点时会发生什么。

1)假设您在服务清单中没有放置任何关于端点的内容。这意味着您实际上将 0 指定为code中的端口。在这种情况下,顺丰不做任何分配或管理。该端口是由操作系统从操作系统动态端口范围分配的。每个服务实例侦听器实际分配的端口都不同。在大多数情况下,这应该是一个合理的默认选择。

2)假设您在清单中指定了一个端点,而根本没有指定任何端口,即:

<Endpoint Name="HealthServiceEndpoint"/>

在这种情况下,分配的端口将来自 SF 应用程序端口范围。对于托管在同一进程中的任何服务实例,它将是相同的,但跨进程不同。(因此,如果您使用的是独占或共享进程托管模型,这很重要)这也假定您的传输支持重用端口。大多数传输都没有(例如在 .NET 中通过 Kestrel 开启 http,在大多数情况下使用 TCP),但也有一些值得注意的示例(Windows 上基于 http.sys 的 http 传输,例如 WebListener/HttpSys,在 WCF 中通过 net.tcp 的 tcp 可能是其他几个)。

3) 假设您在服务结构清单中指定一个端点并为该端口明确指定 0,即:

<Endpoint Name="HealthServiceEndpoint" Port="0" Protocol="http"/>

在这种情况下,分配的端口将来自操作系统动态端口范围,并且对于托管在使用该端点的同一进程中的任何服务实例,它将最终相同/共享。端口将因进程而异。(因此,如果您使用的是独占或共享进程托管模型,这又很重要)

4) 自然,如果指定了端点并指定了特定端口,则该端口将用于进程内和跨进程的所有服务实例。这有点含蓄地假设这种共享会起作用,这又取决于您的传输和平台,或者您从未计划在此节点上运行多个服务实例。

其他琐事:

  • “transport”元素主要决定SF是在windows上用http.sys注册你的url还是配置证书来保护流量(大部分可以在你的服务代码或SetupEntryPoint中完成)。
  • 在撰写本文时,类型被忽略(这是旧版本 SF 的保留)
  • PathSuffix 用于创建一个默认的 uri 片段,该片段附加到平台分配的 IP 和端口。这用于有代码不使用 SF 的侦听器 API 的情况下,这些 API 在 /api/value 等不同的路径上设置了一些侦听器,就像容器内的代码可能做的那样。
于 2018-03-30T22:51:23.513 回答