【问题标题】:Call Service Fabric service from console application using WCF HTTPS endpoint使用 WCF HTTPS 终结点从控制台应用程序调用 Service Fabric 服务
【发布时间】:2017-07-01 08:54:19
【问题描述】:

我在 Azure 的 Service Fabric 群集中托管了一项服务(不是本地),我正在尝试使用本地计算机上的控制台应用程序调用其中的方法。使用 WCF 进行通信,我在我的应用程序中的特定端口上设置了一个 HTTPS 端点,并在 Azure 门户中为该端口配置了负载平衡规则。集群有 6 个节点,应用程序是唯一部署在集群上的节点。

已遵循 GitHub (link) 上的 ServiceFabric.WcfCalc,它在使用 HTTP 端点的本地集群上工作,但一旦部署,就无法使用 HTTPS 端点调用服务上的方法。我需要做什么才能让它工作?已尝试按照示例 here 进行操作,但不知道如何为 HTTPS 配置此功能,并在多个节点上提供服务以供控制台应用程序访问。

提前致谢。

编辑这是我用来调用服务方法的客户端代码。我在这里将 fabric:/ URI 传递给构造函数。

public class Client : ServicePartitionClient<WcfCommunicationClient<IServiceInterface>>, IServiceInterface
{
    private static ICommunicationClientFactory<WcfCommunicationClient<IServiceInterface>> communicationClientFactory;

    static Client()
    {
        communicationClientFactory = new WcfCommunicationClientFactory<IServiceInterface>(
            clientBinding: new BasicHttpBinding(BasicHttpSecurityMode.Transport));
    }

    public Client(Uri serviceUri)
        : this(serviceUri, ServicePartitionKey.Singleton)
    { }

    public Client(
        Uri serviceUri,
        ServicePartitionKey partitionKey)
        : base(
            communicationClientFactory,
            serviceUri,
            partitionKey)
    { }


    public Task<bool> ServiceMethod(DataClass data)
    {
        try
        {
             //It hangs here
            return this.InvokeWithRetry((c) => c.Channel.ServiceMethod(data));
        }
        catch (Exception)
        {
            throw;
        }
    }
}

在本地计算机上调试控制台应用程序时,应用程序挂起在调用 Service Fabric 中我的服务中的方法的 InvokeWithRetry 调用上。应用程序不会抛出任何异常,也不会返回到 Visual Studio 中的调试器。

【问题讨论】:

  • 部署到集群后尝试调用服务上的方法时看到什么错误或问题?超时还是其他?
  • 我的代码中没有抛出异常,尽管我确实在 Service Fabric 群集资源管理器中看到了以下警告:-“HTTP 无法注册 URL http://+:443/26c710ea-38b9-4416 -9d70-c1710e698521/8d259277-ed49-4e11-b7ec-fac80075297e-131314658022522000/。另一个应用程序已经用 HTTP.SYS 注册了这个 URL。”当我从本地计算机上的控制台应用程序调用服务方法时,就会发生这种情况。上面已编辑问题以反映这一点。
  • 如果您正确配置了端点,我希望在 URL 中看到 HTTPS 而不是 HTTP。

标签: wcf azure azure-service-fabric


【解决方案1】:
  • 确保使用唯一的 url 运行每个服务实例/副本。

  • 确保使用WebHttpSecurityMode.Transport 调用WebHttpBinding 构造函数。

  • 确保使用与服务清单端点 declaration 相同的 端口 编号(可能为 443)注册 url。

  • 确保端点配置为HTTPS

【讨论】:

  • 我已经按照您的建议进行了操作,但是一旦我调试控制台应用程序并进入服务方法调用,应用程序就会挂起,并且不会返回到 Visual Studio 中的调试器。跨度>
  • 我以前没用过 Postman。我将使用什么地址,因为它肯定不会接受我在代码中用于 ServicePartitionClient 的 fabric:/ URI,我用它来调用服务方法。
  • 使用在 string uri = string.Format(CultureInfo.InvariantCulture, "{0}://{1}:{2}/", scheme, host, port); 行创建的 url 并公开一个元数据端点,以便您可以查询 wsdl。
【解决方案2】:

您在 Service Fabric 中看到的警告是告诉您已经注册了另一个服务来侦听您节点上的 port 443。这意味着 Service Fabric 无法启动您的服务(因为它在尝试使用 http.sys 注册 URL 时会在内部引发异常)。您可以将服务的端口更改为不会与现有服务冲突的其他端口,例如:

<Resources>
  <Endpoint Name="CalculatorEndpoint" Protocol="https" Type="Input" Port="44330" />
</Endpoints>

如果您在 https://{cluster_name}.{region}.cloudapp.azure.com:19080 上登录 Service Fabric Explorer,您应该能够看到那里正在运行的其他应用程序和服务。如果您将服务一直扩展到节点,您应该能够看到已注册的端点,包括现有服务的端口。

奖金 您可以使用FabricClient 查询集群中所有已注册的端点

var fabricClient = new FabricClient();
var applicationList = fabricClient.QueryManager.GetApplicationListAsync().GetAwaiter().GetResult();
foreach (var application in applicationList)
{
    var serviceList = fabricClient.QueryManager.GetServiceListAsync(application.ApplicationName).GetAwaiter().GetResult();
    foreach (var service in serviceList)
    {
        var partitionListAsync = fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName).GetAwaiter().GetResult();
        foreach (var partition in partitionListAsync)
        {
            var replicas = fabricClient.QueryManager.GetReplicaListAsync(partition.PartitionInformation.Id).GetAwaiter().GetResult();
            foreach (var replica in replicas)
            {
                if (!string.IsNullOrWhiteSpace(replica.ReplicaAddress))
                {
                    var replicaAddress = JObject.Parse(replica.ReplicaAddress);
                    foreach (var endpoint in replicaAddress["Endpoints"])
                    {
                        var endpointAddress = endpoint.First().Value<string>();
                        Console.WriteLine($"{service.ServiceName} {endpointAddress} {endpointAddress}");
                    }
}}}}}

只需使用正确的 FabricClient 凭据运行它(如果它是安全集群),您应该会看到它列出了那里所有服务的所有端点。这应该可以帮助您找到具有 :443 端点的那个

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-14
    • 2018-03-03
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2017-07-03
    • 2012-01-16
    • 1970-01-01
    相关资源
    最近更新 更多