Microsoft Azure 负载平衡服务

Microsoft Azure 为在其中托管的虚拟机 (IaaS) 和云服务 (PaaS) 提供负载平衡服务。负载平衡支持应用程序伸缩,并且提供应用程序故障恢复以及其他优势。

可以通过以下方式访问负载平衡服务:通过 Microsoft Azure 门户或应用程序的服务模型指定服务上的输入端点。当在 Microsoft Azure 上部署一个具有一个或多个输入端点的托管服务后,它会自动配置 Microsoft Azure 平台提供的负载平衡服务。要充分利用服务的弹性/冗余性优势,您需要让至少两个虚拟机服务于同一端点。

下图是一个托管在 Microsoft Azure 中的应用程序示例,该应用程序使用负载平衡服务将传入流量(地址/端口 1.2.3.4:80)引导到三个虚拟机,这些虚拟机均侦听端口 80。

下面介绍了 Microsoft Azure 负载平衡服务的主要功能:

 PaaS/IaaS 支持

Microsoft Azure 负载平衡服务适用于所有租户类型(IaaS 或 PaaS)和所有操作系统类型(支持 Windows 或任何基于 Linux 的操作系统)。

PaaS 租户通过服务模型进行配置。IaaS 租户通过管理门户或 PowerShell 进行配置。

Layer-4负载平衡器,基于哈希算法分配

Microsoft Azure 负载平衡器是一种 Layer-4负载平衡器。Microsoft Azure 负载平衡器通过针对给定输入端点上接收到的流量计算哈希函数,在一组可用的服务器(虚拟机)之间分配负载。计算哈希函数是为了使来自同一连接(TCP 或 UDP)的所有数据包最终位于同一台服务器上。Microsoft Azure 负载平衡器采用 5个信息(源 IP、源端口、目标 IP、目标端口、协议类型)计算用于将流量映射到可用服务器的哈希函数。我们选择的哈希函数使到服务器的连接的分布非常随机。但是,根据流量模式,不同的连接可能映射到同一台服务器。(请注意,到服务器的连接的分布不是轮询的,也不像其他文章或博客中误称的那样具有请求队列)。哈希函数的基本前提是获得了大量来自不同客户端的请求,这样请求就可以跨服务器完美分配。

多协议支持

Microsoft Azure 中的负载平衡服务支持 TCP 和 UDP 协议。客户可以在其服务模型的输入端点规范中通过 PowerShell 或管理门户指定协议。

多端点支持

托管服务可以指定多个输入端点,这些端点将自动在负载平衡服务上完成配置。

目前,不支持具有相同端口和协议的多个端点。托管服务可以拥有的最大端口数也存在限制,目前设置为 150。

内部端点支持

每个服务最多可以指定 25 个内部端口,这些端口未暴露给负载平衡器,且用于服务角色之间的通信。

直接端口端点支持(实例输入端点)

托管服务可以指定给定端点不应实现负载平衡, 而是直接访问托管此服务的虚拟机。这样应用程序就可以控制客户端直接重定向到给定应用程序实例 (VM) ,而不必让每个请求都实现负载平衡​​(负载平衡有可能造成重定向到不同的实例)。

自动重新配置扩展 / 缩小、服务修复和更新

负载平衡服务与 Microsoft Azure 计算服务一起协作,以确保在为输入端点指定的服务器实例数扩大或缩小(由于 web role/worker role 实例数的增加或在相同负载平衡组下放置了额外的持久 VM)时,负载平衡服务会自动重新配置以针对增加或减少的实例实现负载平衡。

负载平衡服务也会以透明的方式重新配置,以响应 Microsoft Azure Fabric Controller 执行的服务修复操作或客户执行的服务更新。

服务监控

负载平衡服务提供了一项功能,可探测各种服务器实例的运行状况并让运行不佳的服务器实例不再被轮询。支持以下三种类型的探测器:来宾代理探测器(在 PaaS VM 上)、HTTP 自定义探测器和 TCP 自定义探测器。对于来宾代理,负载平衡服务会查询 VM 中的来宾代理以了解服务的状态。对于 HTTP,负载平衡服务通过获取指定的 URL 来确定实例的运行状况。对于 TCP,则依赖于成功建立与已定义探测端口的 TCP 会话。

源 NAT (SNAT)

所有来自服务的出站流量均使用与入站流量相同的 VIP 地址进行源 NAT (SNAT) 处理。我们将在以后的文章中深入介绍 SNAT 的工作原理。

数据中心内部的流量优化

Microsoft Azure 负载平衡器会优化同一区域中 Microsoft Azure 数据中心之间的流量,使通过 VIP 通信且位于同一区域中的 Azure 租户之间的流量可在 TCP/IP 连接启动后完全绕过 Microsoft Azure 负载平衡器。

VIP 交换

Microsoft Azure 负载平衡器支持交换两个租户的 VIP,让处于“暂存”环境的租户移动到“生产”环境,反之亦然。VIP 交换操作允许客户端在部署服务的新版本时使用相同的 VIP 与服务通信。可以在 staging 环境中部署和测试服务的新版本,而不会干扰生产流量。当新版本通过所有必要的测试后,可以通过与现有的生产服务交换将其提送到生产环境。与“旧”生产环境建立的现有连接将保持不变。新连接将被定向到“新”的生产环境。

示例:负载平衡服务

接下来我们将了解如何在示例云服务中使用上文中负载平衡服务提供的大多数功能。我们要建模的 PaaS 租户如下图所示:

租户有两个前端 (FE) 角色和一个后端 (BE) 角色。FE 角色暴露了四个使用 http、tcp 和 udp 协议的负载平衡端点。其中一个端点也用于通知负载平衡器该角色的运行状况。BE 角色暴露了三个使用 http、tcp 和 udp 协议的端点。FE 和 BE 角色将一个直接端口端点暴露给相应的服务实例。

使用 Azure 服务模型表示上述服务,如下所示(一些架构细节已被删除,以使其更清晰):  

<ServiceDefinition name="ProbeTenant">

  <LoadBalancerProbes>

    <LoadBalancerProbe name="MyProbe" protocol="http" path="Probe.aspx" intervalInSeconds="5" timeoutInSeconds="100" />

  </LoadBalancerProbes>

  

  <WorkerRole name="BERole" vmsize="Small">

    <Endpoints>

      <InternalEndpoint name="BE_InternalEP_Tcp" protocol="tcp" />

      <InternalEndpoint name="BE_InternalEP_Udp" protocol="udp" />

      <InternalEndpoint name="BE_InternalEP_Http" protocol="http" port="80" />

      <InstanceInputEndpoint name="InstanceEP_BE" protocol="tcp" localPort="80">

          <AllocatePublicPortFrom>

              <FixedPortRange min="10210" max="10220"  />

          </AllocatePublicPortFrom>

      </InstanceInputEndpoint>

    </Endpoints>

  </WorkerRole>

  
 <WorkerRole name="FERole" vmsize="Small">

    <Endpoints>

        <InputEndpoint name="FE_External_Http" protocol="http" port="10000" />

        <InputEndpoint name="FE_External_Tcp"  protocol="tcp"  port="10001" />

        <InputEndpoint name="FE_External_Udp"  protocol="udp"  port="10002" />      

        <InputEndpointname="HTTP_Probe" protocol="http" port="80" loadBalancerProbe="MyProbe" />

      
        <InstanceInputEndpoint name="InstanceEP" protocol="tcp" localPort="80">

           <AllocatePublicPortFrom>

              <FixedPortRange min="10110" max="10120"  />

           </AllocatePublicPortFrom>

        </InstanceInputEndpoint>

        <InternalEndpoint name="FE_InternalEP_Tcp" protocol="tcp" />

    </Endpoints>

  </WorkerRole>

</ServiceDefinition>

分析服务模型时,我们先从定义正常运行的探头开始,负载平衡器应使用此探头来查询服务的运行状况:

  <LoadBalancerProbes>

    <LoadBalancerProbe name="MyProbe" protocol="http" path="Probe.aspx" intervalInSeconds="5" timeoutInSeconds="100" />

  </LoadBalancerProbes>

 这表示,我们有一个 http 自定义探头,它使用 URL 相对路径“Probe.aspx”。此探头稍后将附加到一个完全指定的端点。

接下来我们将 FE 角色定义为 WorkerRole。该角色具有多个使用 http、tcp 和 udp 的负载平衡端点,如下所示:

        <InputEndpoint name="FE_External_Http" protocol="http" port="10000" />

        <InputEndpoint name="FE_External_Tcp"  protocol="tcp"  port="10001" />

        <InputEndpoint name="FE_External_Udp"  protocol="udp"  port="10002" />

由于我们没有为这些端点分配自定义探头,因此上述端点的运行状况将由 VM 上的来宾代理控制,并且可以由服务使用 StatusCheck 事件进行更改。

接下来我们在端口 80 上定义一个额外的 http 端点,该端点使用我们之前定义的自定义探头 (MyProbe):

        <InputEndpoint name="HTTP_Probe" protocol="http" port="80" loadBalancerProbe="MyProbe" />

 负载平衡器结合端点信息和探测器信息以创建以下形式的 URL:https://{VM 的 DIP}:80/Probe.aspx,将其用于查询服务的运行状况。此服务将(在日志中?)发现相同的 IP 会定期访问它。这是来自运行 VM 的节点主机的运行状况探测请求。

该服务必须通过 HTTP 200 状态代码对负载平衡器做出响应,以假定该服务正常运行。任何其他 HTTP 状态代码(如 503)会直接导致负载平衡器停止向 VM 发送轮询。

探头定义还会控制探测频率。在上述情况下,负载平衡器每 15 秒探测一次端点。如果 30 秒(两次探测间隔)内没有收到肯定回应,将假设探头关闭,VM 终止轮询。同样,如果服务已终止轮询,当收到肯定回应时,服务将立即恢复轮询。如果服务在运行正常/不正常之间波动,负载平衡器可以决定推迟重新轮询服务,直到它可以让大量探头正常运行。

FE 服务暴露了一组直接端口,每个实例(实例输入端点)一个,这些端口直接连接到以下指定端口上的 FE 实例:

      <InstanceInputEndpoint name="InstanceEP_BE" protocol="tcp" localPort="80">

          <AllocatePublicPortFrom>

              <FixedPortRange min="10210" max="10220"  />

          </AllocatePublicPortFrom>

      </InstanceInputEndpoint>

 上述定义使用 tcp 端口 10110、10111…连接到每个 FE 角色 VM 实例的端口 80。可以通过多种方式使用此功能:

a)  直接访问给定实例,仅对该实例执行操作

b)  在用户应用程序通过负载平衡端点后,将其重定向到特定实例。这可以用于到给定实例的“粘性”会话。需要注意的是,这可能会导致实例过载并删除任何冗余。

最后,FE 角色暴露了一个内部端点,其可用于 FE/BE 角色之间的通信:

        <InternalEndpoint name="FE_InternalEP_Tcp" protocol="tcp" />

 每个角色可以使用 RoleEnvironment 类发现它暴露的端点,以及其他每个角色暴露的端点。

BE 角色也可作为 WorkerRole 进行建模。

BE 角色不会暴露任何负载平衡端点,只会暴露使用 http、tcp 和 udp 的内部端点:

      <InternalEndpoint name="BE_InternalEP_Tcp" protocol="tcp" />

      <InternalEndpoint name="BE_InternalEP_Udp" protocol="udp" />

      <InternalEndpoint name="BE_InternalEP_Http" protocol="http" port="80" />

 BE 角色还会暴露直接连接到 BE 实例的实例输入端点:

      <InstanceInputEndpoint name="InstanceEP_BE" protocol="tcp" localPort="80">

          <AllocatePublicPortFrom>

              <FixedPortRange min="10210" max="10220"  />

          </AllocatePublicPortFrom>

      </InstanceInputEndpoint>

 上述定义使用 tcp 端口 10210…连接到每个 BE 角色 VM 实例的端口 80。

我们希望上述示例充分演示了如何使用所有负载平衡功能对服务进行建模。

在以后的文章中,我们将看到此租户的实际应用,并提供代码示例。此外,我们将更加详细地介绍以下内容:

a)  SNAT 的工作原理

b)  自定义探头

c)  虚拟网络

您也可以向我们发送您希望详细了解的内容。

Microsoft Azure 网络团队

Marios Zikos

 

本文翻译自:

https://blogs.msdn.com/b/windowsazure/archive/2014/04/08/microsoft-azure-load-balancing-services.aspx