認(rèn)識Varnish負(fù)載均衡
開源的產(chǎn)品總是會引起不少人的注意和喜愛。那么,varnish這個加速產(chǎn)品,熟悉HTTP這塊領(lǐng)域的朋友都不會陌生。它的負(fù)載均衡應(yīng)用優(yōu)勢什么樣子的呢?這還要我們從它的結(jié)構(gòu)和性能說起,之后才是對于負(fù)載均衡的介紹,其中還有一些進(jìn)程問題,如果大家不能很好的掌握,還需要對這些知識進(jìn)行一下充電。
Varnish負(fù)載均衡的分析
最近分析了varnis-2.0.4的一部分代碼,主要側(cè)重于其在負(fù)載均衡部分的實現(xiàn)。通過閱讀一些參考文獻(xiàn),以及自己的一些見解我分析,將代碼分析文檔整理于此。
首先將varnish整體工作流程在此進(jìn)行介紹。
1.Varnish 的總體結(jié)構(gòu)
Varnish 主要有兩個進(jìn)程:管理進(jìn)程和 cache 子進(jìn)程。
1)管理進(jìn)程主要就是對于varnish的整個工作狀態(tài)進(jìn)行的調(diào)整和設(shè)置。編譯運(yùn)行之后,它將建立一個守護(hù)進(jìn)程varnishd。Varnishd不斷folk()出cache子進(jìn)程來處理HTTP請求。它的實現(xiàn)部分在源代碼中bin/varnishd/目錄中,主要文件有varnishd.c 、mgt.h、mgt_chld.c、mgt_param.c mgt_cli.h、mgt_pool.c 、mgt_vcc.c、mgt_cli.h、mgt_cli.c。
2)下面談?wù)刢ache子進(jìn)程。
Cache子進(jìn)程包含了實現(xiàn)命令行加載、請求處理、緩存以及負(fù)載均衡的所有線程。分別為:命令行接受處理線程(CLI_Run) ,放牧線程(wrk_herder_thread),放牧超時線程(wrk_herdtimer_thread),請求接受線程(vca_acct),數(shù)據(jù)接受線程(vca_main),很多工作線程(wrk_thread),HTTP對象超時線程(exp_timer),后臺服務(wù)器連接探測線程(vbp_wrk_poll_backend)。
主要涉及到的文件有:
cache_lck.c、cache_panic.c、cache_cli.c、cache_fetch.c、cache_center.c、cache_vcl.c、cache_http.c、cache_session.c、cache_backend_cfg.c、cache_backend_pool.c、cache_backend.h、cache_pool.c、cache_expire.c、cache_hash.c、cache_accptor.c
Cache 子進(jìn)程處理所有具體工作,各個線程的任務(wù)包括:
◆命令行接受處理線程(CLI_Run):接受從管理進(jìn)程通過管道傳過來的命令,做出相應(yīng)決定。其中初始時由管理進(jìn)程默認(rèn)產(chǎn)生,三個命令(vcl.load、vcl.use、start)來啟動后臺服務(wù)器連接探測線程 和兩個接受線程。
◆放牧線程(wrk_herder_thread):用于產(chǎn)生工作線程池。線程不足時會增加線程池。
◆放牧超時檢查線程(wrk_herdtimer_thread):清理一些工作超時的工作線程。
◆請求接受線程(vca_acct):接受 HTTP 初次請求,并叫醒某個工作線程,處理請求。
◆數(shù)據(jù)接受線程(vca_main):在發(fā)送數(shù)據(jù)以后,繼續(xù)可能的再次請求,并把請求交給工作線程。
◆工作線程(wrk_thread):不斷處理請求,進(jìn)入狀態(tài)機(jī)。如果緩存沒有命中,還需要從后臺服務(wù)取過數(shù)據(jù),存入緩存并回復(fù)。然后把該連接通過管道轉(zhuǎn)給數(shù)據(jù)接受線程并睡去。
◆HTTP 對象超時檢查線程(exp_timer):檢查二叉堆中 HTTP 超時對象,刪除之。
◆后臺服務(wù)器連接探測線程(vbp_wrk_poll_backend):針對不同的后臺服務(wù)器組進(jìn)行輪詢,檢查存活與否。
各線程的工作流程大致如圖一所示
圖一:cache子進(jìn)程各個線程流程圖#p#
2.負(fù)載均衡實現(xiàn)的分析
就目前分析來看,Cache子進(jìn)程的代碼實現(xiàn)部分主要由cache_main.c這個文件為主要脈絡(luò)的。Cache_main.c中將cache子進(jìn)程的各個線程一一初始化。
目前我所關(guān)注的重點(diǎn)在于wrk_thread部分,它是實現(xiàn)varnish負(fù)載均衡的主要內(nèi)容。
1)wrk_thread的作用:不斷處理請求,進(jìn)入狀態(tài)機(jī)。如果緩存沒有命中,還需要從后臺服務(wù)取過數(shù)據(jù),存入緩存并回復(fù)。然后把該連接通過管道轉(zhuǎn)給數(shù)據(jù)接受線程并sleep。
2)wrk_thread的工作流程:
圖二:cache子進(jìn)程中,wrk_thread線程工作流程
3)Wrk_thread的代碼實現(xiàn)分析:wrk_thread線程在cache_main.c文件中初始化(代碼:WRK_Init() ,cache_main.c,line 121),具體實現(xiàn)在cache_pool.c文件中出現(xiàn)。
Cache_pool.c文件中主要函數(shù)有:
static void
wrk_addpools(const unsigned pools):增添work線程池
static void *
wrk_herder_thread(void *priv) :放牧進(jìn)程,用于產(chǎn)生工作線程池。線程不足時會增加線程;
static void *
wrk_herdtimer_thread(void *priv):放牧超時檢查線程,清理一些工作超時的工作線程。
static void
wrk_breed_flock(struct wq *qp):在需要并且空間允許的情況下,產(chǎn)生新的線程
static void
wrk_decimate_flock(struct wq *qp, double t_idle, struct varnish_stats *vs):檢查空閑或者已經(jīng)執(zhí)行完的線程,從線程池中清除。
static void *
wrk_thread(void *priv):實際的工作線程,實現(xiàn)主要功能。