具有外部和内部端点的 Service Fabric Web Api

Posted

技术标签:

【中文标题】具有外部和内部端点的 Service Fabric Web Api【英文标题】:Service Fabric Web Api to have, both external and Internal endpoints 【发布时间】:2017-09-10 11:45:18 【问题描述】:

一些背景:

我们有一个 Service Fabric 应用程序,其中包含 2 个 WebApi 服务(以及其他)。一个是我们实际的前端 API,第二个是针对某些特定客户端的第一个 API 的代理。两个 WebApi 在不同的端口上公开。对于通信,我们使用了 Service 模板附带的 OwinCommunicationListener(我们只是对其进行了调整以允许使用 https )。当客户端调用代理 API 时,我们当前使用的是 HttpClient,它正在调用实际 API 的公共 IP 地址。

这显然没有意义,因为两个 WebApi 都托管在同一台机器上,所以我们希望通信是本地的,而不是通过互联网。对于 从 API 到其他微服务的通信,我们使用了内置的 ServiceProxy(强类型 RPC)。目前我们的前端 API 有两个监听器(http、https)。

为了实现我们的目标(API 拥有 2 个公共 http(s) 端点和一个内部端点),我们提出了将 RPC 侦听器与 http 侦听器一起添加到侦听器列表中的想法。因此,在这种情况下,API 将有 2 个用于公共流量的 http 侦听器和 1 个用于内部流量的 RPC。在这种情况下,我们将主 API 重构为从

继承

IService

,然后我们调整了 CreateServiceInstanceListeners 函数,它看起来像这样:

现在,当我运行应用程序时,主 Web API(现在从 IService 继承的那个)永远不会启动 - 在诊断窗口中,我可以看到创建侦听器的无限循环。这是否意味着不能同时使用 http 侦听器和内部强类型 RPC,或者我遗漏了什么?

我已阅读有关使用命名服务进行服务解析的信息,但是我找不到任何适合我的情况的文档或示例。

我真正需要做的是获取其他服务的本地地址,以便我可以通过 http 在本地调用它 - 这是我可以通过查询命名服务来实现的吗?或者也许我可以只使用本地主机地址?(无论如何负载都在前面平衡,所以我想此时不需要它,所以我可以在同一个节点上调用服务)

【问题讨论】:

localhost 选项对我来说最有意义。 【参考方案1】:

创建多个通信侦听器时,请确保将它们命名如下:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
        
            yield return new ServiceInstanceListener(p => new SubscriberCommunicationListener(this, p), "StatelessSubscriberCommunicationListener");
            yield return new ServiceInstanceListener(context => new FabricTransportServiceRemotingListener(context, this), "StatelessFabricTransportServiceRemotingListener");
        

这是使用名称创建代理的代码:

var subStateless = ServiceProxy.Create<ISubscribingStatelessService>(new    
    Uri("fabric:/MyServiceFabricApp/SubscribingStatelessService"),
    listenerName: "StatelessFabricTransportServiceRemotingListener");

Here's 一个示例实现。

【讨论】:

【参考方案2】:

可以通过REST API 或通过FabricClient 连接到集群来访问命名服务。这些 API 中的各种操作实际上都使用了命名服务。但是,它不是您可以(好吧,您至少不应该)连接到的服务。相反,您可以使用 FabricClient 的 QueryManager 列出集群中服务的注册端点。这将显示您的服务的注册端点。

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");
                    
                
            
        
    

【讨论】:

以上是关于具有外部和内部端点的 Service Fabric Web Api的主要内容,如果未能解决你的问题,请参考以下文章

使用 WS-MetadataExchange 为外部客户端和 WcfTestClient 从 Service Fabric 公开 WCF/TCP 终结点

Service-Fabric 绑定到多个端点

分析 Service Fabric 应用程序

Azure Service Fabric 群集端点不可访问

从公司代理服务器后面连接到Service Fabric集群端点

Service Fabric 命名服务未转发到分配给来宾可执行文件的端点