Linux企業運維之varnish
- varnish簡介
-
-
- 總體架構編輯
- 工作流程編輯
- Varnish程式結構
- Varnish Configuration Language (VCL)
-
- 實驗步驟:
-
-
- 搭建varnish伺服器
- 負載均衡
-
- cdn 推送平台
-
-
- cdn 的概念
- cdn 的簡單測試
-
varnish簡介
Varnish 的作者Poul-Henning
Kamp是FreeBSD的核心開發者之一,他認為現在的計算機比起1975年已經複雜許多。在1975年時,儲存媒介隻有兩種:記憶體與硬碟。但現在計算機系統的記憶體除了主存外,還包括了CPU内的L1、L2,甚至有L3快取。硬碟上也有自己的快取裝置,是以Squid
Cache自行處理物件替換的架構不可能得知這些情況而做到最佳化,但作業系統可以得知這些情況,是以這部份的工作應該交給作業系統處理,這就是
Varnish cache設計架構。 [1]
varnish項目是2006年釋出的第一個版本0.9.距今已經有十多年了,此文檔之前也提過varnish還不穩定,那是2007年時候編寫的,經過varnish開發團隊和網友們的辛苦耕耘,現在的varnish已經很健壯。很多門戶網站已經部署了varnish,并且反應都很好,甚至反應比squid還穩定,且效率更高,資源占用更少。相信在反向代理,web加速方面,varnish已經有足夠能力代替squid。
總體架構編輯
==總體流程==
主程序 fork 子程序,主程序等待子程序的信号,子程序退出後,主程序重新啟動子程序
子程序生成若幹線程。
Accept 線程:接受請求,将請求挂在 overflow隊列上
Work 線程: 多個,從對列上摘除請求,對請求進行處理,直到完成,然後處理下一個
請求
Epoll 線程: 一個請求處理稱作一個 session,在 session 周期内,處理完請求後,會交給
Epoll 處理,監聽是否還有事件發生。
Expire 線程:對于緩存的對象,根據過期時間,組織成二叉堆,該線程周期檢查該堆的
根,處理過期的檔案。
線程之間的關系:
accept 線程
監聽端口,接受連接配接。
接受後組織成 struct ses(session 結構) ,看是否有空閑的工作線程,如果有,将請求給它,
pthread_cond_signal 信号通知它沒有空閑線程,如果 overflow過大,則放棄該請求。否則,
将其挂在 overflow 上(需要更多工作線程,發通知)。
繼續監聽 2.1.2 work 線程
從 overflow隊列上摘取請求(struct ses),進入狀态機處理,處理結束後,通過 pipe通信,
将 struct ses發送給 epoll 線程。
Epoll 線程,得到傳過來的 struct ses,若還沒有過期,将 socket 放入 epoll 的事件中,事
件發生時,也會将其放入到 overflow中進行。
工作流程編輯
Varnish與一般伺服器軟體類似,分為master(management)程序和child(worker,主要做cache的工作)程序。master程序讀入指令,進行一些初始化,然後fork并監控child程序。child程序配置設定若幹線程進行工作,主要包括一些管理線程和很多woker線程。
針對檔案緩存部分,master讀入存儲配置(-s file[,path[,size[,granularity]]]
),調用合适的存儲類型,然後建立/讀入相應大小的緩存大檔案。接着,master初始化管理該存儲空間的結構體。這些變量都是全局變量,在fork以後會被child程序所繼承(包括檔案描述符)。
在child程序主線程初始化過程中,将前面打開的存儲大檔案整個mmap到記憶體中(如果超出系統的虛拟記憶體,mmap失敗,程序會減少原來的配置mmap大小,然後繼續mmap),此時建立并初始化空閑存儲結構體,挂到存儲管理結構體,以待配置設定。
接着,真正的工作開始,Varnish的某個負責接受新HTTP連接配接的線程開始等待使用者,如果有新的HTTP連接配接過來,它總負責接收,然後叫醒某個等待中的線程,并把具體的處理過程交給它。Worker線程讀入HTTP請求的URI,查找已有的object,如果命中則直接傳回并回複使用者。如果沒有命中,則需要将所請求的内容,從後端伺服器中取過來,存到緩存中,然後再回複。
配置設定緩存的過程是這樣的:它根據所讀到object的大小,建立相應大小的緩存檔案。為了讀寫友善,程式會把每個object的大小變為最接近其大小的記憶體頁面倍數。然後從現有的空閑存儲結構體中查找,找到最合适的大小的空閑存儲塊,配置設定給它。如果空閑塊沒有用完,就把多餘的記憶體另外組成一個空閑存儲塊,挂到管理結構體上。如果緩存已滿,就根據LRU機制,把最舊的object釋放掉。
釋放緩存的過程是這樣的:有一個逾時線程,檢測緩存中所有object的生存期,如果超初設定的TTL(Time To
Live)沒有被通路,就删除之,并且釋放相應的結構體及存儲記憶體。注意釋放時會檢查該存儲記憶體塊前面或後面的空閑記憶體塊,如果前面或後面的空閑記憶體和該釋放記憶體是連續的,就将它們合并成更大一塊記憶體。
整個檔案緩存的管理,沒有考慮檔案與記憶體的關系,實際上是将所有的object都考慮是在記憶體中,如果系統記憶體不足,系統會自動将其換到swap空間,而不需要varnish程式去控制。
Varnish程式結構
-
Management程序
Management程序主要實作應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個指令行接口等。Management程序會每隔幾秒鐘探測一下Child程序以判斷其是否正常運作,如果在指定的時長内未得到Child程序的回應,Management将會重新開機此Child程序。
管理的接口
- Cacher程序 程序包括多個線程
Accept 線程:接收新的連接配接請求并響應 Worker 線程:child程序會為每個會話啟動一個worker線程,是以,在高并發的場景中可能會出現數百個worker線程甚至更多; Object Expiry 線程:從緩存中清理過期内容; Commad line 線程 : 管理接口 Storage/hashing 線程 :緩存存儲 Log/stats 線程:日志管理線程 Backend Communication 線程:管理後端主機線程 Varnish依賴“工作區(workspace)”以降低線程在申請或修改記憶體時出現競争的可能性。在varnish内部有多種不同的工作區,其中最關鍵的當屬用于管理會話資料的session工作區。
Varnish Configuration Language (VCL)
是 varnish配置緩存政策的工具,它是一種基于“域”(domain specific)的簡單程式設計語言,它支援有限的算術運算和邏輯運算操作、允許使用正規表達式進行字元串比對、允許使用者使用set自定義變量、支援if判斷語句,也有内置的函數和變量等。使用VCL編寫的緩存政策通常儲存至.vcl檔案中,其需要編譯成二進制的格式後才能由varnish調用。事實上,整個緩存政策就是由幾個特定的子例程如vcl_recv vcl_fetch等組成,它們分别在不同的位置(或時間)執行,如果沒有事先為某個位置自定義子例程,varnish将會執行預設的定義。
VCL政策在啟用前,會由management程序将其轉換為C代碼,而後再由gcc編譯器将C代碼編譯成二進制程式。編譯完成後management負責将其連接配接至varnish執行個體,即child程序。正是由于編譯工作在child程序之外完成,它避免了裝載錯誤格式VCL的風險。是以,varnish修改配置的開銷非常小,其可以同時保有幾份尚在引用的舊版本配置,也能夠讓新的配置即刻生效。編譯後的舊版本配置通常在varnish重新開機時才會被丢棄,如果需要手動清理,則可以使用varnishadm的vcl.discard指令完成。
-
Receive 狀态,也就是請求處理的入口狀态,根據 VCL 規則判斷該請求應該是 Pass 或 Pipe,或者進入
Lookup(本地查詢)。
- Lookup 狀态,進入此狀态後,會在 hash 表中查找資料,若找到,則進入 Hit 狀态,否則進 入 miss 狀态。
- Pass 狀态,在此狀态下,會進入後端請求,即進入 fetch 狀态。
- Fetch 狀态,在 Fetch 狀态下,對請求進行後端的擷取,發送請求,獲得資料,并進行本地 的存儲。
- Deliver 狀态, 将擷取到的資料發送給用戶端,然後完成本次請求。
Vcl内置函數和處理流程(狀态引擎)
Vcl内置函數:vcl配置的緩存政策在此些内置函數發揮作用;
vcl_recv:用于接受和處理請求。當請求到達并成功接收後被調用,通過判斷請求的資料來決定如何處理請求。例如如何響應、怎麼響應、使用哪個後端伺服器等。
vcl_fetch:根據伺服器端的響應作出緩存決策,如判斷擷取的内容來決定是将内容放入緩存,還是直接傳回給用戶端。
vcl_pipe:對于無法了解的使用者請求,将請求直接發往後端主機;
vcl_hash:自定義hash生成時的資料來源
vcl_pass:用于将請求直接傳遞至後端主機,後端主機在應答資料後将應答資料發送給用戶端,但不進行任何緩存。
vcl_hit:從緩存中查找到緩存對象時要執行的操作;
vcl_miss:從緩存中款查找到緩存對象時要執行的操作;
vcl_deliver:将使用者請求的内容響應給用戶端時用到的方法;
vcl_error:在varnish端合成錯誤響應而時;
實驗步驟:
搭建varnish伺服器
首先安裝7.3版本的虛拟機,配置好網絡及yum源,關閉防火牆,下載下傳vim,lftp,net_tools(網絡工具,可以使用ifconfig指令)等常用軟體
再建立三個快照作為伺服器。因為考慮到IP沖突等問題,選擇使用一個網段,我用的是172.25.4.0/24這個網段,是以三個快照的IP都在該網段内
選擇最小安裝(沒有圖形界面),安裝完成後在中删除母盤
server1:172.25.4.1
server2:172.25.4.2
server3:172.25.4.3
在server1上将真機中的安裝包拷貝過來
安裝企業7版本的安裝包
檢視系統參數
vim /etc/varnish/varnish.params是服務的基本配置檔案
修改varnish服務使用的端口為80
server1上面設定,将server1作為一個代理伺服器,它的後端伺服器是server2這個web伺服器
用戶端請求web伺服器的資源通過server1這個代理伺服器
寫入sub vcl_deliver子產品
寫入兩種情況:server1有緩存 server1沒有緩存
之後重新開機服務systemctl restart varnish
在三台伺服器上下載下傳并開啟http
将下server2寫入到第二台伺服器中
在真機裡通路server1
第一次因為要去通路,需要進行緩存,是以顯示MISS
之後就顯示HIT
負載均衡
在server1中編輯配置檔案,輸入以下内容
vim /etc/vaenish/default.vcl
将下bbs.westos.org:server3寫入到第三台伺服器的預設釋出檔案中
将下www.westos.org:server2寫入到第二台伺服器的預設釋出檔案中
再編輯真機vim /etc/hosts
測試
如果想要使第二台和第三台伺服器的分擔負載不一樣
則編輯以下内容
重新開機服務後測試,當通路www.westos.org時,兩台伺服器各通路一次
cdn 推送平台
cdn 的概念
CDN的全稱是Content Delivery
Network,即内容分發網絡。其基本思路是盡可能避開網際網路上有可能影響資料傳輸速度和穩定性的瓶頸和環節,使内容傳輸的更快、更穩定。通過在網絡各處放置節點伺服器所構成的在現有的網際網路基礎之上的一層智能虛拟網絡,CDN系統能夠實時地根據網絡流量和各節點的連接配接、負載狀況以及到使用者的距離和響應時間等綜合資訊将使用者的請求重新導向離使用者最近的服務節點上。其目的是使使用者可就近取得所需内容,解決
Internet網絡擁擠的狀況,提高使用者通路網站的響應速度。
CDN是建構在網絡之上的内容分發網絡,依靠部署在各地的邊緣伺服器,通過中心平台的負載均衡、内容分發、排程等功能子產品,使使用者就近擷取所需内容,降低網絡擁塞,提高使用者通路響應速度和命中率。CDN的關鍵技術主要有内容存儲和分發技術。
CDN的基本原理是廣泛采用各種緩存伺服器,将這些緩存伺服器分布到使用者通路相對集中的地區或網絡中,在使用者通路網站時,利用全局負載技術将使用者的通路指向距離最近的工作正常的緩存伺服器上,由緩存伺服器直接響應使用者請求。
cdn 的簡單測試
環境設定:httpd 服務 varnish服務 php服務
1)安裝bansys軟體包
unzip bansys.zip -d /var/www/html
2 )把解壓後的所有檔案必須放在httpd預設釋出目錄下
3)配置 /var/www/html/config.php
172.25.4.0/24;這個網段的所有主機都有權限清理代理伺服器上面的緩存
未完,