在 Service Fabric 中与服务建立连接和通信Connect and communicate with services in Service Fabric

在 Service Fabric 中,服务在 Service Fabric 群集(通常分布在多个 VM 间)中的某个位置运行。In Service Fabric, a service runs somewhere in a Service Fabric cluster, typically distributed across multiple VMs. 它可以从一个位置移动到另一个位置(由服务所有者移动或由 Service Fabric 自动移动)。It can be moved from one place to another, either by the service owner, or automatically by Service Fabric. 服务不以静态方式绑定到特定计算机或地址。Services are not statically tied to a particular machine or address.

Service Fabric 应用程序通常由许多不同服务组成,其中每个服务执行专门任务。A Service Fabric application is generally composed of many different services, where each service performs a specialized task. 这些服务可能会相互进行通信以形成一个完整功能,如呈现 Web 应用程序的不同部分。These services may communicate with each other to form a complete function, such as rendering different parts of a web application. 其中也有连接到服务并与之通信的客户端应用程序。There are also client applications that connect to and communicate with services. 本文档介绍如何在 Service Fabric 中设置与服务进行的通信以及服务之间的通信。This document discusses how to set up communication with and between your services in Service Fabric.

自带协议Bring your own protocol

Service Fabric 可帮助管理服务的生命周期,但是它不会制定有关服务执行的操作的决策。Service Fabric helps manage the lifecycle of your services but it does not make decisions about what your services do. 这包括通信。This includes communication. 服务由 Service Fabric 打开时,服务可以使用所需的任何协议或通信堆栈为传入请求设置终结点。When your service is opened by Service Fabric, that's your service's opportunity to set up an endpoint for incoming requests, using whatever protocol or communication stack you want. 服务使用任何寻址方案(如 URI)来侦听一般的 IP: 端口 地址。Your service will listen on a normal IP:port address using any addressing scheme, such as a URI. 多个服务实例或副本可能会共享主机进程,在这种情况下,它们需要使用不同端口,或使用端口共享机制(例如 Windows 中的 http.sys 内核驱动程序)。Multiple service instances or replicas may share a host process, in which case they will either need to use different ports or use a port-sharing mechanism, such as the http.sys kernel driver in Windows. 在任一情况下,主机进程中的每个服务实例或副本都必须可唯一寻址。In either case, each service instance or replica in a host process must be uniquely addressable.


服务发现和解析Service discovery and resolution

在分布式系统中,服务可能随时间推移从一台计算机移动到另一台计算机。In a distributed system, services may move from one machine to another over time. 发生这种情况可能是由于各种原因,包括资源平衡、升级、故障转移或扩大。这意味着服务终结点地址会在服务移动到具有不同 IP 地址的节点时发生更改,并且可能在不同端口上打开(如果服务使用动态选择的端口)。This can happen for various reasons, including resource balancing, upgrades, failovers, or scale-out. This means service endpoint addresses change as the service moves to nodes with different IP addresses, and may open on different ports if the service uses a dynamically selected port.


Service Fabric 提供一种服务发现和解析服务,称为“命名服务”。Service Fabric provides a discovery and resolution service called the Naming Service. 命名服务维护一个表,它将命名服务实例映射到它们所侦听的终结点地址。The Naming Service maintains a table that maps named service instances to the endpoint addresses they listen on. Service Fabric 中的所有命名服务实例都具有表示为 URI 的唯一名称,例如 "fabric:/MyApplication/MyService"All named service instances in Service Fabric have unique names represented as URIs, for example, "fabric:/MyApplication/MyService". 服务的名称在服务的生存期内不会更改,只有终结点地址才能在服务移动时发生更改。The name of the service does not change over the lifetime of the service, it's only the endpoint addresses that can change when services move. 这与 URL 保持不变但 IP 地址可能会更改的网站类似。This is analogous to websites that have constant URLs but where the IP address may change. 与 Web 上的 DNS(将网站 URL 解析为 IP 地址)类似,Service Fabric 具有一个注册机构,它将服务名称映射到其终结点地址。And similar to DNS on the web, which resolves website URLs to IP addresses, Service Fabric has a registrar that maps service names to their endpoint address.

此图显示了 Service Fabric 具有将服务名称映射到其终结点地址的注册器。

解析服务以及连接到服务涉及循环运行的以下步骤:Resolving and connecting to services involves the following steps run in a loop:

  • 解析:从命名服务获取服务发布的终结点。Resolve: Get the endpoint that a service has published from the Naming Service.
  • 连接:通过服务在该终结点上使用的任何协议连接到服务。Connect: Connect to the service over whatever protocol it uses on that endpoint.
  • 重试:连接尝试可能会由于许多原因而失败(例如,如果服务自上次解析终结点地址以来已移动)。Retry: A connection attempt may fail for any number of reasons, for example if the service has moved since the last time the endpoint address was resolved. 在这种情况下,前面的解析和连接步骤需要重试,并且此循环会重复执行,直到连接成功。In that case, the preceding resolve and connect steps need to be retried, and this cycle is repeated until the connection succeeds.

连接到其他服务Connecting to other services

在群集内相互连接的服务通常可以直接访问其他服务的终结点,因为群集中的节点处于相同的本地网络上。Services connecting to each other inside a cluster generally can directly access the endpoints of other services because the nodes in a cluster are on the same local network. 为了更轻松地在服务之间连接,Service Fabric 提供使用命名服务的其他服务。To make is easier to connect between services, Service Fabric provides additional services that use the Naming Service. DNS 服务和反向代理服务。A DNS service and a reverse proxy service.

DNS 服务DNS service

由于许多服务(特别是容器化服务)可以拥有一个现有的 URL 名称,能够使用标准 DNS 协议(而不是命名服务协议)解析这些名称会十分方便,尤其是在应用程序“提升和转移”方案中。Since many services, especially containerized services, can have an existing URL name, being able to resolve these using the standard DNS protocol (rather than the Naming Service protocol) is very convenient, especially in application "lift and shift" scenarios. 这正是 DNS 服务能够发挥作用的地方。This is exactly what the DNS service does. 借助 DNS 服务,用户能够将 DNS 名称映射到服务名称,进而解析终结点 IP 地址。It enables you to map DNS names to a service name and hence resolve endpoint IP addresses.

如下图所示,Service Fabric 群集中运行的 DNS 服务会将 DNS 名称映射到服务名称,服务名称随后会被命名服务解析,以返回要连接的终结点地址。As shown in the following diagram, the DNS service, running in the Service Fabric cluster, maps DNS names to service names which are then resolved by the Naming Service to return the endpoint addresses to connect to. 在创建时提供服务的 DNS 名称。The DNS name for the service is provided at the time of creation.

此图显示了 DNS 服务在 Service Fabric 群集中运行时如何将 DNS 名称映射到服务名称,然后命名服务解析服务名称以返回要连接的终结点地址。

有关如何使用 DNS 服务的更多详细信息,请参阅 Azure Service Fabric 中的 DNS 服务一文。For more details on how to use the DNS service see DNS service in Azure Service Fabric article.

反向代理服务Reverse proxy service

反向代理处理群集中的服务,群集公开包括 HTTPS 在内的 HTTP 终结点。The reverse proxy addresses services in the cluster that exposes HTTP endpoints including HTTPS. 反向代理具有特定的 URI 格式,能够极大地简化调用其他服务及其方法的操作,它能够处理一个服务使用命名服务与其他服务进行通信所需完成的解析、连接、重试步骤。The reverse proxy greatly simplifies calling other services and their methods by having a specific URI format and handles the resolve, connect, retry steps required for one service to communicate with another using the Naming Service. 换而言之,它会在调用其他服务时对用户隐藏命名服务,并让这一操作和调用 URL 一样简单。In other words, it hides the Naming Service from you when calling other services by making this as simple as calling a URL.

此图显示了反向代理如何处理群集中公开 HTTP 终结点(包括 HTTPS)的服务。

有关如何使用反向代理服务的更多详细信息,请参阅 Azure Service Fabric 中的反向代理一文。For more details on how to use the reverse proxy service see Reverse proxy in Azure Service Fabric article.

来自外部客户端的连接Connections from external clients

在群集内相互连接的服务通常可以直接访问其他服务的终结点,因为群集中的节点处于相同的本地网络上。Services connecting to each other inside a cluster generally can directly access the endpoints of other services because the nodes in a cluster are on the same local network. 但是在某些环境中,群集可能位于通过一组有限端口对入口流量进行路由的负载均衡器之后。In some environments, however, a cluster may be behind a load balancer that routes ingress traffic through a limited set of ports. 在这些情况下,服务仍可以使用命名服务相互通信和解析地址,但必须执行额外步骤才能允许外部客户端连接到服务。In these cases, services can still communicate with each other and resolve addresses using the Naming Service, but extra steps must be taken to allow external clients to connect to services.

Azure 中的 Service FabricService Fabric in Azure

Azure 中的 Service Fabric 群集位于 Azure 负载均衡器之后。A Service Fabric cluster in Azure is placed behind an Azure Load Balancer. 发送到群集的所有外部流量都必须通过该负载均衡器。All external traffic to the cluster must pass through the load balancer. 该负载均衡器自动在给定端口上将入站流量转发到打开了相同端口的随机 节点The load balancer will automatically forward traffic inbound on a given port to a random node that has the same port open. Azure 负载均衡器只了解节点上打开的端口,它不了解各个服务打开的端口 。The Azure Load Balancer only knows about ports open on the nodes, it does not know about ports open by individual services.

Azure 负载均衡器和 Service Fabric 拓扑

例如,若要在端口 80 上接受外部流量,必须配置以下项:For example, in order to accept external traffic on port 80, the following things must be configured:

  1. 编写侦听端口 80 的服务。Write a service that listens on port 80. 在服务的 ServiceManifest.xml 中配置端口 80,并在服务中打开一个侦听器,例如自托管的 Web 服务器。Configure port 80 in the service's ServiceManifest.xml and open a listener in the service, for example, a self-hosted web server.

            <Endpoint Name="WebEndpoint" Protocol="http" Port="80" />
        class HttpCommunicationListener : ICommunicationListener
            public Task<string> OpenAsync(CancellationToken cancellationToken)
                EndpointResourceDescription endpoint =
                string uriPrefix = $"{endpoint.Protocol}://+:{endpoint.Port}/myapp/";
                this.httpListener = new HttpListener();
                string publishUri = uriPrefix.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);
                return Task.FromResult(publishUri);
        class WebService : StatelessService
            protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
                return new[] { new ServiceInstanceListener(context => new HttpCommunicationListener(context))};
        class HttpCommunicationlistener implements CommunicationListener {
            public CompletableFuture<String> openAsync(CancellationToken arg0) {
                EndpointResourceDescription endpoint =
                try {
                    HttpServer server = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(endpoint.getPort()), 0);
                    String publishUri = String.format("http://%s:%d/",
                        this.serviceContext.getNodeContext().getIpAddressOrFQDN(), endpoint.getPort());
                    return CompletableFuture.completedFuture(publishUri);
                } catch (IOException e) {
                    throw new RuntimeException(e);
        class WebService extends StatelessService {
            protected List<ServiceInstanceListener> createServiceInstanceListeners() {
                <ServiceInstanceListener> listeners = new ArrayList<ServiceInstanceListener>();
                listeners.add(new ServiceInstanceListener((context) -> new HttpCommunicationlistener(context)));
                return listeners;       
  2. 在 Azure 中创建 Service Fabric 群集,并将端口 80 指定为要承载服务的节点类型的自定义终结点端口。Create a Service Fabric Cluster in Azure and specify port 80 as a custom endpoint port for the node type that will host the service. 如果具有多种节点类型,则可以对服务设置 放置约束 ,以确保它只在打开了自定义终结点端口的节点类型上运行。If you have more than one node type, you can set up a placement constraint on the service to ensure it only runs on the node type that has the custom endpoint port opened.


  3. 创建了群集之后,在群集的资源组中配置 Azure 负载均衡器以在端口 80 上转发流量。Once the cluster has been created, configure the Azure Load Balancer in the cluster's Resource Group to forward traffic on port 80. 通过 Azure 门户创建群集时,会为每个已配置的自定义终结点端口自动设置此项。When creating a cluster through the Azure portal, this is set up automatically for each custom endpoint port that was configured.


  4. Azure 负载均衡器使用探测确定是否要将流量发送到特定节点。The Azure Load Balancer uses a probe to determine whether or not to send traffic to a particular node. 探测会定期检查每个节点上的终结点以确定节点是否正在进行响应。The probe periodically checks an endpoint on each node to determine whether or not the node is responding. 如果探测未能在配置的次数之后收到响应,则负载均衡器会停止将流量发送到该节点。If the probe fails to receive a response after a configured number of times, the load balancer stops sending traffic to that node. 通过 Azure 门户创建群集时,会为每个已配置的自定义终结点端口自动设置探测。When creating a cluster through the Azure portal, a probe is automatically set up for each custom endpoint port that was configured.

    在 Azure 负载均衡器中转发流量

请务必记住,Azure 负载均衡器和探测只了解节点,而不了解在节点上运行的服务 。It's important to remember that the Azure Load Balancer and the probe only know about the nodes, not the services running on the nodes. Azure 负载均衡器始终将流量发送到响应探测的节点,因此必须格外小心以确保服务在能够响应探测的节点上可用。The Azure Load Balancer will always send traffic to nodes that respond to the probe, so care must be taken to ensure services are available on the nodes that are able to respond to the probe.

Reliable Services:内置通信 API 选项Reliable Services: Built-in communication API options

Reliable Services 框架附带几个预建的通信选项。The Reliable Services framework ships with several pre-built communication options. 可以根据所选的编程模型、通信框架和编写服务时使用的编程语言决定哪个选项最适合自己。The decision about which one will work best for you depends on the choice of the programming model, the communication framework, and the programming language that your services are written in.

  • 无特定协议: 如果没有选择特定的通信框架,但想要快速启动并运行某个程序,则理想之选是 服务远程处理,此项允许对 Reliable Services 和 Reliable Actors 进行强类型远程过程调用。No specific protocol: If you don't have a particular choice of communication framework, but you want to get something up and running quickly, then the ideal option for you is service remoting, which allows strongly-typed remote procedure calls for Reliable Services and Reliable Actors. 这是服务通信入门最简单、最快捷的方法。This is the easiest and fastest way to get started with service communication. 服务远程处理可处理服务地址的解析、连接、重试和错误处理。Service remoting handles resolution of service addresses, connection, retry, and error handling. 这适用于 C# 和 Java 应用程序。This is available for both C# and Java applications.
  • HTTP:对于与语言无关的通信,HTTP 为行业标准选择提供了可在许多不同语言(Service Fabric 全都支持)中使用的工具和 HTTP 服务器。HTTP: For language-agnostic communication, HTTP provides an industry-standard choice with tools and HTTP servers available in many different languages, all supported by Service Fabric. 服务可以使用提供的任何 HTTP 堆栈,包括适用于 C# 应用程序的 ASP.NET Web APIServices can use any HTTP stack available, including ASP.NET Web API for C# applications. 以 C# 编写的客户端可以利用 ICommunicationClientServicePartitionClient 类(而 Java 则可以使用 CommunicationClientFabricServicePartitionClient 类)来进行服务解析、HTTP 连接和重试循环Clients written in C# can leverage the ICommunicationClient and ServicePartitionClient classes, whereas for Java, use the CommunicationClient and FabricServicePartitionClient classes, for service resolution, HTTP connections, and retry loops.
  • WCF:如果具备将 WCF 用作通信框架的现有代码,则可将 WcfCommunicationListener 用于服务器端,并将 WcfCommunicationClientServicePartitionClient 类用于客户端。WCF: If you have existing code that uses WCF as your communication framework, then you can use the WcfCommunicationListener for the server side and WcfCommunicationClient and ServicePartitionClient classes for the client. 但是,这仅适用于基于 Windows 的群集上的 C# 应用程序。This however is only available for C# applications on Windows based clusters. 有关更多详细信息,请参阅这篇有关通信堆栈的基于 WCF 的实现的文章。For more details, see this article about WCF-based implementation of the communication stack.

使用自定义协议和其他通信框架Using custom protocols and other communication frameworks

服务可以使用任何协议或框架进行通信,无论它是 TCP 套接字上的自定义二进制协议,还是通过 Azure 事件中心Azure IoT 中心实现的流式处理事件。Services can use any protocol or framework for communication, whether its a custom binary protocol over TCP sockets, or streaming events through Azure Event Hubs or Azure IoT Hub. Service Fabric 提供了通信 API,可以将通信堆栈插入其中,同时将用于发现和连接的所有工作与你分离。Service Fabric provides communication APIs that you can plug your communication stack into, while all the work to discover and connect is abstracted from you. 有关更多详细信息,请参阅这篇有关 Reliable Service 通信模型的文章。See this article about the Reliable Service communication model for more details.

后续步骤Next steps

了解有关 Reliable Services 通信模型中可用的概念和 API 的详细信息,然后快速开始使用服务远程处理或深入了解如何使用具有 OWIN 自承载的 Web API 编写通信侦听器。Learn more about the concepts and APIs available in the Reliable Services communication model, then get started quickly with service remoting or go in-depth to learn how to write a communication listener using Web API with OWIN self-host.