雜談篇-nginx(tengine)+lua動(dòng)態(tài)后端實(shí)現(xiàn),無間斷擴(kuò)容縮容

現(xiàn)在很多地方都使用nginx或者tengine進(jìn)行前端的負(fù)載均衡胎源,但單純使用nginx(tengine)不能完全滿足日常需求辜窑,所以攒驰,需要進(jìn)行適當(dāng)?shù)墓δ軘U(kuò)展吝岭,在以往只能是nginx c模塊開發(fā),這樣費(fèi)時(shí)費(fèi)力還難維護(hù)威蕉,對(duì)于中小型公司簡(jiǎn)直是一萬點(diǎn)傷害呢刁俭。幸運(yùn)的是有大神做了nginx的lua模塊,使得nginx(tengine)功能擴(kuò)展變得簡(jiǎn)單和易維護(hù)韧涨。

結(jié)合我們現(xiàn)在正在使用的例子牍戚,分幾篇文章和大家分享一下,nginx(tengine)和lua一起搭配使用的例子虑粥。

動(dòng)態(tài)后端

面對(duì)場(chǎng)景:

自動(dòng)化擴(kuò)容和縮容還有智能化運(yùn)維一直是我們努力實(shí)現(xiàn)的目標(biāo)如孝,但在傳統(tǒng)的nginx后端配置中,修改upstream的server配置是需要reload或者restart娩贷。對(duì)于應(yīng)用為長(zhǎng)鏈接第晰、流量大系統(tǒng),這會(huì)影響用戶體驗(yàn)彬祖。

具體做法是:

1.利用lua中 "lua_shared_dict"? 申請(qǐng)共享內(nèi)存空間茁瘦,這個(gè)內(nèi)存空間能被nginx(tengine)所有子進(jìn)程讀取储笑;

2.構(gòu)造API甜熔,讓其通過調(diào)用進(jìn)行修改共享內(nèi)存空間的值 ;

3.利用 proxy_pass 可使用變量特性及l(fā)ua指令 "set_by_lua" 動(dòng)態(tài)修改當(dāng)前proxy的值達(dá)到動(dòng)態(tài)效果。


簡(jiǎn)單代碼例子

1.申請(qǐng)共享內(nèi)存塊dyproxy

lua_shared_dict dyproxy 3m;

2.制造修改功能api突倍,host為key纺非,rip為后端ip

location ~ ^/DYPROXYSET {

default_type 'text/plain';

content_by_lua '

local dip = ngx.shared.dyproxy

local uri_args = ngx.req.get_uri_args()

if? uri_args["method"] == "add" then

if uri_args["domain"] == nil then

ngx.say("domain is null")

elseif uri_args["rip"] == nil? then

ngx.say("rip is null")

else

dip:set(uri_args["domain"],uri_args["rip"]) //設(shè)置domain:rip ,eg: xx.pcauto.com.cn:192.168.10.1|192.168.10.2

ngx.say("Set successfully : domain"..uri_args["domain"].."|rip"..uri_args["rip"])

end

elseif? uri_args["method"] == "del" then

if uri_args["domain"] == nil then

ngx.say("domain is null")

else

dip:delete(uri_args["domain"])

ngx.say("del successfully")

end

end

';

}

3.使用共享內(nèi)存的值達(dá)到動(dòng)態(tài)變量的效果

location ~ ^/testdyproxy {

default_type 'text/plain';

set_by_lua_file $dybackend conf/dyproxy.lua;

proxy_pass? ? ? ? http://$dybackend;

proxy_redirect? ? off;

proxy_set_header? Host? ? ? ? ? ? $host;

proxy_set_header? X-Real-IP? ? ? ? $remote_addr;

proxy_set_header? X-Forwarded-For? $proxy_add_x_forwarded_for;

proxy_connect_timeout 3;

proxy_read_timeout 10;

}

dyproxy.lua:

math.randomseed(tostring(os.time()):reverse():sub(1, 6))

local dip = ngx.shared.dyproxy

backend =? dip:get(ngx.var.host)

if backend == nil then

return "192.168.10.208:80"

end

local backendarr = loadstring("return "..ngx.unescape_uri(backend))()

local fm = 10000

nowindex = math.fmod(fm , table.getn(backendarr)) + 1

return backendarr[nowindex]? //nowindex簡(jiǎn)單隨機(jī)拿出其中一個(gè)后端ip

經(jīng)常使用nginx(tengine)的朋友可能注意到這里有兩個(gè)問題赘方;就是在后端發(fā)生異常情況的時(shí)候,后端節(jié)點(diǎn)的摘除和共享內(nèi)存的持久化問題弱左。

這個(gè)兩個(gè)問題點(diǎn)需要存在兩個(gè)東西窄陡,服務(wù)健康監(jiān)控系統(tǒng)和服務(wù)節(jié)點(diǎn)信息管理系統(tǒng)。

服務(wù)健康健康系統(tǒng):大家業(yè)務(wù)各有不同拆火,根據(jù)情況定造跳夭。

服務(wù)節(jié)點(diǎn)信息管理系統(tǒng):主要是維護(hù)服務(wù)注冊(cè)信息,我們現(xiàn)在lua 內(nèi)存共享變量是不另外做持久化處理们镜,只是在nginx(tengine)的重啟腳本里面加入調(diào)用服務(wù)節(jié)點(diǎn)信息系統(tǒng)步驟币叹,在nginx(tengine)重啟完后,進(jìn)行自動(dòng)調(diào)用服務(wù)節(jié)點(diǎn)信息管理系統(tǒng)獲取信息并寫入共享內(nèi)存中模狭。

總結(jié):經(jīng)過這樣改造颈抚,達(dá)到不需要reload restart nginx(tengine)情況下,進(jìn)行服務(wù)的擴(kuò)容和縮容嚼鹉。

-----------------------------------------


-----------------------------------------

以下內(nèi)容是摘自網(wǎng)上同行統(tǒng)計(jì)其它公司或開源模塊實(shí)現(xiàn)的動(dòng)態(tài)后端介紹:

1. nginx + upsync 模塊

這個(gè)方案在沙箱試了很久都沒有贩汉,功能上沒有任何問題驱富。但是在線上系統(tǒng)并發(fā)超過50k的情況下, reload nginx后幾分鐘會(huì)出現(xiàn)頁面無法訪問,靜態(tài)頁面的請(qǐng)求都變成下載了匹舞,最后導(dǎo)致整個(gè)應(yīng)用crash. 這個(gè)應(yīng)該是upsync的bug導(dǎo)致http response content type類型改變了褐鸥。沒有upsync開發(fā)者的幫助這個(gè)問題很難解決。

2. 右拍云的slardar

slardar 是基于nginx 1.9.5 然后集成了又拍云自己開發(fā)的一些lua module,還有春哥的balancer.lua 新模塊 并且結(jié)合consul k/v 實(shí)現(xiàn)了upstream動(dòng)態(tài)更新

slardar可以通過動(dòng)態(tài)更新consul的k/v存儲(chǔ)來添加upstream,添加lua script, 非常靈活赐稽。 不過這個(gè)需要對(duì)nginx的開發(fā)流程非常了解叫榕,并且熟悉nginx lua代碼

github上 https://github.com/upyun/slardar 目前還沒有人提issue和pr,估計(jì)只有又拍云自己在用了,目前來說通用性不好(雖然這個(gè)技術(shù)架構(gòu)和我們的架構(gòu)非常契合)

3. tengine + ngx_http_dyups_module

github 上 https://github.com/yzprofile/ngx_http_dyups_module 這個(gè)模塊已經(jīng)開源很久el并且merge到了tengine里姊舵,說明這個(gè)模塊已經(jīng)相當(dāng)成熟了, 這個(gè)模塊都是C編寫的效率肯定是超過用lua實(shí)現(xiàn)的

* ngx_http_dyups_module 提供了可以操作upstream的http restful api, 管理upstream變得非常容易

* 線上系統(tǒng)之前使用的nginx就是tengine, 所以使用這個(gè)方案會(huì)更容易一些晰绎,只需重新編譯并加一個(gè)dyups模塊,原來的配置無需改動(dòng)

* 現(xiàn)在線上系統(tǒng)的nginx是通過健康監(jiān)測(cè)模塊主動(dòng)check服務(wù)的端口號(hào)在不在蠢莺,這個(gè)檢測(cè)時(shí)有時(shí)間間隔的寒匙,線上的配置是

check interval=2000 rise=2 fall=3 timeout=1000;

這個(gè)健康監(jiān)測(cè)連續(xù)失敗3次nginx才會(huì)認(rèn)為后端實(shí)例不可用,即6s后躏将,nginx才會(huì)把一個(gè)有問題的實(shí)例屏蔽掉锄弱。通過consul service自己的健康監(jiān)測(cè)不需要這么長(zhǎng)的時(shí)間,幾乎是近實(shí)時(shí)的祸憋,dyups可以很快的拿掉有問題的實(shí)例会宪,影響小了很多。

4. consul nginx template

*consul template定義nginx配置文件模版蚯窥,從consul上讀取server信息(ip + port)掸鹅,然后更新nginx,并reload nginx. 這些都是consul幫助實(shí)現(xiàn)的,不過還是有reload操作拦赠。


更多文章巍沙,請(qǐng)關(guān)注微信訂閱號(hào):輕量運(yùn)維

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市荷鼠,隨后出現(xiàn)的幾起案子句携,更是在濱河造成了極大的恐慌,老刑警劉巖允乐,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件矮嫉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡牍疏,警方通過查閱死者的電腦和手機(jī)蠢笋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鳞陨,“玉大人昨寞,你說我怎么就攤上這事。” “怎么了编矾?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵熟史,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我窄俏,道長(zhǎng)蹂匹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任凹蜈,我火速辦了婚禮限寞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仰坦。我一直安慰自己履植,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布悄晃。 她就那樣靜靜地躺著玫霎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪妈橄。 梳的紋絲不亂的頭發(fā)上庶近,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音眷蚓,去河邊找鬼鼻种。 笑死,一個(gè)胖子當(dāng)著我的面吹牛沙热,可吹牛的內(nèi)容都是我干的叉钥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼篙贸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼投队!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起爵川,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤敷鸦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后雁芙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡钞螟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年兔甘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳞滨。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡洞焙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澡匪,我是刑警寧澤熔任,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站唁情,受9級(jí)特大地震影響疑苔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甸鸟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一惦费、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抢韭,春花似錦薪贫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鳍贾,卻和暖如春鞍匾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背贾漏。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工候学, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人纵散。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓梳码,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親伍掀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掰茶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容