HCM upstream/downstream 事件驱动协作下的 HTTP 反向代理流程#

HTTP 反向代理的总流程#

整体看,Socket 事件驱动的 HTTP 反向代理总流程如下: 图:Socket 事件驱动的 HTTP 反向代理总流程

图中看出,有4种事件驱动了整个流程。后面几节会逐个分析。

为免一下子进入各个步骤细节而让人迷途,建议读者回顾一下之前举例的所有步骤的总流程: Istio 下 Envoy 配置举例

下面以 HTTP/1.1 为例,分 5 个步骤去解释 HTTP 代理的过程:

  1. Downstream Read Request 模块协作

  2. Downstream Request Router 模块协作

  3. Upstream Write Request 模块协作

  4. Upstream Read Response 模块协作

  5. Downstream Write Response 模块协作

Downstream Read Request 模块协作#

图:Downstream Read-Ready 模块协作

图:Downstream Read-Ready 模块协作#

用 Draw.io 打开

大概说明一下流程:

  1. downstream socket 可读回调

  2. Http::ConnectionManagerImpl 读取 socket,增量放入 Http1::ConnectionImpl

  3. Http1::ConnectionImpl 调用 nghttp2 增量解释 HTTP 请求

  4. 如果 nghttp2 认为已经 完整读取了 HTTP Request 请求,则调用 Http::ServerConnection::onMessageCompleteBase()

  5. Http::ServerConnection::onMessageCompleteBase() 首先 停止 downstream ReadReady 监听

  6. Http::ServerConnection::onMessageCompleteBase() 调用 Http::FilterManager ,发起 http filter chain 的 decodeHeaders 迭代流程

  7. 一般,http filter chain 的最后一个 http filter 是 Router::FilterRouter::Filter::decodeHeaders() 被调用

  8. Router::Filter::decodeHeaders() 的逻辑就见下图了。

Downstream Request Router 模块协作#

图:Downstream Request Router 模块协作

图:Downstream Request Router 模块协作#

用 Draw.io 打开

大概说明一下流程:

  1. Router::FilterRouter::Filter::decodeHeaders() 被调用

  2. 根据配置的 Router 规则,匹配到 Cluster

  3. 如 Cluster 连接池对象不存在,则新建

  4. 新建 Envoy::Router::UpstreamRequest 对象。

  5. 调用 Envoy::Router::UpstreamRequest::encodeHeaders(bool end_stream) , encode HTTP header

  6. 经过一系列的负载均衡算法,匹配到 upstream 的 host(endpoint)

  7. 发现到选定的 upstream host 的连接不足,则:

    1. 打开一新的 socket fd(未连接)

    2. 注册 upstream socket FD 的 WriteReady / Connected 事件。 准备在事件回调时写 upstream request

    3. 用 socket fd 发起到 upstream host 的异步连接请求

  8. 关联 downstream 与 upstream fd

Upstream Write Request 模块协作#

图:upstream connect & write 模块协作

图:upstream connect & write 模块协作#

用 Draw.io 打开

大概说明一下流程:

  1. upstream socket write ready 回调

  2. 发现是连接成功回调,关联 upstream socket 到 ConnectionPool::ActiveClient

  3. upstream socket write ready 回调

  4. 发现是连接可写,写入 upstream HTTP request

Upstream Read Response 模块协作#

图:Upstream Read-Response 模块协作

图:Upstream Read-Response 模块协作#

用 Draw.io 打开

Downstream Write Response 模块协作#

图:Downstream Write Response 模块协作

图:Downstream Write Response 模块协作#

用 Draw.io 打开

求证过程#