2

我在 AWS 上部署了一些 RESTfull API,主要是在 Elasticbeanstalk 上。

我的公司正在逐渐采用微服务架构,因此,我想开始以更专业和自动化的方式管理这些 API。因此,我想采用某种 API Manager 来提供标准功能,例如路由和发现。

另外,我希望使用这样的 API Manager 将我的一些 API 公开到 Internet。管理器将仅通过 SSL 暴露于 Internet,并且在将外部消费者的请求路由到内部 API 之前,应该需要某种形式的身份验证。对于我的用例,每个请求的 Authorization 标头中的简单 API 密钥就足够了。

我目前正在考虑将两种产品作为 API 管理器:WSO2 和 Kong。前者是托管在 Github 上的一个有点新的开源项目。

在我正在考虑的所有部署场景中,API 管理器都必须部署在 AWS EC2 实例上。此外,它们必须至少部署在两个不同的可用区和弹性负载均衡器 (ELB) 后面,以便为托管 API 提供高可用性。

我的大多数 API 都遵守 HATEOAS 约束。因此,他们的许多 JSON 响应都包含指向其他资源的链接,这些资源必须根据原始请求动态构建。

例如:

如果用户通过公开的 API Manager 从 Internet 发送请求,则 URL 如下所示: https ://apimanager.mycompany.com/accounts/123

因此,用户应该会收到一个 JSON 响应,其中包含一个 Account 资源,其中包含一个指向订阅资源的链接。链接 URL 应基于原始请求的协议、主机和端口,因此应如下所示:https://apimanager.mycompany.com/subscriptions/789

为了满足上面提到的动态链接生成要求,我的 API 依赖于 X-Forwarded-Proto、X-Forwarded-Host 和 X-Forwarded-Port HTTP 标头。这些应该包含协议(http 或 https)、主机名和消费者在原始请求中使用的端口,不管请求通过了多少代理。

但是,我注意到当请求通过 ELB 时,X-Forwarded-Proto 和 X-Forwarded-Port 标头更改为引用请求通过的最后一个 ELB 的值,而不是原始请求中的值。

例如:如果原始请求通过 HTTPS 到达 API Manager,Manager 通过 HTTP 将请求转发到内部 API;因此,当请求到达第二个 ELB 时,ELB 会将 X-Forwarded-Proto 标头更改为“http”。结果,X-Forwarded-Proto 标头的原始“https”值丢失。因此,API 无法在 URL 中使用“https”协议建立正确的链接。

显然,ELB 不能配置为以任何其他方式运行。我在 AWS 的文档中找不到任何可能影响此行为的设置。

此外,似乎没有比 AWS 的 ELB 更好的替代品了。如果我选择使用 HAProxy 等其他产品,或者通过 API Manager 本身进行负载平衡,我将不得不将其安装在常规 EC2 实例上,因此会产生单点故障。

我包括一个非正式的图表,以更好地表达我的观点。

图表

此外,我找不到任何有关 WSO2 或 Kong 部署方案的相关讨论,这些讨论将以任何方式解决这些问题。我不清楚这些产品应该如何与 AWS 的 ELB 相关联。

非常欢迎有类似环境的其他人发表评论。

谢谢你。

4

1 回答 1

1

有趣的问题/挑战 - 我不知道配置Elastic Load Balancer X-Forwarded-*标头行为的方法。但是,您可以通过利用 ELB 的不同侦听器类型来解决此问题,用于OSI 模型的两个受支持的网络层:

没有代理协议的 TCP/SSL 侦听器

与其使用对终止 SSL 等有意义的 HTTP 侦听器(OSI 第 7 层),不如将非侵入式 TCP/SSL 侦听器(OSI 第 4 层)用于内部负载平衡器,请参阅协议

当您将 TCP(第 4 层)用于前端和后端连接时,您的负载均衡器会将请求转发到后端实例而不修改标头。[...] [强调我的]

我没有尝试过,但希望X-Forwarded-*在这种情况下,外部 HTTP/HTTPS 负载平衡器添加的标头未经内部 TCP/SSL 负载平衡器修改即可通过。

带有代理协议的 TCP/SSL 侦听器

或者,您也可以立即为您的负载均衡器利用更高级/最新的代理协议支持,请参阅介绍性博客文章Elastic Load Balancing 添加对代理协议的支持以了解更多信息:

直到今天,ELB 仅在您使用 HTTP(S) 负载平衡时才允许您获取客户端 IP 地址,它将此信息添加到 X-Forwarded-For标头中。由于 X-Forwarded-For 仅用于 HTTP 标头,如果 ELB 配置为 TCP 负载平衡,您将无法获取客户端 IP 地址。你们中的许多人告诉我们,您希望 TCP 流量具有类似的功能,因此我们添加了对代理协议的支持。它只是在发送到服务器的 TCP 数据中添加一个带有客户端连接信息的人类可读标头。[...] 代理协议在您提供非 HTTP 流量时很有用。或者,如果您正在发送 HTTPS 请求并且不想终止负载均衡器上的 SSL 连接,则可以使用它。[...]

除了X-Forwarded-*标头之外,您还可以启用禁用 代理协议处理。另一方面,您的后端层可能尚未自动促进代理协议,需要相应地进行调整。

于 2015-06-27T14:51:08.007 回答