跳到内容

HTTP 请求流

虽然 概述 描述了 Knative Serving 的逻辑组件,架构 描述了其整体架构,但本文档解释了 HTTP 请求流向在 Knative Serving 上运行的应用程序的行为和流程。

下图显示了 Knative Serving 的不同请求流和控制平面循环。请注意,某些组件(如自动伸缩器和 apiserver)不会在每次请求时更新,而是定期度量系统(这被称为控制平面)。

Diagram of Knative request flow through HTTP router to optional Activator, then queue-proxy and user container

HTTP 路由器、激活器(activator)和自动伸缩器都是共享的集群级资源;这使得新的 Knative 服务在不使用时只需进行元数据开销,并允许更有效地管理和升级这些共享组件。

路由决策是在 HTTP 路由器(可插拔的入口层)上基于每个请求的级别进行的,并记录在请求的内部标头中。一旦请求被分配给一个 Revision,后续的路由就取决于度量的流量流;在低流量或零流量时,传入的请求被路由到激活器,而在高流量级别(可用突发容量大于 target-burst-capacity)时,流量被直接路由到应用程序 Pod。

从零开始扩展

当特定 Revision 的流量很低或为零时,HTTP 路由器会将流量发送到激活器,其中包含指示所选 Revision 的标头。激活器充当传入请求的缓冲区或队列——如果请求被路由到一个当前没有可用容量的 Revision,激活器会延迟该请求,并向自动伸缩器发出信号,表示需要额外的容量。

当自动伸缩器检测到 Revision 的可用容量低于请求的容量时,它会向 Kubernetes 请求增加 Pod 数量

当这些新 Pod 准备就绪或现有 Pod 有容量时,激活器会将延迟的请求转发到就绪的 Pod。如果需要启动新 Pod 来处理请求,这就称为“冷启动”。

高流量

当一个 Revision 具有大量流量(可用突发容量大于 target-burst-capacity)时,入口路由器直接使用 Revision 的 Pod 地址进行编程,并且激活器从流量流中移除。这降低了延迟并提高了效率,因为不需要激活器的额外缓冲。在所有情况下,queue-proxy 仍然在请求路径中。

如果流量降至突发容量阈值以下(计算方式为:current_demand + target-burst-capacity > (pods * concurrency-target)),则入口路由器将被重新编程,以将流量发送到激活器 Pod。

入口和激活器之间的流量路由是通过将激活器端点的子集写入 Revision 服务的 Endpoints 来完成的。与 Revision 对应的 Kubernetes Service 是无选择器(selectorless)的,它可以包含 Revision 的 Pod 端点或激活器端点。使用无选择器服务的原因如下:

  • 某些入口实现不允许跨命名空间的服务引用。激活器运行在 knative-serving 命名空间中。

  • 某些入口实现不能无缝处理路由端点所依赖的 Kubernetes 服务的更改。

  • 通过基于每个 Revision 进行子集划分,传入的请求被引导到一个少量激活器,这些激活器可以更有效地做出就绪/未就绪容量决策。每个 Revision 的有效激活器数量少不是一个扩展问题,因为当 Revision 扩展以接收更多流量时,激活器将从请求路径中移除。

队列代理

queue-proxy 组件实现了一些功能来提高 Knative 的可靠性和扩展性

  • 为自动伸缩器度量并发请求,特别是在从请求路径中移除激活器时。

  • 如果请求,则实现containerConcurrency 请求并发的硬限制

  • 处理 Pod 终止时的优雅关闭(拒绝新请求,使就绪性检查失败,继续为现有请求提供服务)。

  • 从用户容器外部报告 HTTP 指标和跟踪,以便可以度量基础架构延迟的贡献。

  • 在启动期间(就绪之前),更积极地探测用户容器,以便比 Kubelet 探测(最快每秒一次)更早地提供服务。

  • 为了支持此功能,Knative Serving 会将用户容器的 readinessProbe 重写为 queue-proxy 的一个参数;queue-proxy 的就绪性检查结合了 queue-proxy 自身的就绪性和用户容器的就绪性。

我们使用分析和 cookie 来了解网站流量。有关您使用我们网站的信息会与 Google 共享以达到此目的。了解更多。