envoy源码分析(八)--main线程专项分析
1 框架启动分析
三件事:
1 StrippedManBase 构造
作为MainCommon的base成员。
关键成员: server_, init_manager_
2 server instance 初始化
3 server run
3a worker run
在listener manager 框架下。
conn_handler
主循环:threadRoutine()
event_base_loop()
3b main run
event_base_loop()
2 分析异步任务注册/监听初始化。
异步注册:
connectHandlerImpl:: addListener()
TcpListenerImpl() 构造函数 【回调: onSocketEvent()】
dispacher.createFileEvent() 【水平触发】
FileEventImple()
newConnection()->createServerConnection()->NetworServerConnctionImpl
UdpListenerImpl() 构造函数 【回调: onSocketEvent()】
ListenerFilterBufferImpl() 构造函数 【回调: onFileEvent()】 【边缘触发】
filter->onData()
ServerConnectionImpl()构造函数 【回调: onFileEvent()】
FilterManagerImpl::onRead()/onWrite() 【边缘触发】
filter->onData()
createCodec()->Http2::ServerConnctionImpl()
codec_->dispatch(data)
onBody(data) --> decodeData()
event 实例化
IoSocketHandlerImpl::file_event_
FileEventImpl::cb_
回调
ActiveTcpListerner::onAccept()
ActiveUdpListener::onDataWorker()
3 Admin监听流程分析
InstanceBase构造的时候创建了类成员 handler_ , 类型是: ConnectionHandler
异步注册,与worker一样:
connectHandlerImpl:: addListener()
后边的回调流程都一样。
adminImpl::createCodec()
adminFilter::decodeData()
admin_makeRequest()
handler->start() <==> ADMIN_HANDLER() 【StatsRequest::start()】
handler->nexChunk() 【StatsRequest::nextChunk()】
监听启动的地方:
admin_->startHttpListener()
4 state机制与线程间同步
获取各worker统计的方法:
Stats::PrimitiveCounterSnapshot = PrimitiveCounter
关键结构的初始化:
在初始化函数 StrippedMainBase::StrippedMainBase() 中。
tls_ ThreadLocal::InstanceImpl()
// 在类 instanceBase 中是成员 thread_local_
todo
stats_store_ Stats::ThreadLocalStoreImpl()
// 在类 instanceBase 中是成员 Stats::StoreRoot& stats_store_;
统计合并机制:
admin线程启动了一个timer做合并,默认5秒。

state-sink的处理:
在admin线程发送。
在上小节的stat_flush_timer回调中调用
/source/extensions/stat_sinks/common/statsd/
UdpStatsdSink::flush()
5 xDS处理
增量xds的类型:
InstanceBase::initializaOrThrow()
MainImpl::initialize()
ClusterManagerImpl::initialize()
DeltaGrpcMuxFactory->create() => GrpcMuxDelta() // source/extensions/config_subscription/grpc/xds_mux/grpc_mux_impl.h
GrpcMuxImpl::Start()
GrpcStream::establishNewStream()
AsyncClient->start() // grpc/typed_async_client.h AsyncClient::start()
client->startRaw() // grpc/typed_async_client.cc startUntyped()
AsyncClientImpl::startRaw() // aync_cliet_impl.cc<grpc>
AsyncStreamImpl::initialize() // aync_cliet_impl.cc<grpc>
http_async_client.start()
TODO:找到tcp连接创建的地方。 这个tcp创建在GRPC库里边了,envoy代码是没有的。
重试的timer
retry_timer_ = dispatcher.createTimer(void{ establishNewStream() })
选取GRPC服务的工厂类:
AsyncClientManagerImpl::factoryForGrpcService() ==> AsyncClientFactoryImpl()
createUncachedRawAsyncClient() // 由工厂类创建不同的client。
AsyncClientImpl::AsyncClientImpl() // aync_cliet_impl.cc<grpc> 有 startRaw() 函数
grpc类型有两种,一种envoy自己实现的,一种google的, 在ads_config中可以进行配置:
https://www.envoyproxy.io/docs/envoy/v1.32.13/intro/arch_overview/other_protocols/grpc#arch-overview-grpc-services
TODO:不设置的时候,默认值用了哪个?
6 健康检查处理
函数 HealthCheckerFactory::ceate() 用来创建健康检查对象。
在两个地方调用:
1 ClusterFactoryImplBase::create()
调用栈:
ClusterManagerImpl:: initialize()
ClusterManagerImpl::loadCluster()
clusterFromProto()
2 HdsCluster::updateHealthchecks() 或 HdsCluster::initHealthChecks()
调用栈:
AsyncStreamImpl::onData()
AsyncStreamCallbacks::onReceiveMessageRaw() // typed_async_client.h
HdsDelegate::onReceiveMessage()
prcessMessage()
HdsDelegate::createHdsCluster()
7 到后端的连接
类 ClientConnectionImpl 的初始化函数中创建了类 ClientSocketImpl
浙公网安备 33010602011771号