通过Service Fabric

时间:2016-06-22 21:21:22

标签: azure-service-fabric

我试图通过http公开基于WCF的restful服务,但到目前为止还没有成功。我首先尝试使用我的本地机器,以证明它有效。我找到了一个建议here,我删除了我的本地群集,然后以管理员身份从SF SDK文件夹手动运行此powershell命令,使用机器名绑定重新创建它:。\ DevClusterSetup.ps1 -UseMachineName

它成功创建了集群。我可以使用SF Explorer并在集群清单中看到NodeList中的条目显示的是机器名而不是localhost。这似乎很好。

但我注意到的第一个问题是,如果我通过SF Explorer扩展到我的应用程序运行的节点,我会看到一个端点条目,但URL不是我所期望的。我看到了这一点:http://surfacelap/d5be9425-3247-4290-b77f-1a90f728fb8d/39cda0f7-cef4-4c7f-8af2-d05786a834b0-131111019607641260

即使我有端点设置,这是我应该看到的吗?我没想到路径中的guid和其他数字。这让我怀疑SF没有看到我的服务是可公开访问的,而是可能只设置为在应用程序内部访问?如果我深入了解我的服务清单,我会看到这一点:

<Resources>
    <Endpoints>
      <Endpoint Name="ResolverEndpoint" Protocol="http" Type="Input" Port="80" />
    </Endpoints>
</Resources>

但我怎么知道服务本身是否映射到它?当我使用上面的疯狂长网并尝试一种简单的服务方法时,我得到了一个http 202响应,没有按预期的响应数据。如果我然后将方法名称更改为不存在的名称,我得到相同的东西,而不是预期的http 404.我已经尝试使用我的机器名称和localhost。结果相同。

很明显我做错了什么。下面是我的CreateServiceInstanceListeners重写。在其中您可以看到我使用“ResolverEndpoint”作为我的端点资源名称,它与服务清单匹配:

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[] { new ServiceInstanceListener((context) =>
            new WcfCommunicationListener<IResolverV2>(
                serviceContext: context,
                wcfServiceObject: new ResolverServiceV2(),
                listenerBinding: new WebHttpBinding(WebHttpSecurityMode.None),
                endpointResourceName: "ResolverEndpoint"
            )
        )};
    }

我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

服务清单中指定的端点资源由进程中使用相同端点资源名称的所有副本侦听器共享。因此,如果您的服务具有多个分区,则可能来自不同分区的多个副本可能最终在同一进程中。为了区分发往不同分区的消息,侦听器将分区ID和附加实例GUID添加到路径中。

如果您打算使用单一分区服务,并且知道同一进程中不会有多个副本,则可以直接提供EndpointAddress,您希望侦听器打开。使用CodePackageActivationContext API从NodeContext中获取端点资源名称,节点名称或IP地址的端口,然后提供您希望侦听器打开的路径。

以下是构造监听地址的WcfCommunicationListener中的代码。

  private static Uri GetListenAddress(
        ServiceContext serviceContext,
        string scheme,
        int port)
    {
        return new Uri(
            string.Format(
                CultureInfo.InvariantCulture,
                "{0}://{1}:{2}/{5}/{3}-{4}",
                scheme,
                serviceContext.NodeContext.IPAddressOrFQDN,
                port,
                serviceContext.PartitionId,
                serviceContext.ReplicaOrInstanceId,
                Guid.NewGuid()));
    }

请注意,您现在只能在节点上拥有一次应用程序,一个服务和一个分区,并且在本地进行测试时,请将该服务的实例计数保留为1.当在实际群集中部署时,您可以使用-1实例计数。

答案 1 :(得分:1)

以下是让它发挥作用的方法:https://github.com/loekd/ServiceFabric.WcfCalc

您的代码的基本更改是使用群集的公共名称作为端点URL以及该端点上的其他WebHttpBehavior行为。