idou老師教你學Istio 29:Envoy啟動流程
Envoy啟動時,會啟動一個進程,並在這個進程中啟動很多線程,這樣,可以啟動很多worker線程,一般worker線程數與核心數相同,每個worker線程處理所有已配置的listener上的請求,管理連接並處理filterchain,非阻塞;同時,在這個進程中會啟動一個主線程,它負責啟動和停止envoy,也是通過API提供配置管理的線程,同時它收集不同的指標,管理其它線程,也是非阻塞的。
- 重要數據結構定義
2.1 Filter
過濾器,包括listener filter、network filter和http filter。Listener filter可以用於操作連接元數據,在新接收的套接字上進行操作,例如獲取原始目的地址,重定向連接等;network filter主要負責數據讀寫;http filter主要負責數據處理。
2.2 Listener
監聽器,envoy中支持在每個線程中配置任意數量的監聽器,每個監聽器獨立配置一定數量的network filter,也可以選擇性的配置listener filter,listener filter在連接建立之前處理,network filter在連接建立之後處理。
2.3 Worker
一個worker對應一個envoy的執行線程,將listener綁定在worker上,worker負責監聽、過濾和轉發,每個連接的生命周期會綁定在一個單獨的worker上,通常情況下,envoy實現了100%的非阻塞。
- 代碼流程
3.1 流程概述
Envoy啟動時,首先啟動主線程,在主線程中對listener和filter進行初始化操作,然後將listener綁定到worker上,並由主線程拉起worker線程,由worker線程負責監聽新連接。
3.2 初始化
3.2.1 main入口
main函數是envoy啟動的總入口,首先生成main_common,用於後面的初始化。
3.2.2 初始化main_common
在main_common裏面會生成maincommonbase,它會做server instance的初始化,一個instance是一個服務的實例.
3.2.3 Instance初始化
在maincommonbase裏調用InstanceImpl函數後,首先對啟動攜帶的配置信息進行註冊,然後執行instance的初始化。
Instance的初始化包括兩部分:
① 將當前instance註冊到ListenerManager,來管理更新;
② 創建並初始化MainImpl,MainImpl用來初始化監聽listener;
MainImpl根據配置文件獲取靜態監聽listener列表,將它們實例化並註冊到ListenerManager。
3.2.4 初始化listener
tener,根據配置文件為它創建ListenerFilterFactoryList,並根據配置為它添加ListenerFilterFactory。
listener filter有三個:original dst filter,proxy protocol filter, TLS inspector filter,一一按照配置判斷是否加入ListenerFilterFactoryList。
配置ListenerFilterFactoryList的同時,也會根據配置為這個listener創建NetworkerFilterFactoryList,供後續建立在這個listener上的連接使用。
3.3 啟動
3.3.1 啟動入口
在main_common初始化正常完成後,執行main_common→run()啟動,從而後續執行instance的run()方法,在instance的run()方法,會執行網絡級別上的listener初始化。
3.3.2 啟動worker,將listener綁定到worker上
此處,會將從配置文件讀取的所有listener綁定到所有的worker上,worker是服務的並發線程,數目一般和核心數相同,將listener綁定到worker上後會通過connectionhandler模塊將其初始化。
3.3.3 Listener初始化
Listener的初始化過程首先生成ActiveListener,通過ActiveListener調用network包內的創建函數來對listener進行網絡級別的初始化。
3.3.5 啟動worker線程,進入監聽
Listener綁定在worker上,當listener初始化完成後,需要啟動worker服務才能真正進入監聽流程。
此處,為每個worker啟動新線程,並調用libevent的event_base_loop進入監聽,等待連接事件到達觸發後,回調onAccept進入處理流程。
- 總結
本文從程序入口main函數開始,分析了envoy如何啟動,以及如何對listener、worker這些核心數據結構進行初始化,並詳細闡述了從envoy主線程啟動到worker線程進入監聽行為的全過程。
相關服務請訪問https://support.huaweicloud.com/cce/index.html?cce_helpcenter_2019
idou老師教你學Istio 29:Envoy啟動流程