类名解释
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
对象dispatch
Http::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
方法发送给上游stream
UpstreamRequest
实现了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::ClientConnectionImpl
Http::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
方法)将数据分发出去。