您现在访问的是微软AZURE全球版技术文档网站,若需要访问由世纪互联运营的MICROSOFT AZURE中国区技术文档网站,请访问 https://docs.azure.cn.

Azure Service Fabric 中的反向代理Reverse proxy in Azure Service Fabric

借助 Azure Service Fabric 中内置的反向代理,Service Fabric 群集中运行的微服务可以发现包含 http 终结点的其他服务,并与之通信。Reverse proxy built into Azure Service Fabric helps microservices running in a Service Fabric cluster discover and communicate with other services that have http endpoints.

微服务通信模型Microservices communication model

Service Fabric 中的微服务在群集中的部分节点上运行,可以出于各种原因在这些节点之间迁移。Microservices in Service Fabric run on a subset of nodes in the cluster and can migrate between the nodes for various reasons. 因此,微服务的终结点可能会动态变化。As a result, the endpoints for microservices can change dynamically. 若要发现群集中的其他服务并与之通信,微服务必须完成以下步骤:To discover and communicate with other services in the cluster, microservice must go through the following steps:

  1. 通过命名服务解析服务位置。Resolve the service location through the naming service.
  2. 连接到服务。Connect to the service.
  3. 在实现服务解析以及在发生连接故障时应用的重试策略的循环中,包装上述步骤Wrap the preceding steps in a loop that implements service resolution and retry policies to apply on connection failures

有关详细信息,请参阅与服务连接和通信For more information, see Connect and communicate with services.

使用反向代理通信Communicating by using the reverse proxy

反向代理是在每个节点上运行的服务,用于代表客户端服务处理终结点解析、自动重试及其他连接故障。Reverse proxy is a service that runs on every node and handles endpoint resolution, automatic retry, and other connection failures on behalf of client services. 可以将反向代理配置为,一边处理客户端服务的请求,一边应用各种策略。Reverse proxy can be configured to apply various policies as it handles requests from client services. 借助反向代理,客户端服务可以使用任意客户端 HTTP 通信库,无需服务中有特殊的解析和重试逻辑。Using a reverse proxy allows the client service to use any client-side HTTP communication libraries and does not require special resolution and retry logic in the service.

反向代理在本地节点上公开一个或多个终结点,以供客户端服务用来向其他服务发送请求。Reverse proxy exposes one or more endpoints on local node for client services to use for sending requests to other services.

内部通信

备注

支持的平台Supported Platforms

Service Fabric 中的反向代理目前支持以下平台Reverse proxy in Service Fabric currently supports the following platforms

  • Windows 群集:Windows 8 及更高版本,或 Windows Server 2012 及更高版本Windows Cluster: Windows 8 and later or Windows Server 2012 and later
  • Linux 群集:反向代理当前不适用于 Linux 群集Linux Cluster: Reverse Proxy is not currently available for Linux clusters

从群集外部访问微服务Reaching microservices from outside the cluster

微服务的默认外部通信模型为“选择加入”模型,在该模型中,无法直接从外部客户端访问每个服务。The default external communication model for microservices is an opt-in model where each service cannot be accessed directly from external clients. Azure 负载均衡器充当微服务和外部客户端之间的网络边界,可以进行网络地址转换并将外部请求转发到内部的 IP:端口终结点。Azure Load Balancer, which is a network boundary between microservices and external clients, performs network address translation and forwards external requests to internal IP:port endpoints. 要允许外部客户端直接访问微服务的终结点,必须先将负载均衡器配置为将流量转发到群集中服务使用的每个端口。To make a microservice's endpoint directly accessible to external clients, you must first configure Load Balancer to forward traffic to each port that the service uses in the cluster. 另外,大多数微服务(尤其是有状态微服务)并不驻留在群集的所有节点上。Furthermore, most microservices, especially stateful microservices, don't live on all nodes of the cluster. 这些微服务在故障转移时可在节点之间移动。The microservices can move between nodes on failover. 在这种情况下,负载均衡器无法有效确定要将流量转发到的副本的目标节点位置。In such cases, Load Balancer cannot effectively determine the location of the target node of the replicas to which it should forward traffic.

从群集外部通过反向代理访问微服务Reaching microservices via the reverse proxy from outside the cluster

可以在负载均衡器中直接配置反向代理的端口,而无需配置单个服务的端口。Instead of configuring the port of an individual service in Load Balancer, you can configure just the port of the reverse proxy in Load Balancer. 这种配置可让群集外部的客户端使用反向代理访问群集内部的服务,无需经过额外的配置。This configuration lets clients outside the cluster reach services inside the cluster by using the reverse proxy without additional configuration.

外部通信

警告

在负载均衡器中配置反向代理的端口后,可从群集外部访问群集中公开 HTTP 终结点的所有微服务。When you configure the reverse proxy's port in Load Balancer, all microservices in the cluster that expose an HTTP endpoint are addressable from outside the cluster. 这意味着微服务设计为内部的可能会被确定的恶意用户发现。This means that microservices meant to be internal may be discoverable by a determined malicious user. 这潜在地提供可被利用的严重漏洞;例如:This potentially presents serious vulnerabilities that can be exploited; for example:

  • 恶意用户可以通过反复调用没有足够强化的攻击面的内部服务来发起拒绝服务攻击。A malicious user may launch a denial of service attack by repeatedly calling an internal service that does not have a sufficiently hardened attack surface.
  • 恶意用户可能会将格式错误的数据包传送到内部服务,从而导致意外行为。A malicious user may deliver malformed packets to an internal service resulting in unintended behavior.
  • 设计为内部的服务可能会返回不应公开给群集外部的服务的私有或敏感信息,从而将此敏感信息泄露给恶意用户。A service meant to be internal may return private or sensitive information not intended to be exposed to services outside the cluster, thus exposing this sensitive information to a malicious user.

在公开反向代理端口之前,请确保完全了解并减轻对群集及其上运行的应用程序的潜在安全影响。Make sure you fully understand and mitigate the potential security ramifications for your cluster and the apps running on it, before you make the reverse proxy port public.

使用反向代理访问服务时所用的 URI 格式URI format for addressing services by using the reverse proxy

反向代理使用特定的统一资源标识符 (URI) 格式来识别传入请求应该转发到的服务分区:The reverse proxy uses a specific uniform resource identifier (URI) format to identify the service partition to which the incoming request should be forwarded:

http(s)://<Cluster FQDN | internal IP>:Port/<ServiceInstanceName>/<Suffix path>?PartitionKey=<key>&PartitionKind=<partitionkind>&ListenerName=<listenerName>&TargetReplicaSelector=<targetReplicaSelector>&Timeout=<timeout_in_seconds>
  • http(s): 可以将反向代理配置为接受 HTTP 或 HTTPS 流量。http(s): The reverse proxy can be configured to accept HTTP or HTTPS traffic. 对于 HTTPS 转发,在设置反向代理侦听 HTTPS 后,请参阅使用反向代理连接到安全服务For HTTPS forwarding, refer to Connect to a secure service with the reverse proxy once you have reverse proxy setup to listen on HTTPS.

  • 群集的完全限定域名 (FQDN) | 内部 IP: 对于外部客户端,可以配置反向代理,以便可以通过群集域(例如 mycluster.eastus.cloudapp.azure.com)访问反向代理。Cluster fully qualified domain name (FQDN) | internal IP: For external clients, you can configure the reverse proxy so that it is reachable through the cluster domain, such as mycluster.eastus.cloudapp.azure.com. 默认情况下,反向代理在每个节点上运行。By default, the reverse proxy runs on every node. 对于内部流量,可在本地主机或任意内部节点 IP(例如 10.0.0.1)上访问反向代理。For internal traffic, the reverse proxy can be reached on localhost or on any internal node IP, such as 10.0.0.1.

  • Port: 这是为反向代理指定的端口,例如 19081。Port: This is the port, such as 19081, that has been specified for the reverse proxy.

  • ServiceInstanceName: 在不使用“fabric:/”方案的情况下尝试访问的已部署服务实例的完全限定名称。ServiceInstanceName: This is the fully-qualified name of the deployed service instance that you are trying to reach without the "fabric:/" scheme. 例如,若要访问 fabric:/myapp/myservice/ 服务,可以使用 myapp/myserviceFor example, to reach the fabric:/myapp/myservice/ service, you would use myapp/myservice.

    服务实例名称要区分大小写。The service instance name is case-sensitive. 若 URL 中的服务实例名称大小写不同,则会导致请求失败,并显示 404(未找到)。Using a different casing for the service instance name in the URL causes the requests to fail with 404 (Not Found).

  • Suffix path: 要连接到的服务的实际 URL 路径,例如 myapi/values/add/3Suffix path: This is the actual URL path, such as myapi/values/add/3, for the service that you want to connect to.

  • PartitionKey: 对于分区服务,这是针对要访问的分区计算出的分区键。PartitionKey: For a partitioned service, this is the computed partition key of the partition that you want to reach. 请注意,这是分区 ID GUID。Note that this is not the partition ID GUID. 对于使用单独分区方案的服务,此参数不是必需的。This parameter is not required for services that use the singleton partition scheme.

  • PartitionKind: 这是服务分区方案。PartitionKind: This is the service partition scheme. 该方案可以是“Int64Range”或“Named”。This can be 'Int64Range' or 'Named'. 对于使用单独分区方案的服务,此参数不是必需的。This parameter is not required for services that use the singleton partition scheme.

  • ListenerName 服务中的终结点采用以下形式:{"Endpoints":{"Listener1":"Endpoint1","Listener2":"Endpoint2" ...}}。ListenerName The endpoints from the service are of the form {"Endpoints":{"Listener1":"Endpoint1","Listener2":"Endpoint2" ...}}. 当服务公开了多个终结点时,此参数标识应将客户端请求转发到的终结点。When the service exposes multiple endpoints, this identifies the endpoint that the client request should be forwarded to. 如果服务只有一个侦听器,则可以省略此项。This can be omitted if the service has only one listener.

  • TargetReplicaSelector 这指定应当如何选择目标副本或实例。TargetReplicaSelector This specifies how the target replica or instance should be selected.

    • 当目标服务为有状态服务时,TargetReplicaSelector 可以是下列其中一项:“PrimaryReplica”、“RandomSecondaryReplica”或“RandomReplica”。When the target service is stateful, the TargetReplicaSelector can be one of the following: 'PrimaryReplica', 'RandomSecondaryReplica', or 'RandomReplica'. 如果未指定此参数,默认值为“PrimaryReplica”。When this parameter is not specified, the default is 'PrimaryReplica'.
    • 当目标服务为无状态服务时,反向代理将选择服务分区的一个随机实例来将实例转发到其中。When the target service is stateless, reverse proxy picks a random instance of the service partition to forward the request to.
  • Timeout: 此参数指定反向代理针对服务创建的 HTTP 请求(代表客户端请求)的超时。Timeout: This specifies the timeout for the HTTP request created by the reverse proxy to the service on behalf of the client request. 默认值为 60 秒。The default value is 60 seconds. 这是一个可选参数。This is an optional parameter.

用法示例Example usage

fabric:/MyApp/MyService 服务为例,该服务可针对以下 URL 打开一个 HTTP 侦听器:As an example, let's take the fabric:/MyApp/MyService service that opens an HTTP listener on the following URL:

http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/

下面是该服务的资源:Following are the resources for the service:

  • /index.html
  • /api/users/<userId>

如果服务使用单独分区方案,则 PartitionKeyPartitionKind 查询字符串参数不是必需的,可以使用网关访问服务,如下所示:If the service uses the singleton partitioning scheme, the PartitionKey and PartitionKind query string parameters are not required, and the service can be reached by using the gateway as:

  • 外部访问方式:http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyServiceExternally: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService
  • 内部访问方式:http://localhost:19081/MyApp/MyServiceInternally: http://localhost:19081/MyApp/MyService

如果服务使用“统一 Int64”分区方案,则必须使用 PartitionKeyPartitionKind 查询字符串来访问服务的分区:If the service uses the Uniform Int64 partitioning scheme, the PartitionKey and PartitionKind query string parameters must be used to reach a partition of the service:

  • 外部访问方式:http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64RangeExternally: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range
  • 内部访问方式:http://localhost:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64RangeInternally: http://localhost:19081/MyApp/MyService?PartitionKey=3&PartitionKind=Int64Range

要访问服务公开的资源,可直接在 URL 中将资源路径置于服务名称之后:To reach the resources that the service exposes, simply place the resource path after the service name in the URL:

  • 外部访问方式:http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService/index.html?PartitionKey=3&PartitionKind=Int64RangeExternally: http://mycluster.eastus.cloudapp.azure.com:19081/MyApp/MyService/index.html?PartitionKey=3&PartitionKind=Int64Range
  • 内部访问方式:http://localhost:19081/MyApp/MyService/api/users/6?PartitionKey=3&PartitionKind=Int64RangeInternally: http://localhost:19081/MyApp/MyService/api/users/6?PartitionKey=3&PartitionKind=Int64Range

然后,网关会将这些请求转发到服务的 URL:The gateway will then forward these requests to the service's URL:

  • http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/index.html
  • http://10.0.0.5:10592/3f0d39ad-924b-4233-b4a7-02617c6308a6-130834621071472715/api/users/6

针对端口共享服务进行特殊处理Special handling for port-sharing services

无法访问某个服务时,Service Fabric 反向代理会尝试重新解析服务地址以及重试请求。The Service Fabric reverse proxy attempts to resolve a service address again and retry the request when a service cannot be reached. 无法访问某个服务时,通常表示服务实例或副本已在其常规生命周期中转移到其他节点。Generally, when a service cannot be reached, the service instance or replica has moved to a different node as part of its normal lifecycle. 发生这种情况时,反向代理可能会收到网络连接错误,指出在原来解析过的地址上的某个终结点不再处于开放状态。When this happens, the reverse proxy might receive a network connection error indicating that an endpoint is no longer open on the originally resolved address.

不过,副本或服务实例可能会共享主机进程,在通过基于 http.sys 的 Web 服务器进行托管的情况下还可能会共享端口,这些 Web 服务器包括:However, replicas or service instances can share a host process and might also share a port when hosted by an http.sys-based web server, including:

在这样的情形下,可能会出现 Web 服务器出现在主机进程中并且能够响应请求,而被解析的服务实例或副本却再也不能在主机上使用的情况。In this situation, it is likely that the web server is available in the host process and responding to requests, but the resolved service instance or replica is no longer available on the host. 这种情况下,网关会从 Web 服务器收到 HTTP 404 响应。In this case, the gateway will receive an HTTP 404 response from the web server. 因此,HTTP 404 响应可能有两种不同的含义:Thus, an HTTP 404 response can have two distinct meanings:

  • 案例 #1:服务地址正确,但用户请求的资源不存在。Case #1: The service address is correct, but the resource that the user requested does not exist.
  • 案例 #2:服务地址不正确,且用户请求的资源可能在其他节点上。Case #2: The service address is incorrect, and the resource that the user requested might exist on a different node.

第一种情况是正常的 HTTP 404,属于用户错误。The first case is a normal HTTP 404, which is considered a user error. 在第二种情况中,用户请求的资源确实存在。However, in the second case, the user has requested a resource that does exist. 反向代理找不到该资源,因为服务本身已移动。The reverse proxy was unable to locate it because the service itself has moved. 反向代理需要重新解析地址,并重试请求。The reverse proxy needs to resolve the address again and retry the request.

因此,反向代理需要通过某种方式来区分这两种情况。The reverse proxy thus needs a way to distinguish between these two cases. 为了进行这种区分,需要从服务器获得提示。To make that distinction, a hint from the server is required.

  • 默认情况下,反向代理假设第二种情况属于事实,因此会尝试重新解析和重新发出请求。By default, the reverse proxy assumes case #2 and attempts to resolve and issue the request again.

  • 若要向反向代理指示第一种情况属于事实,服务应返回以下 HTTP 响应标头:To indicate case #1 to the reverse proxy, the service should return the following HTTP response header:

    X-ServiceFabric : ResourceNotFound

此 HTTP 响应标头指示的是正常的 HTTP 404 情形,即所请求的资源不存在,因此反向代理不会尝试重新解析服务地址。This HTTP response header indicates a normal HTTP 404 situation in which the requested resource does not exist, and the reverse proxy will not attempt to resolve the service address again.

针对容器中运行的服务的特殊处理Special handling for services running in containers

对于容器中运行的服务,可以使用环境变量 Fabric_NodeIPOrFQDN 构造反向代理 URL,如下面的代码中所示:For services running inside containers, you can use the environment variable, Fabric_NodeIPOrFQDN to construct the reverse proxy URL as in the following code:

    var fqdn = Environment.GetEnvironmentVariable("Fabric_NodeIPOrFQDN");
    var serviceUrl = $"http://{fqdn}:19081/DockerSFApp/UserApiContainer";

对于本地群集,Fabric_NodeIPOrFQDN 默认设置为“localhost”。For the local cluster, Fabric_NodeIPOrFQDN is set to "localhost" by default. 使用 -UseMachineName 参数启动本地群集,确保容器可访问节点上运行的反向代理。Start the local cluster with the -UseMachineName parameter to make sure containers can reach reverse proxy running on the node. 有关详细信息,请参阅配置开发人员环境以调试容器For more information, see Configure your developer environment to debug containers.

在 Docker Compose 容器中运行的 Service Fabric 服务需要特殊的 docker-compose.yml 端口部分 http: 或 https: 配置 。Service Fabric services that run within Docker Compose containers require a special docker-compose.yml Ports section http: or https: configuration. 有关详细信息,请参阅 Azure Service Fabric 中的 Docker Compose 部署支持For more information, see Docker Compose deployment support in Azure Service Fabric.

后续步骤Next steps