前言
Envoy是Servicemesh体系中的佼佼者,也是目前Istio默认集成的数据平面,在网上Envoy源码解析的文章非常少,基本很难搜罗到对应的一些细节资料。以下将从源码级别切入,深度分析Envoy架构
1. 初始化
1.1 main函数执行
服务启动的总入口main函数,会去生成MainCommon,并执行run方法。
int
1.2 MainCommon初始化
// main_common.cc
1.3 Instance初始化
Instance会启动初始化,在初始化核心函数中,将会进行listenerConfig的全面注册
// server.cc
需要格外注意的是,这边addOrUpdateListener的ListenerImpl,是Server NameSpace下的,其继承关系如下所示:
class
该类主要作用,在于明确listener的配置,以及明确其Read/Write Filter的创建方式。真正的Listener,此时尚未被创建出来。Listener的Read/Write Filter的Factory如下函数进行遍历添加:
// createNetworkFilterFactoryList方法将进行遍历中的每个filter工厂类的初始化
2. 启动
2.1 启动入口
在main函数执行的最后,会调用MainCommon的启动方法:
main_common
从而进一步调用到InstanceImpl的run方法
bool
在InstanceImpl#run方法中,会进行真实网络级别Listener的初始化(基于上文提到的ListenerManager中的ListenerConfig数组active_listeners),
void
2.2 绑定listener到worker上
每个work绑定一个单独的ConnectionHandler,handler将完成listener绑定的任务。worker即代表了envoy服务的并发度。主体逻辑都将在worker及绑定的对应的libevent库中执行。
void
2.3 Listener初始化
void
2.4 Listener对新连接设置回调函数 & Listener Filter创建
void
2.5 连接初始化 & Read/Write Filter创建
划重点了,此处同样利用了libevent对连接的读写事件进行监听,同时采用了epoll边缘触发的机制。同时可以看到,write_buffer采用了高低水位的一个监控控制,来避免对服务本身造成太大的冲击。
void
2.6 启动Worker
初始化完了连接和Listener,也初始化完了Accept Listener Filter和Read/Write Listener Filter,此时,Listener的libevent事件已经准备就绪,有请求到来后,Connection的read/write事件也将被触发。
void
3. 结语
本章节,分析了最开始阶段envoy如何启动,以及如何进行相关的核心数据结构的初始化。下一章节,我们将结合源码,进一步分析当请求到来后,envoy是如何进行处理的。我们将一个全流程完成串联后,将会进行一些核心数据结构的关系梳理。