类名解释
Http::ServerConnection表示 Envoy 作为一个http server,在接收到下游请求后,建立的一个 Http::Connection,Http::ClientConnection表示 Envoy 作为一个client,对上游cluster发起http请求,建立的一个 Http::ConnectionHttp::StreamEncoder,将网络层接收到的数据Buffer::Instance数据进行编码,对于 Http::ServerConnection 来说,用于将上游链接返回的数据发给下游;对于 Http::ClientConnection 来说,用于将下游请求的数据转发给上游。Http::StreamDecoder,将网络层接收到的数据Buffer::Instance进行解码,对于 Http::ServerConnection 来说,用于将下游请求的数据转发给上游;对于 Http::ClientConnecton 来说,将上游返回的数据转发给下游请求Http::ConnectionPool::Instance是对上游Cluster建立的连接池,http/1.1和http2有各自的实现
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 数据处理流程简化版
Network::Listener接收到数据,发给Network::Filter处理Http::ConnectionManagerImpl作为一个Network::Filter接收到数据,创建Http::ServerConnection对象,数据都通过Http::ServerConnection对象dispatchHttp::Http1:ServerConnectionImpl作为Http::ServerConnection实现,会拿到Http::ConnectionManagerImpl提供的一个Http::StreamDecoder对象,通过Http::StreamDecoder将下游的请求数据转发出去,同时会将Http:StreamEncoder返回给Http::ConnectionManagerImpl(通过 callback),用于接收来自上游的数据。- 下游请求产生的
Http::ServerConnection创建成功以后,Http::ConnectionManagerImpl则同时拿到了Http::StreamDecoder和Http::StreamEncoder。 Http::ConnectionManagerImpl::ActiveStream作为Http:StreamDecoder实现,将下游数据转发给Http::StreamDecoderFilter处理Http::Router::Filter作为Http::StreamDecoderFilter实现,会获取上游的 http 连接池对象Http::ConnectionPool::Instance,通过连接池对象请求一个Http::ClientConnection,链接异步创建上游链接后,会通过 callbacks 返回一个Http:StreamEncoder对象,用于接收转发过来的下游的数据。Http::Http1::ConnectionPoolImpl作为Http::ConnectionPool::Instance实现,创建Http::ClientConnection对象时,会接收到实参Http::StreamDecoder(Http::Router::Filter::UpstreamRequest),用于用于接收上游返回的数据- 上游请求的
Http::ClientConnection创建成功后,Http::Router::Filter::UpstreamRequest则同时拿到了Http::StreamDecoder和Http::StreamEncoder - 第 3 步创建的
Http::ServerConnection继续接收到下游请求数据时,会转发给Http::ConnectionManagerImpl提供的Http::StreamDecoder对象,下游数据会被copy后,通过第 6 步Http::ClientConnection创建的Http::StreamEncoder对象,发送给上游 - 而
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::ServerConnectionImpl和Http::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 chainHttp::StreamDecoderFilter在解析 headers 信息时,获取 router 信息,并创建Http::Router::Filter,Http::Router::Filter则会为每一个下游的请求创建一个Http::Router::Filter::UpstreamRequest对象来封装。Filter在接收到对下游数据的decodeData时,会拷贝一份数据,然后调用对应的UptreamRequest的encodeData方法发送给上游streamUpstreamRequest实现了Http::StreamDecoder和Http::StreamCallbacks,用来decode上游 stream 接收到的数据,实现的Http::StreamCallbacks的onPoolReady方法用来接收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::ClientConnectionImplHttp::Http1::ClientConnectionImpl::newStream方法被调用的时候,会实例化一个Http::Http1::RequestStreamEncoderImpl对象,实现了Http::Stream和Http::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 方法)将数据分发出去。
本文深入解析了Envoy代理服务器的HTTP数据处理流程,包括ServerConnection和ClientConnection的建立,StreamEncoder和StreamDecoder的工作机制,以及ConnectionPool的使用。阐述了Envoy如何在下游请求和上游服务间进行高效的数据编解码和转发。

1451

被折叠的 条评论
为什么被折叠?



