互聯網技術產品及架構 - 3.2 互聯網大併發處理技術產品Nginx

版權所有,轉載請註明出處 http://soartju.iteye.com/blog/1850031

作者:高飛(Kao.field,Soartju)

 

三、互聯網主要技術產品介紹

3.2互聯網大併發處理技術產品-Nginx

3.2.1 Nginx是啥、能做啥、爲什麼用它

首先來說說大併發的問題,當然這是個系統性問題,需要應用服務器、數據庫、緩存等等方面統一配合才能支持大併發,不過爲了簡單,我們現在就假設數據庫沒瓶頸、IO沒瓶頸。

我們都知道,一臺web服務器(tomcatresin等),它能處理的併發請求量肯定是有個上線的,超了這個量,你就算把服務器咋了,它也頂不住。開多個實例?我靠別擡槓,說的就是單臺,開再多實例,那也是有個承受上線的。

好吧,單臺有個封頂上線,要是訪問量很大,併發很多,怎麼辦?這就引出了我們的一個互聯網技術產品-NginxNginx是個什麼東西呢,簡單的說,他就是個代理,他可以同時代理多臺代碼邏輯完全一樣的web服務器,請求來了(訪問個url地址就會發請求哈), 他先接收然後找到後面的真正web服務器來處理。本來請求是發給單個web服務器的,現在都發到nginx了,然後它在分發到後面的多臺web服務器。假如nginx代理了3web服務器,那現在的併發處理能力就是原來單個web服務器的三倍(3web性能一樣的情況)。這裏有兩個問題,一是web服務器爲啥要一樣?是啊,不一樣其實也ok,不過對於同一個請求,你要是都只有一臺服務器提供服務器,那性能是沒什麼提升的,要是多臺一樣的提供服務,就可以分配給多臺承擔壓力了。二是,nginx是怎麼找到後臺的真正web服務器,並讓他們之間均等的?這個問題呢,就是nginx的實現了,nginx提供了輪詢的方式(還有其他方式了),這種方式最常見,能保證後面的web服務器被均勻的訪問到,這個通過配置nginx就可以實現了。

有些朋友可能會問,nginx沒有瓶頸嗎?能代理無限個web服務器?好問題,nginx也有瓶頸,但是代理4-5web服務器還是比較很輕鬆的,單臺nginx的瓶頸問題,還有其他方式解決,這裏只給個概念,就先不擴展了,DNS輪詢、LVS都能將請求分發到多個nginx上。

 

3.2.2 Session共享、用戶識別跟蹤

我在剛接觸nginx時,有個最讓我費解的問題,就是nginx代理的web服務器, 他們之間的session是怎麼共享的?本來單機的時候,之間用session就行了,這好多臺web服務器,每臺web服務器上都有各自的session,完全不一樣啊,那不是亂套了?(session是通過cookie中的seesionid識別的,不同的web服務器分配的sessionid不同,那到不同的web服務器上也就沒法拿到其它服務器的session了,而且session也不在一臺web服務器上,怎麼共享?不瞭解session原理的同學先去找找資料哈),怎麼做的呢?

我當時也是找了一堆資料,什麼memcache共享session啊,no session啊,看的那叫雲裏霧裏。現在反過來看,人家說的還真對,不過我是感覺把簡單問題說複雜了,還搞了一堆名詞,顯着那麼高深。其實不管是memcache共享還是no session,就是讓web服務器在用戶的cookie裏,記錄一個唯一標識,通過這個唯一標識,所有的web服務器都可以拿到用戶的其他信息。這裏一定要記得,所有web服務器是一樣的代碼,所以彼此之間生成的唯一標識規則是一樣的,也就都能夠識別這個唯一標識,有了唯一標識,那就想做啥做啥了,你想查用戶的任何信息,那都ok了。什麼?你的session中還存了除了用戶信息以外的其他信息?哥們,那你就得改了,把用戶信息和他的其他信息綁定(怎麼綁定?靠,userid+綁定信息id唄),存到一個全局唯一的地方,就可以訪問到了。再或者,直接把session信息保存到全局唯一的緩存中,如memcache,通過sessionId這個唯一標識,每次去memcache中獲取session信息。不過session能不能序列化,是個大問題,您還是改程序結構吧。

具體的說,就是所有web服務器都是一樣的,當用戶登陸後,往用戶的cookie中記錄一段標識用戶的信息,如userinfo = 加密1useridnicknameemailage),當後繼用戶有請求過來時,web服務器通過獲取用戶cookie中的userinfo,再用解密算法拿到明文的userid等信息,拿到userid後,你就可以識別用戶了,要麼到數據庫裏去查用戶信息,要麼從已經緩存的memcache中查找用戶信息。OKsession共享的問題就這樣解決了,其實session共享,就是爲了解決不同服務器間,識別用戶和數據共享的問題,放在一個全局唯一的地方,如數據庫、memcache緩存中就可以了。

 

3.2.3 URL重定向及頁面靜態化

均衡的問題、共享的問題解決了,還有一個比較常用的技術就是頁面靜態化。想當年,當我第一次聽說這個名詞的時候,那叫一個神奇啊,居然還能把一個動態頁面(jsp之類的),弄成一個靜態html頁面,對說這話的人(忘了誰了)那也是無比的敬仰啊。後來當我用了之後,才發現,嗨,用的就是人家的現有技術產品,只是用了一下下而已,沒那麼深奧。

好了,回到正題,首先來說說,爲什麼要用頁面靜態化?我們在訪問網站時,經常會有一些頁面,更新少,但是讀的多,或者沒有必要馬上訪問到最新的變動數據,尤其是新聞文章頁面、blog文章頁面等等,基本上很少去更新的,既然是這樣,每次要是都動態請求web服務器,佔用服務器的計算,那就沒什麼必要了,尤其是當訪問量非常大時,如果都讓web服務器動態計算,別說web服務器,每次從數據庫訪問數據都能讓數據庫秒掛。所以就出來這麼個概念,對於讀多寫少的頁面,就可以把整個頁面緩存成靜態html文件,直接訪問html頁面就行了,而不需要再跑到web服務器上去動態生成頁面。

那這就涉及到一個問題,本來是個jsp頁面或者其他的動態頁面, 用戶每次訪問的是.jsp結尾的url,如果緩存成html,怎麼讓用戶再去訪問那個html呢?嘿嘿,nginx已經設計好了,既可以滿足讓用戶始終訪問同一個url,又可以滿足緩存需求和動態生成頁面需求。如何做到的?舉個例子就全明白了。

首先,Nginx提供了url重定向的功能,你就把它想象成你訪問的地址是urlA,但是nginx會把它轉換成urlBurlA呢是用戶訪問nginx時的url,但是nginx訪問webserver時就變成了urlB,用戶只能看到urlA,但看不到urlBurlB只對nginx可見。好暈啊,沒事,我們拿例子說話。

假如我們現在訪問一篇新聞,如果是原來的動態頁面方式,訪問web服務器時url可能是這樣的:http://192.168.1.1/getArticle.jsp?articleId=123,注意其中的參數articleId=123。用了nginx就不一樣了,我們就可以在nginx上配置一個虛擬的urlhttp://kao.field.com/Article/123.html,通過配置,nginx可以識別出此url最後的參數123123.html中的123哦,url前綴格式自己定義,能識別出來是訪問文章頁就行了),然後重定向到後端web服務器上真正的url,也就是上面的url地址http://192.168.1.1/getArticle.jsp?articleId=123。因爲只有nginx對用戶可見,web服務器用戶是看不到的,所以用戶只能訪問http://kao.field.com/Article/123.html請求到達nginx後,nginx就會根據配置情況,拿到參數123,然後再去web服務器上請求對應的url地址http://192.168.1.1/getArticle.jsp?articleId=123nginx上的配置應該類似下面這樣:

 

rewrite "^/Article/(.*)\.html$" /getArticle.jsp?articleId=$1 break; 	//$1就是前面的(.*)

(還是上代碼直接)

 

因此訪問http://kao.field.com/Article/123.html靜態頁面,其實最終訪問的就是後端的http://192.168.1.1/getArticle.jsp?articleId=123動態頁面。 既然有了html頁面,nginx就可以針對http://kao.field.com/Article/123.html靜態頁面配置緩存時間了,你可以根據實際情況,緩存 2分鐘還是1小時之類的。對於新聞類文章,可能更新慢一點可以接受(也就是你改了文章,2分鐘後看到效果也ok),那緩存2分鐘就行了,那在2分鐘內,用戶看到的始終是上一次到web服務器上生成的動態頁面,過了兩分鐘,靜態頁面失效,請求會再次穿透nginx到後端的web服務器訪問jsp,重新動態生成頁面並緩存成html頁面,也就是說2分鐘內,是始終不會到web服務器的,2分鐘後靜態頁面失效,纔會再次來到web服務器,然後在緩存,周而復始。

至於nginx是怎麼把後端一個jsp,緩存成html的,這個不在我們話題內。反正呢,最後可以把jsp返回的內容,生成一個htmlnginx把這個html緩存到本地磁盤或者內存,當下次用戶在訪問這個html時,只要nginx上的html緩存還在,就直接返回這個html頁面,否則就到web服務器請求動態頁面,然後再把生成的動態頁面保存爲靜態html緩存起來。

有的朋友可能會問,那要是實時呢?方法很多,你去掉緩存就實時了,不過其他節點能不能提得住就是個問題了,需要引入其他一些技術手段才能保證整體系統都能扛得住,以後再聊。

 

3.2.4 小結

好了,經過第一個互聯網技術產品的引入,我們的web服務器集羣已經顯現了,服務能力已經是單機的N倍,主要的用戶跟蹤及Session共享問題已經解決,我們簡單畫下原型圖,以後的架構就在這上面逐漸擴展開來。



 

1 nginx+webserver集羣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章