网址映射概览

Google Cloud 应用负载均衡器和 Cloud Service Mesh 使用名为网址映射的 Google Cloud 配置资源将 HTTP(S) 请求路由到后端服务或后端存储桶。

例如,对于外部应用负载均衡器,您可以使用单个网址映射,根据网址映射中配置的规则将请求路由到不同的目的地:

  • 针对 https://example.com/video 的请求转到一个后端服务。
  • 针对 https://example.com/audio 的请求转到其他后端服务。
  • 针对 https://example.com/images 的请求转到 Cloud Storage 后端存储桶。
  • 针对任何其他主机和路径组合的请求转到默认后端服务。

网址映射与以下 Google Cloud 产品结合使用:

可用的网址映射资源类型有两种:全局和区域性。您使用的资源类型取决于产品的负载均衡方案。

产品 负载均衡方案 网址映射资源类型 支持的目标
全球外部应用负载均衡器 EXTERNAL_MANAGED 全球、外部 后端服务、后端存储桶
传统版应用负载均衡器 EXTERNAL 全球、外部 后端服务、后端存储桶
区域级外部应用负载均衡器 EXTERNAL_MANAGED 区域、外部 后端服务
跨区域内部应用负载均衡器 INTERNAL_MANAGED 全球、内部 后端服务
区域级内部应用负载均衡器 INTERNAL_MANAGED 区域、内部 后端服务
Cloud Service Mesh INTERNAL_SELF_MANAGED 全球、内部 后端服务

并非所有网址映射都能用于所有产品。与全球外部应用负载均衡器、区域级外部应用负载均衡器、内部应用负载均衡器和 Cloud Service Mesh 搭配使用的网址映射还支持多种高级流量管理功能。如需详细了解这些差异,请参阅负载均衡器功能比较:路由和流量管理。 此外,区域级网址映射也可以是在 App Hub预览版)中指定为服务的资源。

网址映射的工作原理

当请求到达负载均衡器时,负载均衡器会根据网址映射中定义的规则将请求路由到特定的后端服务或后端存储桶。

后端服务表示后端的集合,而后端是应用或微服务的实例。 后端存储桶是一种 Cloud Storage 存储桶,通常用于托管静态内容,例如映像。

对于区域级外部应用负载均衡器、内部应用负载均衡器和 Cloud Service Mesh,可能的目标如下:

此外,全局外部应用负载均衡器还支持:

例如,假设您采用以下设置:

  • 一个 IP 地址:
    • 向您的组织发出的所有请求都会转到相同 IP 地址和相同负载均衡器。
    • 根据请求网址,流量会被定向至不同的后端服务。
  • 两个网域:
    • example.net 用于托管培训视频。
    • example.org 用于托管您组织的网站。
  • 四组服务器:
    • 一组服务器用于托管您组织的网站(后端服务:org-site)。
    • 一组服务器用于托管整个培训视频网站(后端服务:video-site)。
    • 一组服务器用于托管高清 (HD) 培训视频(后端服务:video-hd)。
    • 一组服务器用于托管标清 (SD) 培训视频(后端服务:video-sd)。

您希望按如下方式路由请求:

  • 将向 example.org(或 example.net 以外的任何网域)发出的请求转到 org-site 后端服务。
  • example.net 发出且与更具体的匹配路径不匹配的请求转到 video-site 后端服务。
  • 将向 example.net/video/hd/* 发出的请求转到 video-hd 后端服务。
  • 将向 example.net/video/sd/* 发出的请求转到 video-sd 后端服务。

/video/*--path-rule/video/test1/video/test2 等 URI 匹配。但是,此路径规则与路径 /video 不匹配。

如果负载均衡器收到网址中包含 /../ 的请求,则负载均衡器会通过移除 .. 之前的路径段来转换网址,然后以转换后的网址做出响应。例如,在针对 http://example.net/video/../abc 发送请求时,负载均衡器会以 302 重定向到 http://example.net/abc 做出响应。然后,大多数客户端会通过向负载均衡器返回的网址(在本例中为 http://example.net/abc)发出请求来响应。此 302 重定向不会记录在 Cloud Logging 中。

通过网址映射,您可以设置此类主机和基于路径的路由。

后端服务设置示例。
后端服务设置示例(点击放大)。

命名

每个网址映射都有一个名称。当您使用 Google Cloud 控制台创建基于 HTTP(S) 的负载均衡器时,系统会为网址映射分配一个名称。此名称与 Google Cloud 控制台中的负载均衡器名称相同。如果您使用 Google Cloud CLI 或 API,则可以为网址映射自定义一个名称。

网址映射组件

网址映射是一组 Google Cloud 配置资源,用于将对网址的请求定向到后端服务或后端存储桶。网址映射使用其处理的每个网址的主机名和路径部分来实现这一点:

  • 主机名是网址的域名部分;例如,网址 http://example.net/video/hd 的主机名部分为 example.net
  • 路径是网址中位于主机名和可选端口号后面的部分;例如,对于网址 http://example.net/video/hd,其路径部分为 /video/hd
带有基本网址映射的负载均衡器配置。
带有基本网址映射的负载均衡器配置(点击可放大)

此图展示了彼此相关的负载均衡配置对象的结构。

您可以使用以下网址映射配置参数来控制接收传入请求的后端服务或后端存储桶 :

  • 默认后端服务默认后端存储桶。创建网址映射时,您必须指定默认后端服务 或默认后端存储桶,但不能同时指定两者。在没有适用的主机规则的情况下,此默认后端服务或后端存储桶表示 Google Cloud 将对包含任何主机名的网址的请求定向到的后端服务 或后端存储桶 。
  • 主机规则 (hostRules)。主机规则会将发送到一个或多个关联主机名的请求定向到单个路径匹配器 (pathMatchers)。网址的主机名部分应与主机规则中配置的一组主机名完全匹配。在网址映射主机和路径规则中,如果省略主机,则该规则将匹配所请求的任何主机。如需将对 http://example.net/video/hd 的请求定向到路径匹配器,您需要一个至少包含主机名 example.net 的主机规则。该主机规则还可以处理对其他主机名的请求,但它会将这些请求定向到同一路径匹配器。

    如果您需要将请求定向到其他路径匹配器,必须使用不同的主机规则。网址映射中的两个主机规则不能包含相同主机名。

    您可以对所有主机名进行匹配,只需在主机规则中指定通配符 * 即可。例如,对于网址 http://example.orghttp://example.net/video/hdhttp://example.com/audio,在主机规则中指定 * 即可对所有三个主机名(即 example.orgexample.netexample.com)进行匹配。也可以通过指定通配符 * 来匹配部分主机名。例如,主机规则 *.example.net 与主机名 news.example.netfinance.example.net 都匹配。

    • 端口号。不同的应用负载均衡器以不同的方式处理端口号。对于内部应用负载均衡器,您可以使用主机规则参数指定端口号。例如,如需定向对端口 8080 的 example.net 请求,请将主机规则设置为 example.net:8080。 对于传统应用负载均衡器,在匹配主机规则时仅考虑网址中的主机名。例如,端口 8080 和端口 80 的 example.net 请求与主机规则 example.net 相匹配。
  • 路径匹配器 (pathMatchers)。路径匹配器是供主机规则引用的配置参数。它定义了网址的路径部分与应处理请求的后端服务 或后端存储桶 之间的关系。路径匹配器由以下两个元素组成:

    • 路径匹配器默认后端服务路径匹配器默认后端存储桶。对于每个路径匹配器,您必须至少指定默认后端服务 或默认后端存储桶,但不能同时指定两者。如果网址的主机名与路径匹配器关联的主机规则相匹配,且网址路径与路径匹配器中的任何路径规则都不匹配,则此默认后端服务或后端存储桶表示 Google Cloud 将对网址的请求定向到的后端服务 或后端存储桶 。

    • 路径规则。对于每个路径匹配器,您可以指定一个或多个路径规则,这些路径规则是将网址路径映射到单个后端服务 或后端存储桶的键值对。下一部分详细介绍了路径规则原理。

操作顺序

对于请求网址中的给定主机名和路径,Google Cloud 会按照以下过程将请求定向到网址映射中配置的相应后端服务或后端存储桶:

  • 如果网址映射不包含与该网址的主机名对应的主机规则,则 Google Cloud 会将请求定向到网址映射的默认后端服务或默认后端存储桶,具体取决于您定义的哪一个。

  • 如果网址映射包含与该网址的主机名对应的主机规则,那么系统会查询该主机规则引用的路径匹配器:

    • 如果路径匹配器包含与该网址的路径完全匹配的路径规则,则 Google Cloud 会将请求定向到该路径规则对应的后端服务 或后端存储桶 。

    • 如果路径匹配器不包含与该网址的路径完全匹配的路径规则,但包含以 /* 结尾且其前缀与该网址的路径的最长部分匹配的路径规则,则 Google Cloud 会将请求定向到该路径规则对应的后端服务 或后端存储桶 。例如,对于包含两个路径匹配器规则 /video/hd/movie1/video/hd/* 的网址映射,如果网址包含确切路径 /video/hd/movie1,则它会与该路径规则匹配。

    • 如果以上两个条件都不满足,则 Google Cloud 会将请求定向到路径匹配器的默认后端服务 或默认后端存储桶,具体取决于您定义的哪一个。

路径匹配器限制

主机名、路径匹配器和路径规则存在限制条件。

路径规则中的通配符、正则表达式和动态网址

  • 在路径规则中,只能在正斜杠字符 (/) 后面添加通配符 (*)。例如,/videos/*/videos/hd/* 是有效的路径规则,但 /videos*/videos/hd* 不是有效的路径规则。

  • 路径规则不使用正则表达式或子字符串匹配。PathTemplateMatch 可以使用简化的路径匹配运算符。例如,/videos/hd/videos/hd/* 路径规则不适用于路径为 /video/hd-abcd 的网址。不过,/video/* 路径规则适用于该路径。

  • 路径匹配器(以及一般网址映射)不会提供作用类似于 Apache LocationMatch 指令的功能。如果您的应用生成具有通用前缀的动态网址路径(例如 /videos/hd-abcd/videos/hd-pqrs),并且您需要将向这些路径发出的请求发送到不同的后端服务,您可能无法通过网址映射来实现此目的。对于仅包含几个可能的动态网址的场景,您可能可以使用一组有限的路径规则来创建路径匹配器。对于较为复杂的使用场景,您将需要在后端上执行基于路径的正则表达式匹配。

路由规则的路径模板中的通配符和模式匹配运算符

借助灵活的格式匹配运算符,您可以使用通配符语法来匹配网址路径的多个部分,包括部分网址和后缀(文件扩展名)。当您需要路由流量并根据复杂网址路径执行重写时,这些运算符非常有用。您还可以将一个或多个路径组件与命名变量相关联,然后在重写网址时引用这些变量。借助命名变量,您可以在将请求发送到来源之前对网址组件重新排序和移除。

只有以下产品支持使用通配符的模式匹配:

  • 全球外部应用负载均衡器
  • 区域级外部应用负载均衡器
  • 区域级内部应用负载均衡器
  • 跨区域内部应用负载均衡器
  • Cloud Service Mesh

以下示例为电子商务应用路由流量,该应用针对购物车信息和用户信息提供单独的服务。您可以使用灵活的模式匹配运算符和命名变量来配置 routeRules,以便将用户的唯一 ID 发送到用户账号详情页面,并在重写网址后将用户的购物车信息发送到购物车处理服务。

  pathMatchers:
    - name: cart-matcher
      routeRules:
        - description: CartService
          matchRules:
            - pathTemplateMatch: '/xyzwebservices/v2/xyz/users/{username=*}/carts/{cartid=**}'
          service: cart-backend
          priority: 1
          routeAction:
            urlRewrite:
              pathTemplateRewrite: '/{username}-{cartid}/'
    - name: user-matcher
      routeRules:
        - description: UserService
          matchRules:
            - pathTemplateMatch: '/xyzwebservices/v2/xyz/users/*/accountinfo/*'
          service: user-backend
          priority: 1

以下是客户端请求 /xyzwebservices/v2/xyz/users/abc@xyz.com/carts/FL0001090004/entries/SJFI38u3401nms?fields=FULL&client_type=WEB(包含用户信息和购物车信息)时发生的情况:

  1. 请求路径与 cart-matcher pathMatcher 中的 pathTemplateMatch 匹配。{username=*} 变量与 abc@xyz.com 匹配,{cartid=**} 变量与 FL0001090004/entries/SJFI38u3401nms 匹配。
  2. 查询参数会与路径拆分,路径会根据 pathTemplateRewrite 重写,查询参数会附加到重写的路径。我们只能使用用于在 pathTemplateRewrite 中定义 pathTemplateMatch 的相同变量。
  3. 重写后的请求会将重写后的网址路径发送到 cart-backend/abc@xyz.com-FL0001090004/entries/SJFI38u3401nms?fields=FULL&client_type=WEB

当客户端改为请求仅包含用户和账号信息的 /xyzwebservices/v2/xyz/users/abc%40xyz.com/accountinfo/abc-1234 时,会发生以下情况:

  1. 请求路径与 user-matcher pathMatcher 中的 pathTemplateMatch 匹配。第一个 *abc%40xyz.com 匹配,而第二个 *abc-1234 匹配。
  2. 请求会发送到 user-backend

下表概述了路径模板模式的语法。

运算符 会匹配出的结果
* 单个路径段,不包括周围的路径分隔符 / 字符。
** 匹配零个或零个以上的字符,包括多个路径段之间的任何路径分隔符 / 字符。如果包含其他运算符,则 ** 运算符必须是最后一个运算符。
{name}{name=*} 与一个路径段匹配的命名变量。匹配单个路径段,不包括周围路径分隔符 / 字符。
{name=news/*} 明确匹配两个路径段的命名变量:news* 通配符段。
{name=*/news/*} 与三个路径段匹配的命名变量。
{name=**} 与零个或零个以上字符匹配的命名变量。如果存在,则必须是最后一个运算符。

使用这些运算符进行灵活的模式匹配时,请牢记以下注意事项:

  • 多个模式可以组合为一个模式。
  • 查询参数会与路径拆分,路径会根据 pathTemplateRewrite 重写,查询参数会附加到重写的路径。
  • 请求未进行百分比编码。例如,采用百分号编码的斜杠字符 (%2F) 的网址不会解码为未编码的形式。
  • 每个变量名称(例如 {segment}{region})只能在同一模式中出现一次。同名的多个变量无效,因此会被拒绝。
  • 变量名称区分大小写,且必须是有效的标识符。如需检查变量名称是否有效,请确保它与正则表达式 ^[a-zA-Z][a-zA-Z0-9_]*$ 匹配。
    • {API}{api}{api_v1} 都是有效的标识符。它们识别三个不同的变量。
    • {1}{_api}{10alpha} 不是有效的标识符。
  • 每个模板模式最多只能有 5 个运算符。

如需在请求发送到来源之前执行可选的网址重写,您可以使用您定义用于捕获路径的变量。例如,您可以在定义 urlRewrite 时引用、重新排列或省略 pathTemplateRewrite 字段中的变量。

对网址重写使用变量和运算符进行灵活的模式匹配时,请牢记以下注意事项:

  • 重写网址时,如果重写网址中不需要变量,则可以省略变量。
  • 在进行任何重写之前,您可以通过检查响应标头来识别客户端在来源发送的网址。原始客户端网址填充了 x-client-request-url 标头和 x-envoy-original-path 标头。

主机名和主机规则关系

  • 主机名只能引用单条主机规则。

  • 单条主机规则可以处理多个主机名。

主机名和主机规则之间的关系。
主机名和主机规则之间的关系(点击可放大)

主机规则和路径匹配器关系

  • 多条主机规则可以引用单个路径匹配器。

  • 一条主机规则只能引用单个路径匹配器。

下图对这几点进行了说明。

主机规则和路径匹配器之间的关系。
主机规则和路径匹配器之间的关系(点击可放大)

网址和后端关系

每个唯一网址仅会定向到一个后端服务 或一个后端存储桶。 因此:

  • Google Cloud 使用网址的主机名部分来选择单个主机规则及其引用的路径匹配器。

  • 在路径匹配器中使用路径规则时,您不能为同一路径创建多条路径规则。例如,对 /videos/hd 的请求不能定向到多个后端服务 或后端存储桶。后端服务的后端实例组或后端网络端点组 (NEG) 可以分布在不同的可用区和区域,您可以创建使用 Multi-Regional Storage 类别的后端存储桶。

    如需将唯一网址的流量定向到多项服务,您可以使用路由规则,而不是路径规则。如果您为标头或参数匹配配置具有路由规则的路径匹配器,则可以根据唯一网址上的标头或查询参数的内容将该网址定向到多个后端服务 或后端存储桶。

    同样,对于区域级外部应用负载均衡器和 Cloud Service Mesh,路由操作的加权后端服务可以将同一网址定向到多个后端服务 或后端存储桶,具体取决于对加权后端服务设置的权重。

网址映射和协议

您可以使用相同的网址映射、主机规则和路径匹配器来处理客户端提交的 HTTP 和 HTTPS 请求,前提是目标 HTTP 代理和目标 HTTPS 代理都引用了该网址映射。

最简单的网址映射

最简单的网址映射仅具有默认后端服务 或默认后端存储桶。该网址映射不包含主机规则,也不包含路径匹配器。默认后端服务 或默认后端存储桶 (无论您定义的哪一个)可处理所有请求的网址。

如果您定义了默认后端服务,则 Google Cloud 会根据该后端服务的配置将请求定向到其后端实例组或后端 NEG。

除默认规则外不使用其他规则的网址映射
只有默认服务、不含任何规则的网址映射(点击放大)

具有外部应用负载均衡器的网址映射工作流示例

以下示例演示了网址映射的操作顺序。本示例仅配置现有传统应用负载均衡器的网址映射。为便于理解概念,该示例仅使用了后端服务;不过,您可以改用后端存储桶。如需了解如何创建负载均衡器的其他组件,请参阅创建传统版应用负载均衡器

如需详细了解如何使用路径匹配器和主机规则创建和配置网址映射,请参阅 gcloud compute url-maps create 文档

  1. 为负载均衡器创建网址映射,并指定默认后端服务。 本示例创建了网址映射 video-org-url-map,它引用现有后端服务 org-site

    gcloud compute url-maps create video-org-url-map \
        --default-service=org-site
    
  2. 创建名为 video-matcher 且具有以下特征的路径匹配器:

    • 默认后端服务为 video-site(现有的一项后端服务)。
    • 添加相关路径规则,将对确切网址路径 /video/hd 或网址路径前缀 /video/hd/* 的请求定向至现有后端服务 video-hd
    • 添加相关路径规则,将对确切网址路径 /video/sd 或网址路径前缀 /video/sd/* 的请求定向至现有后端服务 video-sd
    gcloud compute url-maps add-path-matcher video-org-url-map \
        --path-matcher-name=video-matcher \
        --default-service=video-site \
        --path-rules=/video/hd=video-hd,/video/hd/*=video-hd,/video/sd=video-sd,/video/sd/*=video-sd
    
  3. 为引用 video-matcher 路径匹配器的 example.net 主机名创建主机规则。

    gcloud compute url-maps add-host-rule video-org-url-map \
        --hosts=example.net \
        --path-matcher-name=video-matcher
    

video-org-url-map 网址应如下所示:

gcloud compute url-maps describe video-org-url-map
creationTimestamp: '2021-03-05T13:34:15.833-08:00'
defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/org-site
fingerprint: mfyJIT7Zurs=
hostRules:
- hosts:
  - '*'
  pathMatcher: video-matcher
- hosts:
  - example.net
  pathMatcher: video-matcher
id: '8886405179645041976'
kind: compute#urlMap
name: video-org-url-map
pathMatchers:
- defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/video-site
  name: video-matcher
  pathRules:
  - paths:
    - /video/hd
    - /video/hd/*
    service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/video-hd
  - paths:
    - /video/sd
    - /video/sd/*
    service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/video-sd
selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/urlMaps/video-org-url-map

video-org-url-map 网址映射按以下方式将请求的网址定向到后端。

包含路径规则、路径匹配器和主机规则的网址映射。
包含路径规则、路径匹配器和主机规则的网址映射(点击放大)。

下表说明了上图中显示的请求处理。

主机名 网址路径 选定后端服务 选择原因
主机名:
example.org 以及除
example.net 以外的所有其他主机名
所有路径 org-site 该主机名不包含在网址映射的任何主机规则中,因此请求会被定向到网址映射的默认后端服务。
主机名:
example.net
/video
/video/examples
video-site 由于没有针对 /video//video/* 的路径规则,因此请求会转到默认后端服务。针对 example.net 的主机规则引用了一个路径匹配器,但该路径匹配器没有适用于这些路径的任何路径规则。
主机名:
example.net
/video/hd
/video/hd/movie1
/video/hd/movies/movie2
/video/hd/* 开头的其他网址
video-hd 针对 example.net 的主机规则引用了一个路径匹配器,该路径匹配器的路径规则会将针对与 /video/hd 完全匹配或以 /video/hd/* 开头的网址路径的请求定向到 video-hd 后端服务。
主机名:
example.net
/video/sd
/video/sd/show1
/video/sd/shows/show2
/video/sd/* 开头的其他网址
video-sd 针对 example.net 的主机规则引用了一个路径匹配器,该路径匹配器的路径规则会将针对与 /video/sd 完全匹配或以 /video/sd/* 开头的网址路径的请求定向到 video-sd 后端服务。

网址重定向

网址重定向会将域名的访问者从一个网址重定向到另一个网址。

默认网址重定向不会匹配传入请求中的任何特定格式。例如,您可能需要使用默认网址重定向,将所有主机名重定向到您选择的主机名。

您可以通过多种方式创建网址重定向,如下表所述。

方法 配置
网址映射的默认网址重定向 顶级 defaultUrlRedirect
路径匹配器的默认网址重定向 pathMatchers[].defaultUrlRedirect[]
路径匹配器的路径规则的网址重定向 pathMatchers[].pathRules[].urlRedirect
路径匹配器的路由规则的网址重定向 pathMatchers[].routeRules[].urlRedirect

defaultUrlRedirecturlRedirect 内部,pathRedirect 工作方式始终如下所示:

  • 系统会将整个请求路径替换为您指定的路径。

defaultUrlRedirecturlRedirect 中,prefixRedirect 的工作方式取决于它的使用方式:

  • 如果您使用 defaultUrlRedirect,则 prefixRedirect 实际上是前缀前置,因为匹配的路径始终为 /
  • 如果您在路径匹配器的路径规则或路径规则中使用 urlRedirect,则 prefixRedirect 是前缀更换品,具体取决于路径规则或路由规则中定义的请求路径匹配方式。

重定向示例:

下表提供了一些重定向配置的示例。右侧列显示默认网址重定向的 API 配置。

您希望 使用默认网址重定向来实现
HTTP 到 HTTPS 的重定向

重定向
http://host.name/path

https://host.name/path
            kind: compute#urlMap
            name: web-map-http
            defaultUrlRedirect:
              httpsRedirect: True
           
HTTP 到 HTTPS + 主机重定向

重定向
http://any-host-name/path

https://www.example.com/path
            kind: compute#urlMap
            name: web-map-http
            defaultUrlRedirect:
              httpsRedirect: True
              hostRedirect: "www.example.com"
          
HTTP 到 HTTPS + 主机重定向 + 完整路径重定向

重定向
http://any-host-name/path

https://www.example.com/newPath
            kind: compute#urlMap
            name: web-map-http
            defaultUrlRedirect:
              httpsRedirect: True
              hostRedirect: "www.example.com"
              pathRedirect: "/newPath"
           
HTTP 到 HTTPS + 主机重定向 + 前缀重定向

重定向
http://any-host-name/originalPath

https://www.example.com/newPrefix/originalPath
            kind: compute#urlMap
            name: web-map-http
            defaultUrlRedirect:
              httpsRedirect: True
              hostRedirect: "www.example.com"
              prefixRedirect: "/newPrefix"
            

以下部分代码段为各 API 资源添加注解:

defaultUrlRedirect:
   redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
   httpsRedirect: True # True if you want https://, false if you want http://
   hostRedirect: "new-host-name.com" # Omit to keep the requested host
   pathRedirect: "/new-path" # Omit to keep the requested path; mutually exclusive to prefixRedirect
   prefixRedirect: "/newPrefix" # Omit to keep the requested path; mutually exclusive to pathRedirect
   stripQuery: False # True to omit everything in the URL after ?
   ...

后续步骤