陳 沛,馬衛(wèi)東
(1.武漢郵電科學(xué)研究院 湖北 武漢 430074;2.光迅科技股份有限公司 湖北 武漢 430205)
一種基于Nginx的負(fù)載均衡算法實(shí)現(xiàn)
陳 沛1,馬衛(wèi)東2
(1.武漢郵電科學(xué)研究院 湖北 武漢 430074;2.光迅科技股份有限公司 湖北 武漢 430205)
為了滿足日益增長的網(wǎng)站訪問量對(duì)服務(wù)器的需求,提出了一種基于Nginx的負(fù)載均衡算法,并完成算法的軟件實(shí)現(xiàn)。該算法能在高并發(fā)的情況下選擇合適的后臺(tái)服務(wù)器,充分利用硬件資源,減少系統(tǒng)阻塞或延時(shí)。測(cè)試結(jié)果表明,相比Nginx自帶的負(fù)載均衡算法,該算法處理連接的速率更高,穩(wěn)定性更好,達(dá)到了設(shè)計(jì)要求。
Nginx;負(fù)載均衡算法;Linux;性能提升
Abstract:In order to satisfy the increasing access number to the Web server,a load balancing algorithm based on Nginx is designed in this paper.The algorithm can choose the appropriate server in high concurrency situation,make full use of the hardware resources and reduce the system blocking or delay.The experimentshow that the algorithm is able to deal with connections faster with smaller error ratiocompared to the Nginx load balancing algorithm,and achieve the design requirement.
Key words:Nginx;load balance algorithm;Linux;performance improvement
隨著互聯(lián)網(wǎng)的快速發(fā)展,網(wǎng)絡(luò)用戶和網(wǎng)絡(luò)資源訪問都呈爆發(fā)式增長,越來越多的網(wǎng)絡(luò)服務(wù)器工作在高并發(fā)訪問環(huán)境下,由此帶來處理器的高負(fù)荷工作和繁忙的IO處理[1],單純的升級(jí)服務(wù)器硬件只能在一定程度上緩解此問題。而負(fù)載均衡機(jī)制能夠在現(xiàn)有硬件資源之上,將任務(wù)分?jǐn)偟蕉鄠€(gè)后臺(tái)服務(wù)器上共同進(jìn)行工作,它提供了一種廉價(jià)有效透明的方法擴(kuò)展服務(wù)器的并發(fā)訪問能力,避免系統(tǒng)阻塞[2]。其中,負(fù)載均衡算法的實(shí)現(xiàn)直接影響著服務(wù)器的性能表現(xiàn),可見,對(duì)服務(wù)器負(fù)載均衡算法的研究變得尤為重要。為了實(shí)現(xiàn)對(duì)服務(wù)器的準(zhǔn)確選擇,提出并設(shè)計(jì)了一種基于Nginx的負(fù)載均衡模塊。該系統(tǒng)能夠完成對(duì)其準(zhǔn)確測(cè)試。
Nginx是一款輕量級(jí)的Web服務(wù)器、反向代理服務(wù)器及電子郵件服務(wù)器。著名的Apache服務(wù)器會(huì)對(duì)每個(gè)請(qǐng)求都會(huì)使用一個(gè)進(jìn)程處理請(qǐng)求,當(dāng)用戶請(qǐng)求量多的時(shí)候,處理進(jìn)程也會(huì)大量增加,對(duì)系統(tǒng)的資源消耗較多,這樣就導(dǎo)致了對(duì)服務(wù)器的高內(nèi)存和CPU占用,這也就是為什么我們稱Apache為重量級(jí)服務(wù)器[3]。相對(duì)的,由于Http請(qǐng)求的大部分時(shí)間都在等待響應(yīng),Nginx的原理則是當(dāng)連接狀態(tài)改變的時(shí)候,服務(wù)器的事件分發(fā)器將被喚醒處理連接的變化,其他時(shí)間去處理別的請(qǐng)求,所以服務(wù)器只需要一個(gè)進(jìn)程就能夠處理大量的連接請(qǐng)求[3]。
如圖1所示,Nginx默認(rèn)是以多進(jìn)程的方式來工作的。啟動(dòng)后會(huì)開啟一個(gè)master進(jìn)程和多個(gè)worker進(jìn)程,master進(jìn)程主要用來管理worker進(jìn)程,接收來自外界的信號(hào),向各worker進(jìn)程發(fā)送信號(hào),監(jiān)控worker進(jìn)程的運(yùn)行狀態(tài),worker進(jìn)程才開始真正處理請(qǐng)求,各個(gè)worker進(jìn)程之間是相互獨(dú)立對(duì)等的。一個(gè)請(qǐng)求只可能在一個(gè)worker進(jìn)程中處理[4]。
Nginx采用了異步非阻塞的方式來處理請(qǐng)求,在Linux中使用Epoll系統(tǒng)調(diào)用來同時(shí)監(jiān)控多個(gè)事件,如果有事件準(zhǔn)備好了就返回,worker進(jìn)程開始處理請(qǐng)求。當(dāng)事件沒有準(zhǔn)備好時(shí),放到Epoll里面等待喚醒,這樣就可以處理大量的并發(fā)了。與多線程相比,這種事件處理方式是有很大的優(yōu)勢(shì)的,不需要?jiǎng)?chuàng)建線程,每個(gè)請(qǐng)求占用的內(nèi)存也很少,沒有上下文切換,更多的并發(fā)數(shù),只是會(huì)增加一點(diǎn)內(nèi)存而已。
圖1 Nginx架構(gòu)圖
另外,Nginx具有很好的可擴(kuò)展性,它提供了一個(gè)接口供第三方模塊的開發(fā),因此可以比較方便的基于Nginx實(shí)現(xiàn)本文的負(fù)載均衡算法。具體方法如下:
1)定義commands數(shù)組并添加到ngx_module_t結(jié)構(gòu)體中;
2)編寫解析模塊配置的方法ngx_http_mytest;
3)定義ngx_module_t結(jié)構(gòu)體中的 ctx接口供Http框架初始化;
4)編寫處理請(qǐng)求并返回響應(yīng)的函數(shù)ngx_http_mytest_handler,在函數(shù)內(nèi)實(shí)現(xiàn)算法;
完成上面四步之后,一個(gè)模塊就被添加到Nginx中,只需要編譯運(yùn)行就可以實(shí)現(xiàn)模塊的功能[4]。
服務(wù)器的負(fù)載均衡表示的是多臺(tái)服務(wù)器以對(duì)稱的方式組成一個(gè)服務(wù)器,每臺(tái)服務(wù)器的地位都相同,都可以獨(dú)立對(duì)外提供服務(wù)。每當(dāng)有新的請(qǐng)求來到的時(shí)候,負(fù)載均衡算法通過計(jì)算,選擇出對(duì)稱結(jié)構(gòu)中最適合處理這個(gè)請(qǐng)求的一臺(tái)服務(wù)器,將請(qǐng)求分配到這臺(tái)服務(wù)器上,而接受到請(qǐng)求的服務(wù)器將獨(dú)立的回應(yīng)用戶的請(qǐng)求。負(fù)載均衡在Nginx中的表現(xiàn)則是通過算法選擇合適的worker進(jìn)程來處理請(qǐng)求[5]。
負(fù)載均衡的實(shí)現(xiàn)方式分為軟件負(fù)載均衡、硬件負(fù)載均衡、局部負(fù)載均衡、全局負(fù)載均衡、靜態(tài)負(fù)載均衡、動(dòng)態(tài)負(fù)載均衡等[6],Nginx支持的幾種負(fù)載均衡策略包括:
1)輪詢法:每個(gè)請(qǐng)求按時(shí)間順序循環(huán)分配到不同的后端服務(wù)器,這個(gè)是Nginx默認(rèn)的算法。
2)權(quán)重法:根據(jù)不同權(quán)重來選擇服務(wù)器,服務(wù)器的權(quán)重可以手動(dòng)靜態(tài)設(shè)置,也可以動(dòng)態(tài)更新,最終服務(wù)器處理請(qǐng)求數(shù)目的比例正比于權(quán)重,這種方式用于后端服務(wù)器性能不均的情況。
3)ip_hash法:每個(gè)請(qǐng)求按訪問IP的hash結(jié)果分配,這種情況下每個(gè)用戶有固定的后端服務(wù)器,可以解決session問題。
4)url_hash法:按訪問請(qǐng)求的網(wǎng)址的hash結(jié)果來分配請(qǐng)求,不同的url指向不同的服務(wù)器,當(dāng)后端服務(wù)器開啟緩存時(shí),這種算法比較有效[7]。
總之,設(shè)計(jì)負(fù)載均衡策略需要考慮以下幾點(diǎn):
1)設(shè)計(jì)算法時(shí)應(yīng)保證盡量簡單,也許有些算法能更好的分配,但是卻過于復(fù)雜,實(shí)現(xiàn)這些算法會(huì)導(dǎo)致引入額外的資源消耗,反而引起系統(tǒng)阻塞[8];
2)系統(tǒng)在進(jìn)行決策時(shí),不僅要考慮當(dāng)前全局的負(fù)載狀態(tài),還要考慮一段時(shí)間內(nèi)的負(fù)載特性進(jìn)行決策。由于用戶請(qǐng)求的動(dòng)態(tài)變化,服務(wù)器系統(tǒng)各處理節(jié)點(diǎn)上的負(fù)載也在不斷變化,所以就要求系統(tǒng)能夠根據(jù)某種動(dòng)態(tài)均衡策略進(jìn)行服務(wù)節(jié)點(diǎn)負(fù)載的均衡,為用戶提供服務(wù)[9];
3)沒有最好的算法,也沒有通用的算法,只有最合適的算法。不同的時(shí)間,不同的地區(qū),不同的系統(tǒng),情況都是不一樣的。應(yīng)該綜合考慮這些因素,以適應(yīng)于不同變化的要求。
文中設(shè)計(jì)了一種新的負(fù)載均衡算法,它是一種綜合服務(wù)器負(fù)載能力與請(qǐng)求時(shí)間的動(dòng)態(tài)算法。首先用戶可以自定義負(fù)載均衡級(jí)別WM_LEVEL,等級(jí)越高,計(jì)算選擇的節(jié)點(diǎn)就越精確,但是實(shí)現(xiàn)選擇的時(shí)間越長。
首先算法會(huì)查找有沒有空閑服務(wù)器,如果有的話,則把請(qǐng)求發(fā)到服務(wù)器上;如果沒有剩余的空閑服務(wù)器的時(shí)候,算法會(huì)綜合考慮服務(wù)器的當(dāng)前負(fù)載能力、總負(fù)載能力、和上次請(qǐng)求的間隔、一段時(shí)間內(nèi)服務(wù)器請(qǐng)求失敗的次數(shù)等等因素進(jìn)行選擇。算法的實(shí)現(xiàn)函數(shù)為ngx_http_upstream_init_fair,其中nreq是服務(wù)器當(dāng)前承載的請(qǐng)求,delta是距離上一次請(qǐng)求的間隔,評(píng)分宏與當(dāng)前承載請(qǐng)求數(shù)、請(qǐng)求失敗次數(shù)成負(fù)相關(guān),與上一次請(qǐng)求間隔、服務(wù)器總負(fù)載能力成正相關(guān)。因此當(dāng)前承載請(qǐng)求越少越優(yōu),相同請(qǐng)求數(shù)下,上一次間隔越大分?jǐn)?shù)越優(yōu)。
其次,算法還具有自動(dòng)調(diào)優(yōu)功能,在函數(shù)ngx_http_upstream_fair_try_peer中實(shí)現(xiàn),當(dāng)fail次數(shù)過多的時(shí)候,函數(shù)會(huì)更新參數(shù),選擇更合適的服務(wù)器;當(dāng)所有節(jié)點(diǎn)的fail次數(shù)都增加的時(shí)候,會(huì)更新算法中參數(shù)的系數(shù),使?jié)M足動(dòng)態(tài)選優(yōu)的要求,當(dāng)然用戶也可以手動(dòng)調(diào)用優(yōu)化。另外,服務(wù)器的參數(shù)被保存在紅黑樹中,這樣就可以保證加載參數(shù)實(shí)現(xiàn)算法的速度[10]。算法流程圖如圖2所示。
圖2 算法流程圖
為了保證足夠多的連接數(shù)模擬高并發(fā)訪問情況,需要把內(nèi)存配置的足夠大而CPU資源有限[11]。本次測(cè)試的硬件平臺(tái)選擇的是。
系統(tǒng)版本:CentOS release 7 x86 64位
Nginx版本:1.9.10
處理器:4核8線程
內(nèi)存容量:16 G
硬盤容量:100 G
網(wǎng)絡(luò)連接:本地連接
在進(jìn)行測(cè)試之前,首先進(jìn)行Linux系統(tǒng)與Nginx的參數(shù)優(yōu)化[12],如下所示:
worker_processes auto #自動(dòng)把Nginx進(jìn)程與處理器綁定
worker_connections 65535 #每個(gè)進(jìn)程允許的最多連接數(shù)
net.ipv4.ip_local_port_range=1024 65000 #允許系統(tǒng)打開的端口范圍。
max_user_processes 65535#系統(tǒng)支持打開的最大文件數(shù)
采用Webbench模擬并發(fā)連接測(cè)試,Webbench是有名的網(wǎng)站壓力測(cè)試工具,可以向我們展示服務(wù)器的兩項(xiàng)內(nèi)容:每秒鐘相應(yīng)請(qǐng)求數(shù)和每秒鐘傳輸數(shù)據(jù)量。Webbench不但能具有便準(zhǔn)靜態(tài)頁面的測(cè)試能力,還能對(duì)動(dòng)態(tài)頁面進(jìn)行測(cè)試[13]。
在Linux下安裝好Webbench工具后,啟動(dòng)Nginx,只需輸入
就可以開始測(cè)試,命令中的1000模擬的并發(fā)連接數(shù),30表示測(cè)試的持續(xù)時(shí)間,后面跟著要訪問的網(wǎng)頁,等待30 s之后就會(huì)返回測(cè)試每秒鐘相應(yīng)請(qǐng)求數(shù)和每秒鐘傳輸數(shù)據(jù)量。
圖3 Webbench性能測(cè)試
在Nginx默認(rèn)的負(fù)載均衡策略下,逐漸增加模擬的并發(fā)連接數(shù),觀察對(duì)應(yīng)的請(qǐng)求響應(yīng)速率與連接成功數(shù)[14],觀察規(guī)律,得到結(jié)果如表1;然后,添加自定義的負(fù)載均衡模塊,make install編譯安裝之后,再保持同樣的并發(fā)連接數(shù)進(jìn)行測(cè)試,得到結(jié)果如表2所示。
對(duì)比兩組數(shù)據(jù),并繪出趨勢(shì)圖。可以發(fā)現(xiàn)當(dāng)并發(fā)連接數(shù)逐漸增加時(shí),系統(tǒng)開始阻塞,處理連接速率降低,請(qǐng)求失敗數(shù)增加。但是在相同的并發(fā)連接數(shù)目下,自定義算法的連接速率大于默認(rèn)算法,而且隨著并發(fā)連接數(shù)的增加,錯(cuò)誤頁面比例的增加速率也遠(yuǎn)小于默認(rèn)算法。
表1 默認(rèn)負(fù)載均衡算法測(cè)試結(jié)果
表2 自定義負(fù)載均衡算法測(cè)試結(jié)果
在60 000并發(fā)連接時(shí),自定義負(fù)載均衡算法的響應(yīng)速率是默認(rèn)的3倍,而請(qǐng)求失敗數(shù)只有一半;當(dāng)連接數(shù)上升至70 000時(shí),默認(rèn)的算法已經(jīng)阻塞,自定義算法依然能正常工作。
可以得出在相同的硬件上,自定義負(fù)載均衡算法能夠容納更多的并發(fā)連接數(shù),而且保持更好的響應(yīng)速度。
圖4 連接速率對(duì)比
文中基于輕量級(jí)服務(wù)器Nginx設(shè)計(jì)了一種新的動(dòng)態(tài)負(fù)載均衡算法,本算法會(huì)優(yōu)先選擇空閑進(jìn)程,在沒有空閑進(jìn)程的情況下會(huì)綜合考慮服務(wù)器節(jié)點(diǎn)的剩余節(jié)點(diǎn)處理能力、各個(gè)后臺(tái)服務(wù)器的當(dāng)前實(shí)際負(fù)載、進(jìn)程在某個(gè)時(shí)間段之間的平均負(fù)載,擇優(yōu)選擇后臺(tái)進(jìn)程,避免系統(tǒng)阻塞,保證高并發(fā)能力[15]。測(cè)試表明本算法能有效的為請(qǐng)求選擇合適的服務(wù)器,達(dá)到負(fù)載均衡的效果,相比默認(rèn)算法能在相同的硬件條件下支持更多的并發(fā)連接數(shù),達(dá)到了設(shè)計(jì)要求。
圖5 失敗請(qǐng)求數(shù)對(duì)比
[1]楊小嬌.輕量級(jí)高并發(fā)Web服務(wù)器的研究與實(shí)現(xiàn)[D].南京:南京郵電大學(xué),2014.
[2]祝瑞,車敏.基于HTTP協(xié)議的服務(wù)器程序分析[J].現(xiàn)代電子技術(shù),2012(4):117-119,122.
[3]凌質(zhì)億,劉哲星,曹蕾.高并發(fā)環(huán)境下Apache與Nginx的I/O性能比較 [J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2013(6):204-208.
[4]陶輝.深入理解Nginx:模塊開發(fā)與架構(gòu)解析[M].北京:機(jī)械工業(yè)出版社,2013.
[5]蔣文旭.基于Nginx部署環(huán)境的Web加速方案設(shè)計(jì)與實(shí)現(xiàn)[D].北京:北京郵電大學(xué),2013.
[6]郭平,李琪.基于服務(wù)器負(fù)載狀況分類的負(fù)載均衡調(diào)度算法[J].華中科技大學(xué)學(xué)報(bào):自然科學(xué)版,2012(S1):62-65.
[7]Bragard Q,Ventreaque A.Global dynamic loadbalancing for decentralised distributed simu-lation[C]. Proceedings of the Winter Simulation Conference,2014:3797-3808.
[8]王紅斌.Web服務(wù)器集群系統(tǒng)的自適應(yīng)負(fù)載均衡調(diào)度策略研究[D].長春:吉林大學(xué),2013.
[9]王利萍.基于Nginx服務(wù)器集群負(fù)載均衡技術(shù)的研究與改進(jìn)[D].濟(jì)南:山東大學(xué),2015.
[10]王永輝.基于Nginx高性能Web服務(wù)器性能優(yōu)化與負(fù)載均衡的改進(jìn)與實(shí)現(xiàn)[D].成都:電子科技大學(xué),2015.
[11]梁明剛,陳西曲.Linux下基于epoll+線程池高并發(fā)服務(wù)器實(shí)現(xiàn)研究 [J].武漢工業(yè)學(xué)院學(xué)報(bào),2012(3):54-59.
[12]李杰.一種高性能服務(wù)器的設(shè)計(jì)與性能評(píng)估[J].軟件,2014(12):88-93.
[13]喬平安,顏景善,周敏.基于Linux系統(tǒng)的構(gòu)建高性能服務(wù)器的研究 [J].計(jì)算機(jī)與數(shù)字工程,2016(4):653-657.
[14]黃靜,李炳.基于Nginx的Web服務(wù)器性能優(yōu)化研究[J].浙江理工大學(xué)學(xué)報(bào):自然科學(xué)版,2016(4):600-606.
[15]李逍遙.基于LAMP的Web服務(wù)器性能優(yōu)化問題研究與實(shí)現(xiàn)[D].北京:北京郵電大學(xué),2015.
Design of a load balancing algorithm based on Nginx
CHEN Pei1,MA Wei-dong2
(1.Wuhan Research Institute of Posts&Telecommunications,Wuhan430074,China;2.Accelink Technologies Co., Ltd., Wuhan430205,China)
TN912
A
1674-6236(2017)19-0019-04
2016-07-25稿件編號(hào)201607173
陳 沛(1994—),男,江西吉安人,碩士研究生。研究方向:通信與信息系統(tǒng)、互聯(lián)網(wǎng)技術(shù)。