Envoy proxy 源代码解读 - http 请求处理流程分析

类名解释

  • Http::ServerConnection 表示 Envoy 作为一个 http server,在接收到下游请求后,建立的一个 Http::Connection,
  • Http::ClientConnection 表示 Envoy 作为一个 client,对上游 cluster 发起 http 请求,建立的一个 Http::Connection
  • Http::StreamEncoder ,将网络层接收到的数据 Buffer::Instance 数据进行编码,对于 Http::ServerConnection 来说,用于将上游链接返回的数据发给下游;对于 Http::ClientConnection 来说,用于将下游请求的数据转发给上游。
  • Http::StreamDecoder,将网络层接收到的数据 Buffer::Instance 进行解码,对于 Http::ServerConnection 来说,用于将下游请求的数据转发给上游;对于 Http::ClientConnecton 来说,将上游返回的数据转发给下游请求
  • Http::ConnectionPool::Instance 是对上游 Cluster 建立的连接池,http/1.1http2 有各自的实现

http 数据处理流程概念版

  • Network::Listener 接收到数据,发给 Network::Filter 处理
  • Http::ConnectionManagerImpl 作为一个 Network::Filter ,创建一个 Http::ServerConnection,用于编解码网路数据
  • Http::Router::Filter 作为一个 Network::StreamDecoderFilter,将下游数据转发给上游
  • 根据 header 信息,router 通过 Http::ConnectionPool::Instance 获取一个上游链接 Http::ServerConnection ,用于编解码和上游服务通信的数据
  • 下游的数据经过 Http::ServerConneciton 的解码器 Http::StreamDecoder 处理后转发给 Http::ClientConnection 的编码器 Http::StreamEncoder 处理
  • 上游的数据经过 Http::ClientConnection 的解码器 Http::StreamDecoder 处理后转发给 Http::ServerConnection 的编码器 Http::StreamEncoder 处理

http 数据处理流程简化版

  1. Network::Listener 接收到数据,发给 Network::Filter 处理
  2. Http::ConnectionManagerImpl 作为一个 Network::Filter 接收到数据,创建 Http::ServerConnection 对象,数据都通过 Http::ServerConnection 对象 dispatch
  3. Http::Http1:ServerConnectionImpl 作为 Http::ServerConnection 实现,会拿到 Http::ConnectionManagerImpl 提供的一个 Http::StreamDecoder 对象,通过 Http::StreamDecoder 将下游的请求数据转发出去,同时会将 Http:StreamEncoder 返回给 Http::ConnectionManagerImpl (通过 callback),用于接收来自上游的数据。
  4. 下游请求产生的 Http::ServerConnection 创建成功以后,Http::ConnectionManagerImpl 则同时拿到了 Http::StreamDecoderHttp::StreamEncoder
  5. Http::ConnectionManagerImpl::ActiveStream 作为 Http:StreamDecoder 实现,将下游数据转发给 Http::StreamDecoderFilter 处理
  6. Http::Router::Filter 作为 Http::StreamDecoderFilter 实现,会获取上游的 http 连接池对象 Http::ConnectionPool::Instance ,通过连接池对象请求一个 Http::ClientConnection,链接异步创建上游链接后,会通过 callbacks 返回一个 Http:StreamEncoder 对象,用于接收转发过来的下游的数据。
  7. Http::Http1::ConnectionPoolImpl 作为 Http::ConnectionPool::Instance 实现,创建 Http::ClientConnection 对象时,会接收到实参 Http::StreamDecoderHttp::Router::Filter::UpstreamRequest ),用于用于接收上游返回的数据
  8. 上游请求的 Http::ClientConnection 创建成功后,Http::Router::Filter::UpstreamRequest 则同时拿到了 Http::StreamDecoderHttp::StreamEncoder
  9. 第 3 步创建的 Http::ServerConnection 继续接收到下游请求数据时,会转发给Http::ConnectionManagerImpl 提供的 Http::StreamDecoder 对象,下游数据会被 copy 后,通过第 6 步 Http::ClientConnection 创建的 Http::StreamEncoder 对象,发送给上游
  10. Http::ClientConnection 接收到上游数据后,会传给第 7步Http::Router::Filter::UpstreamRequest 实现的 Http::StreamDecoder 的相关方法,然后发给第 3 步骤 Http::ClientConnection 创建的 Http::StreamEncoder 对象,发送给下游

http 数据处理流程详细版

对于 http/1.1 请求,大致流程如下(很多异步处理):

  • Network::FilterManager 会把网络层接收到的数据依次发给不同的 Network::Filter,其中 http 请求交给 Http::ConnectionManagerImpl 对象处理 (Http::ConnectionManagerImpl 是一个 Network::Filter
  • Http::ConnectionManagerImpl 接收到下游请求,通过配置对象创建一个 Http::ServerConnection 对象作为 codec ,将所有数据都 dispatch 到该对象。http/1.1 和 http2 有各自的实现,分别为Http::Http1::ServerConnectionImplHttp::Http2::ServerConnectionImpl ,返回哪个对象则由配置对象来决定。
  • Http::Http1::ServerConnectionImpl 在接收到分发的数据时(dispatch 方法),会调用 nodejs 的 http_parser 组件,对数据流进行解析。
  • 在接收到下游请求时(Http::Http1::ServerConnectionImpl::onMessageBegin),会创建一个 Http::Http1::ServerConnectionImpl::ActiveRequest 对象来封装本次请求
  • ActiveRequest 对象初始化的时候,会初始化一个 Http::Http1::ResponseStreamEncoderImpl 对象(Http::StreamEncoder实现),也就是 ActiveRequest::response_encoder_,用来给下游请求返回数据,ActiveRequest 本身不会操作 response_encoder_ 而是交由Http::StreamDecoder的实现来处理。
  • Http::Http2::ServerConnectionImpl 接着会调用 Http::ServerConnectionCallbacks::newStream 获取 Http::StreamDecoder 实现对象,并赋值给 ActiveRequest::request_decoder_,用于做进一步数据处理。
  • 在获取 Http::StreamEncoder 对象的时候,会将 ActiveRequest::response_encoder_ 成员对象作为 Http::StreamEncoder 实参传递出去,用于接收上游数据的时候直接写入到下游。
  • Http::ConnectionManagerImpl::ActiveStream 作为 Http::StreamDecoder 用来解析 http 数据流,将数据分发给不同的 Http::StreamDecoderFilter 进行处理,其中Http::Router::Filter 作为 Http::StreamDecoderFilter 实现会被加入到 filter chain
  • Http::StreamDecoderFilter 在解析 headers 信息时,获取 router 信息,并创建 Http::Router::FilterHttp::Router::Filter 则会为每一个下游的请求创建一个 Http::Router::Filter::UpstreamRequest 对象来封装。Filter 在接收到对下游数据的 decodeData 时,会拷贝一份数据,然后调用对应的 UptreamRequestencodeData 方法发送给上游 stream
  • UpstreamRequest 实现了 Http::StreamDecoderHttp::StreamCallbacks,用来 decode 上游 stream 接收到的数据,实现的 Http::StreamCallbacksonPoolReady 方法用来接收 Http::StreamEncoder 对象,用来给 Router::Filter 对象 decodeData 之后直接调用 Http::StreamEncoder::encodeData 发送给上游。
  • UpstreamRequest 对象初始化时,会根据配置对象获取对上游 Cluster 发起请求的连接池对象 Http::ConnectionPool::Instance,根据上游 cluster 的定义会实现不同的连接池,如果是 http/1.1,则是 Http::Http1::ConnPoolImpl 。而 UpstreamRequest 自身则作为 Http::StreamDecoder 传给上游链接,用来接收直接接收上游发来的数据,然后通过 Http::StreamDecoderFilterCallbacks 接口的 encodeData 方法调用发送给下游。
  • Http::Http1::ConnPoolImpl 会关联上一个 Upstream::Host 对象,用来创建 Network::ClientConnection 对象,用于网络层的数据传输和接收
  • 对于每一个下游来的请求,Http::Http1::ConnectionPoolImpl 都会关联上一个 Http::CodecClient 对象(Http::CodecClientProd),对于 http2 上游 Http::Http2::ConnectionPoolImpl 情况类似,
  • Http::CodecClientProd对象则会创建一个 Http::ClientConnection 对象,用来表示对上游发起的一个链接,对于 http/1.1 ,创建的是 Http::Http1::ClientConnectionImpl,而 http2 创建的是 Http::Http2::ClientConnectionImpl
  • Http::Http1::ClientConnectionImpl::newStream 方法被调用的时候,会实例化一个 Http::Http1::RequestStreamEncoderImpl 对象,实现了 Http::StreamHttp::StreamEncoder ,返回给调用方,用来将接收到的数据转发给上游。
  • Http::Http1::ClientConnectionImpl::newStream 方法被调用的时候,会保留 Http::StreamEncoder 参数(pending_responses_ 成员),用来将接收到的上游 cluster 返回的数据直接通过 Http::StreamEncoder 返回 UpstreamRequest,而不是一层层的回调

Http::ConnectionManagerImpl

当 Envoy 启动时(或者接收到 lds 更新),解析到如下 listener 配置:

    listeners:
    - address:
        socket_address:
          address: 0.0.0.0
          port_value: 15001
      filter_chains:
      - filters:
        - name: envoy.http_connection_manager

则会初始化一个ConnectionManagerImpl 对象作为网络层的一个 filter,这是 ConnectionManagerImpl 的定义:

// source/common/http/conn_manager_impl.h
/**
 * Implementation of both ConnectionManager and ServerConnectionCallbacks. This is a
 * Network::Filter that can be installed on a connection that will perform HTTP protocol agnostic
 * handling of a connection and all requests/pushes that occur on a connection.
 */
class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
                              public Network::ReadFilter,
                              public ServerConnectionCallbacks,
                              public Network::ConnectionCallbacks {}

在实现的 Network::Filter接口的 onData 方法中,它会通过配置对象(Envoy 在做抽象封装的时候,基本上都是通过某种 Config 对象作为工厂类来返回具体实现的)方法http:ConnectionManagerConfig::createCodec 获取一个实现了 Http::ServerConnection 接口的对象,对于 http/1.1 ,返回的则是 Http::Http1::ServerConnectionImpl 对象,http2 返回的则是 Http::Http2::ServerConnectionImpl ,并将其赋值给 ServerConnectionPtr codec_ 成员对象。当 Http::ConnectionManagerImpl::onData 接收到网络层数据时,会通过 codec_ 成员对象(也就是 Http::ServerConnection::dispatch 方法)将数据分发出去。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值