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