我们有一个Service Fabric Service项目,提供多种服务:Actors,Stateful services和Stateless services合并为一个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>
答案 0 :(得分:2)
很难知道在您的初始报告案例中发生了什么,因为没有特定的错误或错误消息可以解决,但通常这会导致端口冲突,当您最终共享您不想要的端口或哪些可以'共享,或端口耗尽。
服务清单中的端点资源主要用于以下时间:
一般情况下,如果您不需要/想要帮助,您可以自由地忽略端点资源,因为SF确实希望服务代码能够进行设置。如果您没有真正使用SF的编程模型,那么端点资源更重要,因为它是您与SF通信端点的方式。
您获得的行为实际上取决于您正在使用的传输,以及操作系统的动态端口范围和您定义的应用程序端口范围,以及服务代码实际执行的操作。
假设您在服务中设置了一个http通信监听器,如so,并详细介绍了清单中定义和端点时发生的情况,或者不清楚。
1)假设您在服务清单中没有任何关于端点的信息。这意味着您有效地将0指定为端口in code。在这种情况下,SF没有进行任何分配或管理。操作系统从OS动态端口范围分配端口。对于每个服务实例侦听器,实际分配的端口将是不同的。在大多数情况下,这应该作为合理的默认选择。
2)假设您在清单中指定了一个端点,而没有指定任何端口,即:
<Endpoint Name="HealthServiceEndpoint"/>
在这种情况下,分配的端口将来自SF应用程序端口范围。对于在同一进程中托管的任何服务实例,它们都是相同的,但不同的进程不同。 (因此,如果您使用独占或共享process hosting model,这很重要)这也假设您的传输支持重用端口。大多数传输都没有(例如在.NET上通过Kestrel的http,在大多数情况下使用TCP),但是有一些值得注意的例子(基于http.sys的http传输在Windows上像WebListener / HttpSys,tcp通过net.tcp在WCF中可能是一个很少人)。
3)假设您在服务结构清单中指定了一个端点,并为该端口明确指定了0,即:
<Endpoint Name="HealthServiceEndpoint" Port="0" Protocol="http"/>
在这种情况下,分配的端口将来自OS动态端口范围,并且对于使用该端点的同一进程中托管的任何服务实例,它将最终相同/共享。端口在不同进程中会有所不同。 (因此,如果您使用独家或共享process hosting model)
,这一点很重要4)当然,如果指定了端点并指定了特定端口,则该端口将用于进程内和进程之间的所有服务实例。这有点隐含地假设这样的共享将起作用,这又取决于您的传输和平台,或者您从未计划在此节点上运行多个服务实例。
其他琐事: