|
目录
第一节 main函数
第二节 创建server
创建ListenerManager
创建ClusterManager
envoy在处理请求时用到的主要的组件为Listener和Cluster,Listener负责监听downstream发送的请求,Listener监听到downstream发送的请求后,由Cluster来选择upstream中的某个端点来处理该请求,最终Listener将端点的回复信息传回到downstream,其架构图如下所示:

?Listener,Cluster在系统启动时会根据其配置被初始化。? Listener,Cluster和系统其余组件构成了一个完整的服务器,当所有这些组件初始化成功后,envoy服务器也初始化成功了,运行中的服务器可以不断的利用Listener,Cluster等组件来完成其工作。
envoy有一个基于事件的线程模型,主线程会管理envoy服务器的生命周期,配置处理,运行状态等,其余还有一些工作线程,这些工作线程用来处理各种网络请求。所有线程都围绕一个事件循环(libevent)操作,任何给定的downstream的TCP连接(包括其上的所有多路复用流)在其生命周期内都将由一个工作线程处理。每个工作线程会维护一个到?upstream的端点的TCP连接池。
接下来通过分析envoy的启动过程源码来看envoy是怎么创建其服务器的。
envoy源码地址:https://github.com/envoyproxy/envoy.git
第一节 main函数
envoy实现main函数的文件为source/exe/main.cc,main函数调用MainCommon::main实现了envoy的启动,MainCommon::main的代码如下所示:
source/exe/main_common.cc

? 图1-1
第234,235行代码一起实例化了一个server,255行代码启动该server,至此,envoy就启动起来了。
第二节 创建server
envoy通过启动一个服务器server来工作,该server由各种组件组成,这里最关键的组件就是用于管理系统中的监听器listener的监听管理器ListenerManager,用来管理集群cluster的集群管理器ClusterManager,? server在初始化时会初始化这些组件。
第一节中234,235创建server时最终调用的server创建代码如下:
?source/exe/main_common.cc

图2-1
?这里是调用的Server::InstanceImpl类的构造函数构造了server的实例,下面来分析Server::InstanceImpl类的构造函数,代码如下所示:
source/server/server.cc

图2-2
Server::InstanceImpl类构造了server对象,并创建了该server需要的所有组件,比如用于管理系统中的监听器listener的监听管理器ListenerManager,用来管理集群cluster的集群管理器ClusterManager等。
?95行:创建并初始化文件日志系统,用于管理日志;
105行:初始化envoy的热重启功能模块,用于管理envoy服务器的热重启;
106行:初始化一个DrainManager,这个在服务器热重启或者动态删除Listener时会使用
107行:Server::InstanceImpl构造函数调用initialize来创建服务器的其余组件,监听管理器ListenerManager和集群管理器ClusterManager也是在这里创建的。
initialize核心代码如下所示:
source/server/server.cc

图2-3

图2-4

图2-5
346行:从配置文件中加载bootstrap信息
510行:创建ListenerManager来管理Listener
591行:通过从配置文件加载出来的bootstrap信息来创建cluster和listener
创建ListenerManager
ListenerManager拥有一个或多个工作线程,每个工作线程会去处理一个给定的downstream的TCP连接,它会维护一个到?upstream的端点的TCP连接池。ListenerManager负责创建这些工作线程,工作线程创建好了以后ListenerManager就创建完成了。
上文中ListenerManager在source/server/server.cc的510行通过ListenerManagerImpl类的构造函数被创建,该构造函数传入了4个参数:
第一个参数this,是这里的server对象;第二个参数listener_component_factory_是监听器组件工厂类ProdListenerComponentFactory,它将创建真实的套接字,在系统热启动时它会尝试从父进程获取套接字;第三个参数worker_factory_是一个工作线程工厂类ProdWorkerFactory,它将用于为服务器创建工作线程;第四个参数是个布尔类型,指示是否启用事件分发器的统计功能,这个值默认是false,因为启用了事件分发器的统计功能后数据量可能会非常大,如果需要启用该统计功能,需要将bootstrap的enable_dispatcher_stats的值配置为true。下面我们来看ListenerManagerImpl类构造函数的代码:
envoy/source/server/listener_manager_impl.cc

图2-6
261行:server.options().concurrency() 是命令行指定的工作线程的个数,默认是一个
262行:创建工作线程,这里的worker_factory就是上文中提到的工作线程工厂类ProdWorkerFactory,其创建线程的额函数createWorker()如下所示:
envoy/source/server/worker_impl.cc

图2-7
创建ClusterManager
TBD
?
|