【问题标题】:Call Azure Service Fabric from outside从外部调用 Azure Service Fabric
【发布时间】:2018-07-29 17:11:22
【问题描述】:

我正在使用 Azure Service Fabric 和控制台应用程序。我只是想让我的控制台应用程序连接到集群并做一些事情。

控制台应用尝试使用以下内容解析服务地址:

    static void Main(string[] args)
    {
        ServicePartitionResolver resolver = null;

        try
        {
            resolver = new ServicePartitionResolver(
                new string[] {
                    "localhost:19000",
                    "localhost:19001"
                });

            Uri serviceUri = new Uri("fabric:/StatefullServiceTEST/MyStatefulService");
            ResolvedServicePartition partition = resolver.ResolveAsync(serviceUri, new ServicePartitionKey(), CancellationToken.None).GetAwaiter().GetResult();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex.Message}");
        }
        Console.WriteLine();
        Console.Write("Press any key to exit...");
        Console.ReadKey();
    }

我的问题是resolver.ResolveAsync 抛出了一个似乎与 Service Fabric 没有任何联系的异常:

无法将“System.__ComObject”类型的 COM 对象转换为接口 键入“IFabricApplicationManagementClient10”。此操作失败 因为接口的 COM 组件上的 QueryInterface 调用 IID 为“{67001225-D106-41AE-8BD4-5A0A119C5C01}”失败,原因是 以下错误:不支持此类接口(来自 HRESULT 的异常: 0x80004002 (E_NOINTERFACE))。

对此有什么想法吗?

更新

我没有很清楚地解释我的问题以及我想要实现的目标。

我正在使用 Azure Service Fabric(无状态服务和有状态服务):我的问题是:调用托管在 Azure Service Fabric 中的微服务的最佳方式是什么?

问候, 阿提利奥

【问题讨论】:

  • 很可能是由于 nuget 包版本在您拥有的(较新的)集群拥有的(较旧的)之间不匹配。尝试将 Microsoft.ServiceFabric nuget 包降级到较低版本。

标签: c# dns azure-service-fabric


【解决方案1】:

您必须创建一个面向公众的服务(例如 Asp.net Core Web Api),它将服务结构内的服务功能暴露给外部世界(服务结构集群之外)。 FabricClient 方法将用于从服务结构集群内部而不是外部调用服务。

从您的 Asp.net Core 服务中,您将使用 FabricClient 访问托管的服务,因此通常您的 asp.net Core 应用程序充当反向代理来公开实际服务的功能。

【讨论】:

    【解决方案2】:

    您不能使用ServicePartitionResolver,它是一项可靠的服务功能,必须从集群中运行的服务中调用。

    我没看清楚你想要什么。

    如果您想管理服务并获取有关它的详细信息,例如查询正在运行的实例或副本,添加或删除实例等,请使用 Fabric Client,下面是一个快速的 sn-p,检查详细信息herehere:

    `

    using System.Fabric;
    using System.Security.Cryptography.X509Certificates;
    
    string clientCertThumb = "71DE04467C9ED0544D021098BCD44C71E183414E";
    string serverCertThumb = "A8136758F4AB8962AF2BF3F27921BE1DF67F4326";
    string CommonName = "www.clustername.westus.azure.com";
    string connection = "clustername.westus.cloudapp.azure.com:19000";
    
    var xc = GetCredentials(clientCertThumb, serverCertThumb, CommonName);
    var fc = new FabricClient(xc, connection);`
    

    或者,

    如果您想与正在运行的服务(例如 API)进行通信,您应该使用反向代理通过 URL 解析您的服务,如下面的 sn-p,更多详细信息 here

    http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService

    【讨论】:

    • 我正在尝试您建议的 FabricClient 解决方案,但我认为我的系统有问题。代码如下,很简单:try { FabricClient fabricClient = new FabricClient(); } catch (Exception ex) { Console.WriteLine($"Exception: {ex.Message}"); } 正如本文中所建议的那样,但我收到了同样的例外情况......你怎么看?问候,阿提利奥
    • FabricClient 可用于manage 服务,而不是调用它们。
    • 对不起,当你说连接到集群并做一些事情时,我想你想管理应用程序。我添加了两者,因为不知道你的意思是什么类型的东西。第一个示例是管理,第二个示例是与服务通信。我会更新我的答案以明确,您也可以更新您的问题以明确您希望做什么。
    【解决方案3】:

    您无法使用ServicePartitionResolver 从外部访问 ASF 集群中的服务。

    您的集群上必须有一个面向公众的端点,例如充当 Web api 的无状态服务。

    来自the docs

    集群内相互连接的服务通常可以直接访问其他服务的端点,因为集群中的节点位于同一个本地网络上。但是,在某些环境中,集群可能位于负载均衡器后面,该负载均衡器通过一组有限的端口路由外部入口流量。在这些情况下,服务仍然可以相互通信并使用命名服务解析地址,但必须采取额外步骤以允许外部客户端连接到服务。

    Azure 中的 Service Fabric 群集位于 Azure 负载均衡器后面。 到集群的所有外部流量都必须通过负载平衡器。负载均衡器会自动将给定端口上的入站流量转发到打开相同端口的随机节点。 Azure 负载均衡器只知道节点上打开的端口,它不知道各个服务打开的端口。

    因此,除非您的控制台应用程序以 guest executable 的形式托管在集群中,否则您还有更多工作要做。

    【讨论】:

    • 嗨,彼得。谢谢你的回答,我会深化论证。
    猜你喜欢
    • 1970-01-01
    • 2018-07-22
    • 2019-11-30
    • 1970-01-01
    • 2015-07-27
    • 2020-03-11
    • 2016-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多