

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 路径路由模式
<a name="api-routing-path"></a>

按路径路由是一种将多个或所有 API 分组到同一个主机名下，并使用请求 URI 来隔离服务的机制；例如，`api.example.com/service-a` 或 `api.example.com/service-b`。

## 典型用例
<a name="path-routing-use-case"></a>

大多数团队之所以选择这种方法，是因为他们想要一个简单的架构，开发者只需要记住一个 URL（例如 `api.example.com`）即可与 HTTP API 交互。API 文档通常更容易执行摘要，因为它通常是放在一起的，而不是分到不同的门户或 PDF。

对于共享 HTTP API，基于路径的路由被认为是一种简单的机制。但是，它涉及操作开销，例如配置、授权、集成，以及由于多跳而导致的额外延迟。它还需要成熟的变更管理流程，从而确保错误配置不会中断所有服务。

在 AWS 中，有多种方法可以共享 API 并有效地路由到正确的服务。以下各节讨论了三种方法：HTTP 服务反向代理、API 网关和 Amazon CloudFront。统一 API 服务的建议方法都不依赖于运行 AWS 的下游服务。只要与 HTTP 兼容，这些服务就可以在任何地点，或在任何技术上运行，而不会出现问题。

## HTTP 服务反向代理
<a name="path-routing-proxy"></a>

您可以使用像 [NGINX](https://www.f5.com/go/product/welcome-to-nginx) 这样的 HTTP 服务器来创建动态路由配置。在 [Kubernetes](https://kubernetes.io/) 架构中，您还可以创建入口规则，以匹配服务的路径。（本指南未涉及 Kubernetes 入口；有关更多信息，请参阅 [Kubernetes 文档](https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource)。）

以下 NGINX 配置将 `api.example.com/my-service/` 的 HTTP 请求动态映射到 `my-service.internal.api.example.com`。

```
server {
    listen  80;

    location (^/[\w-]+)/(.*) {
        proxy_pass $scheme://$1.internal.api.example.com/$2;
    }
}
```

下图说明了 HTTP 服务反向代理方法。



![\[将 HTTP 服务反向代理用于路径路由。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/cloud-design-patterns/images/routing-2.png)


对于某些不使用其他配置开始处理请求，允许下游 API 收集指标和日志的用例，这种方法可能就足够了。

要为经营生产做好准备，您需要能够为堆栈的每个级别添加可观测性、添加其他配置，或者添加脚本以自定义 API 入口点，以允许更高级的功能，例如速率限制或使用令牌。

### 优点
<a name="path-routing-proxy-pros"></a>

HTTP 服务反向代理方法的最终目标是创建一种可扩展且可管理的方法，将 API 统一到一个域中，以便其对所有 API 使用者表现得连贯一致。这种方法还使您的服务团队能够部署和管理自己的 API，并使部署后的开销最小。用于跟踪的 AWS 托管服务（例如 [AWS X-Ray](https://aws.amazon.com/xray/) 或 [AWS WAF](https://aws.amazon.com/waf/)）在这里仍然适用。

### 缺点
<a name="path-routing-proxy-cons"></a>

这种方法的主要缺点是需要对所需的基础设施组件进行大量的测试和管理，但如果您有站点可靠性工程（SRE）团队，这可能不是问题。

这种方法存在一个成本临界点。在中低量下，它比本指南中讨论的其他一些方法更昂贵。在大批量情况下，它非常具有成本效益（每秒约 10 万个事务或更高）。

## API Gateway
<a name="path-routing-gateway"></a>

[Amazon API Gateway](https://aws.amazon.com/api-gateway/) 服务（REST API 和 HTTP API）可以采用与 HTTP 服务反向代理方法类似的方式，对流量进行路由。在 HTTP 代理模式下使用 API 网关提供了一种简单的方法，可以将许多服务封装到顶级子域 `api.example.com` 的入口点中，然后将请求代理到嵌套服务；例如 `billing.internal.api.example.com`。

您可能不想在根网关或核心 API 网关中每个服务内映射每条路径，从而变得过于精细。相反，更倾向选择通配符路径，例如使用 `/billing/*` 将请求转发到计费服务。通过不映射根网关或核心 API 网关中的所有路径，您可以更为灵活地使用 API，因为您不必在每次更改 API 时都对根 API 网关进行更新。

![\[通过 API 网关进行路径路由。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/cloud-design-patterns/images/routing-3.png)


### 优点
<a name="path-routing-gateway-pros"></a>

为了控制更复杂的工作流程，例如更改请求属性，REST API 将公开 Apache Velocity 模板语言（VTL），以允许您修改请求和响应。REST API 可以提供其他益处，例如：
+ [Auth N/Z，使用 AWS Identity and Access Management（IAM）、](https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-net-applications-security/authentication.html)[Amazon Cognito](https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-net-applications-security/cognito.html) 或 [AWS Lambda 授权方](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html)
+ [用于追踪的 AWS X-Ray](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-understanding-xray-traces.html)
+ [与 AWS WAF 集成](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html)
+ [基本速率限制](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html)
+ 用于将使用者分组到不同等级的使用令牌（参见 API 网关文档中的[限制 API 请求以获得更高的吞吐量](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-request-throttling.html)）

### 缺点
<a name="path-routing-gateway-cons"></a>

在大流量下，某些用户可能会遇到成本问题。

## CloudFront
<a name="path-routing-cloudfront"></a>

您可以使用 [Amazon CloudFront](https://aws.amazon.com/cloudfront/) 中的[动态源选择功能](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html)，有条件地选择要转发请求的来源（服务）。您可以使用此功能通过单个主机名（例如 `api.example.com`）路由多个服务。

### 典型用例
<a name="path-routing-cloudfront-usecase"></a>

路由逻辑以 Lambda@Edge 函数中的代码形式存在，因此它支持高度可定制的路由机制，例如 A/B 测试、金丝雀发布、功能标记和路径重写。此过程如下图所示。

![\[通过 CloudFront 的路径路由。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/cloud-design-patterns/images/routing-4.png)


### 优点
<a name="path-routing-cloudfront-pros"></a>

如果您需要缓存 API 响应，则此方法是一个很好的方法，可以将服务集合统一到单个端点之后。这是一种经济实惠的方法，可以统一 API 集合。

此外，CloudFront 还支持[字段级加密](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/field-level-encryption.html)，以及可实现基本速率限制和基本 ACL 的与 AWS WAF 集成。

### 缺点
<a name="path-routing-cloudfront-cons"></a>

此方法最多支持 250 个可以统一的源（服务）。此限值对于大多数部署来说已经足够，但是随着服务组合的增长，它可能会导致大量 API 出现问题。

更新 Lambda@Edge 函数目前需要花费几分钟的时间。CloudFront 还需要最多 30 分钟才能将更改传播到所有节点。这最终会阻止更新完成前的进一步更新。