- `gcloud command`

```bash
gcloud compute url-maps add-path-matcher [URL_MAP_NAME] \
    --path-matcher-name=[PATH_MATCHER_NAME] \
    --default-service=[DEFAULT_SERVICE_NAME] \
    --path-rules="[PATH_RULE_1],[PATH_RULE_2],..." \
    --global
```


# Quota

# GCP URL Map Path Rules 限制条件与配额详解

## 问题分析

关于 `--path-rules` 参数的限制条件、配额和表达式规范。

---

## 解决方案

### 1. Path Rules 核心限制
- https://docs.cloud.google.com/load-balancing/docs/quotas#url_maps

#### 1.1 数量配额限制

|资源类型|配额限制|说明|
|---|---|---|
|**Path Matchers per URL Map**|100|每个 URL Map 最多 100 个 Path Matcher|
|**Path Rules per Path Matcher**|200|每个 Path Matcher 最多 200 条 Path Rule|
|**Route Rules per URL Map**|1000|总路由规则数(包括所有 Path Rules + Route Rules)|
|**URL Maps per Project**|200|每个项目最多 200 个 URL Map|

**查看当前项目配额:**

```bash
# 查看 URL Map 相关配额
gcloud compute project-info describe \
    --project=$PROJECT_ID \
    --format="table(quotas.metric,quotas.limit,quotas.usage)" \
    | grep -i "url"

# 或使用 API 查询
gcloud compute regions describe $REGION \
    --format="get(quotas)" \
    | grep -i "url_map"
```

---

#### 1.2 Path Pattern 表达式限制

**支持的路径匹配模式:**

|模式类型|语法|示例|说明|
|---|---|---|---|
|**精确匹配**|`/path`|`/api/v1/users`|仅匹配完全相同的路径|
|**前缀匹配**|`/path/*`|`/api-v1/*`|匹配以该前缀开头的所有路径|
|**后缀匹配**|`*.extension`|`*.jpg`|匹配特定文件扩展名(不常用)|
|**通配符**|`/path/*/subpath`|`/api/*/v1`|单级路径通配|

**重要限制:**

```bash
# ✅ 正确的 Path Pattern
/api-v1/*                    # 前缀匹配
/api/v1/users                # 精确匹配
/api/*/v1/users              # 单级通配
/static/*.js                 # 后缀匹配

# ❌ 不支持的 Path Pattern
/api/**/users                # 不支持多级通配符 **
/api/{version}/users         # 不支持变量占位符
/api-v[1-2]/*                # 不支持正则表达式
/api/(v1|v2)/*               # 不支持正则分组
```

---

#### 1.3 Path Rules 字符串长度限制

```bash
# 单条 --path-rules 参数最大长度限制
MAX_PATH_RULES_STRING_LENGTH=2048  # 字符

# 示例: 超长 path-rules 会报错
gcloud compute url-maps add-path-matcher url-map \
  --path-matcher-name=test \
  --default-service=default \
  --path-rules="/api-xxxxxxxxx-very-long-path-name-1/*=backend-1,/api-xxxxxxxxx-very-long-path-name-2/*=backend-2,..." \
  --global
# Error: argument --path-rules: value too long
```

**解决方案: 分批添加或使用 YAML 配置**

---

### 2. Path Rules 优先级与匹配顺序

#### 2.1 匹配优先级规则

```mermaid
graph TD
    A[收到请求] --> B{精确匹配?}
    B -->|Yes| C[使用精确匹配的 Backend]
    B -->|No| D{最长前缀匹配?}
    D -->|Yes| E[使用最长前缀的 Backend]
    D -->|No| F{通配符匹配?}
    F -->|Yes| G[使用通配符匹配的 Backend]
    F -->|No| H[使用 defaultService]
```

**优先级从高到低:**

1. **精确路径匹配** (`/api/v1/users`)
2. **最长前缀匹配** (`/api/v1/*` > `/api/*`)
3. **通配符匹配** (`/api/*/users`)
4. **默认服务** (`defaultService`)

**示例说明:**

```yaml
pathRules:
  # 规则1: 精确匹配 - 最高优先级
  - paths:
    - /api/v1/payment/checkout
    service: payment-checkout-backend
  
  # 规则2: 长前缀匹配 - 次优先
  - paths:
    - /api/v1/payment/*
    service: payment-backend
  
  # 规则3: 短前缀匹配 - 再次优先
  - paths:
    - /api/v1/*
    service: api-v1-backend
  
  # 规则4: 通配符匹配
  - paths:
    - /api/*/public
    service: public-backend

# 请求匹配结果:
# /api/v1/payment/checkout      → payment-checkout-backend (规则1 精确匹配)
# /api/v1/payment/refund        → payment-backend (规则2 前缀匹配)
# /api/v1/user/profile          → api-v1-backend (规则3 前缀匹配)
# /api/v2/public                → public-backend (规则4 通配符匹配)
# /api/v2/admin                 → defaultService (无匹配)
```

---

### 3. 命令行参数限制

#### 3.1 单次 `--path-rules` 参数限制

```bash
# ⚠️ 限制: 单次命令最多添加约 20-30 条规则(取决于路径长度)
# 原因: shell 命令行参数长度限制(通常 2048-4096 字符)

# ❌ 错误示例: 尝试一次性添加 50 条规则
gcloud compute url-maps add-path-matcher url-map \
  --path-matcher-name=api-splitter \
  --default-service=default-backend \
  --path-rules="/api-1/*=bs-1,/api-2/*=bs-2,...,/api-50/*=bs-50" \
  --global
# Error: Argument list too long
```

**解决方案:**

**方法 1: 使用 YAML 配置文件(推荐)**

```yaml
# url-map-config.yaml
kind: compute#urlMap
name: your-url-map
defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/default-backend

hostRules:
- hosts:
  - www.example.com
  pathMatcher: api-splitter

pathMatchers:
- name: api-splitter
  defaultService: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/default-backend
  
  pathRules:
  - paths: ["/api-a-v1/*", "/api-a-v2/*"]
    service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/bs-api-a
  
  - paths: ["/api-b-v1/*", "/api-b-v2/*"]
    service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/bs-api-b
  
  - paths: ["/api-c-v1/*"]
    service: https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/backendServices/bs-api-c
  
  # ... 可添加最多 200 条规则
```

```bash
# 应用配置
gcloud compute url-maps import your-url-map \
    --source=url-map-config.yaml \
    --global \
    --project=$PROJECT_ID
```

**方法 2: 分批添加路径规则**

```bash
#!/bin/bash

URL_MAP="your-url-map"
PATH_MATCHER="api-splitter"

# 第一批规则
gcloud compute url-maps add-path-matcher $URL_MAP \
  --path-matcher-name=$PATH_MATCHER \
  --default-service=default-backend \
  --path-rules="/api-a-v1/*=bs-api-a,/api-b-v1/*=bs-api-b,/api-c-v1/*=bs-api-c" \
  --global

# 后续规则需要先导出,修改,再导入
gcloud compute url-maps export $URL_MAP --destination=temp.yaml --global

# 编辑 temp.yaml 添加新规则

gcloud compute url-maps import $URL_MAP --source=temp.yaml --global
```

---

#### 3.2 Backend Service 名称限制

```bash
# Backend Service 命名规范
MIN_LENGTH=1
MAX_LENGTH=63

# 允许字符: 小写字母、数字、连字符(-)
# 必须以字母开头,以字母或数字结尾

# ✅ 合法命名
payment-api-v1-backend
api-gateway-prod-001
user-service-backend

# ❌ 非法命名
Payment-API           # 不能包含大写字母
-api-backend          # 不能以连字符开头
api_backend           # 不能包含下划线
api-backend-          # 不能以连字符结尾
a-very-long-backend-service-name-that-exceeds-sixty-three-characters  # 超过 63 字符
```

---

### 4. 特殊场景限制

#### 4.1 路径中包含特殊字符

```bash
# ⚠️ 特殊字符需要 URL 编码

# 原始路径: /api/search?q=test&limit=10
# Path Rule 中应写为: /api/search  (不包含查询参数)

# 原始路径: /api/user%20profile
# Path Rule 中应写为: /api/user%20profile (保持编码)

# 示例
gcloud compute url-maps add-path-matcher url-map \
  --path-matcher-name=special-chars \
  --default-service=default \
  --path-rules="/api/user%20profile/*=user-backend" \
  --global
```

**注意事项:**

- URL Map 只匹配路径部分,不包括查询参数(`?key=value`)
- 不包括 Fragment(`#section`)
- 特殊字符需保持 URL 编码格式

---

#### 4.2 大小写敏感性

```bash
# ⚠️ Path Rules 是大小写敏感的

# 规则定义
--path-rules="/API/v1/*=backend-1"

# 匹配结果
/API/v1/users     → ✅ 匹配 backend-1
/api/v1/users     → ❌ 不匹配,使用 defaultService
/Api/v1/users     → ❌ 不匹配,使用 defaultService
```

**最佳实践: 统一使用小写路径**

```bash
# 推荐配置
--path-rules="/api/v1/*=backend-1,/api/v2/*=backend-2"

# 在 Nginx/应用层面进行大小写归一化处理
location ~ ^/API/ {
    return 301 $scheme://$host${uri,,}$is_args$args;  # 转换为小写
}
```

---

### 5. 性能与最佳实践

#### 5.1 路径规则数量对性能的影响

```bash
# 性能基准测试(Google 官方数据)

规则数量          延迟增加
--------        --------
1-10 条         < 0.1ms
11-50 条        < 0.5ms
51-100 条       < 1ms
101-200 条      < 2ms

# 建议: 合理规划路径层级,避免过多规则
```

**优化建议:**

```bash
# ❌ 不推荐: 为每个版本创建独立规则(200 条规则)
/api/v1/user/*=user-v1-backend
/api/v1/payment/*=payment-v1-backend
/api/v1/order/*=order-v1-backend
...
/api/v10/order/*=order-v10-backend

# ✅ 推荐: 按主要功能分组(20 条规则)
/api-user/*=user-api-backend        # 在 Nginx 层面处理版本路由
/api-payment/*=payment-api-backend
/api-order/*=order-api-backend
```

---

#### 5.2 配置验证与测试

```bash
# 验证 URL Map 配置正确性
gcloud compute url-maps validate $URL_MAP \
    --global \
    --project=$PROJECT_ID

# 测试特定路径的路由结果(GCP Console API)
# 使用 REST API 测试
curl -X POST \
  "https://compute.googleapis.com/compute/v1/projects/$PROJECT_ID/global/urlMaps/$URL_MAP/validate" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "resource": {
      "name": "'$URL_MAP'",
      "tests": [
        {
          "host": "www.example.com",
          "path": "/api-a-v1/test",
          "expectedBackendService": "bs-api-a-v1"
        }
      ]
    }
  }'
```

---

### 6. 配额与限制深度解析 (Quotas & Limits)

随着业务规模增长，默认的 URL Map 配额可能成为瓶颈。以下是基于 GCP 官方文档的最新整理及其对环境的影响分析。

#### 6.1 配额参考表

| 配额类型 | 默认值 (Classic) | 可申请最大值 (参考) | 官方参考链接 |
| :--- | :--- | :--- | :--- |
| **URL Maps per project** | 200 | 1,000+ | [Quotas Doc](https://cloud.google.com/load-balancing/docs/quotas#url_maps) |
| **Path matchers per URL map** | 100 | 500 | [Limits Doc](https://cloud.google.com/load-balancing/docs/quotas#url_maps) |
| **Path rules per path matcher** | 200 | 1,000 | [Limits Doc](https://cloud.google.com/load-balancing/docs/quotas#url_maps) |

> [!NOTE]
> 对于新型 **Global External Application Load Balancer (Envoy-based)**，部分限制（如 Match Conditions）可能更严格（默认 100），请务必在控制端确认。

#### 6.2 大规模配置的环境影响 (Environmental Impact)

当您的 URL Map 规模达到数百甚至上千条规则时，需关注以下影响：

1.  **数据面延迟 (Data Plane Latency)**: **忽略不计**。
    - GCP 使用高效的查找算法（如压缩 Tries），查找 10 条还是 1000 条规则的耗时差异通常在微秒（µs）级别。
2.  **控制面同步 (Control Plane Propagation)**: **显著增大**。
    - YAML 文件越大，GCP 控制台验证、下发和全球 GFE 同步的时间就越长。超大配置同步可能需要 **3-5 分钟** 才能在全球生效。
3.  **配置容量限制 (Config Size Limit)**: 
    - 除了条数限制，还有总字节数限制（通常为 **256 KB** 左右）。如果 Path 非常长或 Host 极多，可能会触及容量上限。
4.  **管理风险 (Management Complexity)**:
    - **逻辑遮蔽 (Shadowing)**：规则越多，越容易出现前面的通用规则意外“截流”了后面具体的规则。
    - **人工误操作**：建议必须切换到 [how-to-manage-url-map.md](./how-to-manage-url-map.md) 描述的 GitOps 模式。

#### 6.3 检查与操作命令

```bash
# 查看当前项目 URL Map 使用情况
gcloud compute project-info describe \
    --project=$PROJECT_ID \
    --format="table(quotas.metric.filter(metric:URL_MAPS),quotas.limit,quotas.usage)"

# 变更建议
# 1. 优先使用通配符 (/assets/*) 减少规则条数。
# 2. 如果规则超过 500 条，考虑拆分为多个 Load Balancer（通过域名区分）。
```

---

## 完整示例: 管理大量 API 路由

### 场景: 50 个微服务,每个服务 3 个版本

```bash
# 创建配置生成脚本
cat > generate-url-map.sh << 'EOF'
#!/bin/bash

PROJECT_ID="your-project-id"
OUTPUT_FILE="url-map-large-scale.yaml"

cat > $OUTPUT_FILE << YAML
kind: compute#urlMap
name: microservices-url-map
defaultService: https://www.googleapis.com/compute/v1/projects/$PROJECT_ID/global/backendServices/default-backend

hostRules:
- hosts:
  - api.example.com
  pathMatcher: microservices-matcher

pathMatchers:
- name: microservices-matcher
  defaultService: https://www.googleapis.com/compute/v1/projects/$PROJECT_ID/global/backendServices/default-backend
  pathRules:
YAML

# 生成 50 个服务的路由规则
for service_num in {1..50}; do
  service_name="service-$(printf "%02d" $service_num)"
  
  cat >> $OUTPUT_FILE << YAML
  - paths:
    - /${service_name}-v1/*
    - /${service_name}-v2/*
    - /${service_name}-v3/*
    service: https://www.googleapis.com/compute/v1/projects/$PROJECT_ID/global/backendServices/bs-${service_name}
YAML
done

echo "Generated $OUTPUT_FILE with 50 services × 3 versions = 150 path rules"
EOF

chmod +x generate-url-map.sh
./generate-url-map.sh

# 应用配置
gcloud compute url-maps import microservices-url-map \
    --source=url-map-large-scale.yaml \
    --global \
    --project=$PROJECT_ID
```

---

## 注意事项

### ⚠️ 关键限制总结

1. **Path Rules 数量**: 每个 Path Matcher 最多 200 条
2. **命令行长度**: 单次 `--path-rules` 参数建议不超过 20-30 条
3. **路径表达式**: 不支持正则,仅支持 `*` 通配符
4. **大小写敏感**: 路径匹配区分大小写
5. **优先级**: 精确匹配 > 最长前缀 > 通配符 > 默认服务

### 🎯 最佳实践

1. **使用 YAML 配置**: 管理 10+ 条规则时优先使用 YAML
2. **路径规范化**: 统一使用小写路径,在应用层处理大小写
3. **分层设计**: GLB 处理主路由,Nginx/Kong 处理细粒度路由
4. **监控配额**: 定期检查配额使用情况
5. **版本管理**: 使用 Git 管理 URL Map YAML 配置

---

## 总结

GCP URL Map Path Rules 的核心限制:

```bash
# 数量配额
Path Matcher: 最多 100 个/URL Map
Path Rules: 最多 200 条/Path Matcher
总路由规则: 最多 1000 条/URL Map

# 表达式限制
✅ 支持: /path/*, /exact/path, /path/*/subpath
❌ 不支持: 正则表达式、多级通配符(**)、变量占位符

# 命令行限制
单次 --path-rules 参数: 建议 ≤ 30 条规则
推荐大规模配置使用 YAML import 方式
```

如需管理大量路由规则,建议采用 **YAML 配置文件 + Git 版本控制 + 自动化部署** 的方式。

好问题，这个点**非常容易踩坑**，而且官方文档写得并不直观。

我给你一个**工程师视角、可操作的完整答案**，把 --path-rules 的**能力边界、限制、quota、以及你现在这个写法是否安全**一次讲清楚。

---

````
# gcloud url-maps --path-rules 的能力与限制详解

## 1. --path-rules 本质是什么？

```text
--path-rules = Path Rule 列表
Path Rule = (Path Pattern) → (Backend Service)
````

👉 它是 **URL Map 的 L7 路由规则**，不是表达式语言，也不是策略引擎。

---

## **2. Path Pattern 支持的语法（非常重要）**

### **2.1 支持的形式（只有这几种）**

|**形式**|**是否支持**|**说明**|
|---|---|---|
|/api-a-v1/*|✅|最常用|
|/api/*|✅|前缀匹配|
|/|✅|根路径|
|/*|✅|catch-all|
|/api-a-v1/orders/*|✅|更具体路径|

### **2.2**

### **不支持**

### **的形式（常见误解）**

|**写法**|**是否支持**|**说明**|
|---|---|---|
|正则表达式|❌|没有 regex|
|`/api-(a|b)/*`|❌|
|/api-*-v1/*|❌|* 只能在末尾|
|/api-a-v[0-9]/*|❌|不支持字符类|
|Header / Method 判断|❌|只能看 Path|

👉 **这是一个“静态前缀匹配表”**，不是 Nginx location ~。

---

## **3. Path 匹配的执行规则（极其关键）**

### **3.1 Longest Path Match（最长前缀优先）**

```
/api/*            → 命中
/api-a-v1/*       → 更长 → 优先
/api-a-v1/order/* → 最长 → 优先
```

⚠️ **顺序无关紧要，长度决定优先级**

---

## **4. 数量与 Quota 限制（你真正需要关心的）**

### **4.1 URL Map 级别限制（当前官方值）**

|**项目**|**限制**|
|---|---|
|Path Rules 总数|**最多 1000**|
|Path Matchers|最多 50|
|Host Rules|最多 50|
|单个 Path Rule 中 paths 数|最多 10|

👉 对 API 平台来说，**1000 条 Path Rule = 很充裕**。

---

### **4.2 Backend Service 的复用限制**

- 一个 Backend Service：

  - ✅ 可被多个 Path Rule 使用

- 一个 Path Rule：

  - ❌ 只能指向一个 Backend Service

---

## **5. Cloud Armor 相关的“隐性限制”（很多人不知道）**

> Cloud Armor **不是**在 URL Map 上生效，而是在 Backend Service 上。

因此：

```
Path Pattern 数量 ≠ Cloud Armor Rule 数量
```

但你会遇到这些**间接约束**：

|**项目**|**限制**|
|---|---|
|每个 Backend Service|只能绑定 1 个 Armor Policy|
|每个 Armor Policy|最多 ~100 条规则（视类型）|
|Rate Limit|每 Policy 配置独立|

👉 这正是你现在拆 BS 的正确性所在。

---

## **6. 你的示例命令是否“安全 & 推荐”？**

### **6.1 你的写法**

```
--path-rules="/api-a-v1/*=bs-api-a-v1,/api-b-v1/*=bs-api-b-v1"
```

### **6.2 结论**

✅ **完全合法**

✅ **符合最佳实践**

⚠️ **但有 3 个工程建议**

---

## **7. 工程级最佳实践建议（强烈建议）**

### **7.1 一个 Path Rule 只放一个 API（可读性）**

**不推荐：**

```
--path-rules="/api-a-v1/*=bs-api-a-v1,/api-b-v1/*=bs-api-b-v1"
```

**推荐：**

```
--path-rules="/api-a-v1/*=bs-api-a-v1"
--path-rules="/api-b-v1/*=bs-api-b-v1"
```

👉 方便审计、diff、回滚。

---

### **7.2 Path 命名必须“稳定 + 版本化”**

```
/api-{service}-v{major}/*
```

这是**非常适合 Cloud Armor 隔离的天然边界**。

---

### **7.3 永远保留 default-service（兜底）**

```
defaultService = bs-default
```

- 用于：

  - 未匹配路径

  - 拦截扫描流量

  - 返回 404 / 403

---

## **8. 常见坑位（你现在正好在边缘）**

### **❌ 误区 1：把 URL Map 当表达式引擎**

```
/api-(a|b)-v1/*   ❌
```

➡️ 必须拆成多条 Path Rule。

---

### **❌ 误区 2：用 Path Rule 做安全逻辑**

> URL Map 不做 allow / deny

> Cloud Armor 才做

---

## **9. 一句话结论（给你一个可记忆的结论）**

> **--path-rules 是一个“前缀匹配 → Backend Service”的静态映射表，**

> **没有正则、没有表达式、没有条件判断，靠“最长路径匹配”决胜。**

---

## **10. 如果你愿意，我可以继续帮你：**

- 给你一份 **URL Map + Backend Service 的配额规模评估表**

- 帮你设计 **API 数量增长到 100+ 时的拆分策略**

- 给你一个 **Terraform module：自动生成 path-rules**

你现在更关心 **规模上限**，还是 **如何避免后期重构 URL Map**？
