日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

从奥运订票系统说起——谈FastCGI 与IT 架构

發布時間:2023/11/27 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从奥运订票系统说起——谈FastCGI 与IT 架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2008年,對于首都人民來說,沒有什么比奧運會更大的事情了。如何買到一張稱心如意的比賽門票,也成了很多人的一個夢想。然而,在奧運官網搶票購買的時候,這個夢想卻輕易地被網上購票系統的當機擊成碎片,很多充滿熱情的老百姓們也因此郁悶無比。由于搜狐承擔了奧運的官網,我又在那里工作過相當長一段時間,很多兄弟搶票失敗,于是便認定是搜狐開發的系統太爛,而找我抱怨。其實當時我也很是郁悶:首先這個系統并非搜狐開發;其次我也不在搜狐了。雖然如此,和我同行的一些朋友,又開始問我如何解決類似問題。我也反反復復講了很多次,為了讓廣大讀者能夠深入了解背后的原因和機制,寫出來,大家一起討論可能效果會更好。當然,這并不是我說的架構就一定能解決問題,僅僅是拋磚引玉而已。

??? 在說架構之前,我先說一個老的技術,FastCGI。因為這個技術在后面的結構闡述中將起到非常重要的用處,原以為應該會有不少人會知道,但后來發現好像并非如此。

???關于FastCGI的歷史我就不再贅述,好像自1993年便有了。目前最熱門的視頻網站YouTube體系結構中,就有fast-cgi的模塊。它支持很多httpd服務器,在官方網站上列了很多,如apache,aXesW3 ,MicrosoftIIS,Zeus,近幾年才出的lighttpd沒寫,其實這個新的httpd也支持,但我個人覺得,支持最好的,可能還是Apache。

??? 先講講FastCGI的原理,它和現在常用的運行請求不同,維基百科上有一個術語形容它,這里借用一下:

◆? 短生存期應用程序

◆? 長生存期應用程序

??? CGI技術的機制是:每次當客戶請求一個CGI的時候,Web服務器就請求操作系統生成一個新的CGI進程;當CGI滿足要求后,服務器就殺死這個進程。并且服務器對客戶端的每個請求都要重復這樣的過程。

??? 而FastCGI技術的機制為:FastCGI程序一旦產生后,它可以持續工作,一直保持滿足客戶的請求直到自己被明確終止。如果你希望通過協同處理來提高程序的性能,你可以請求Web服務器運行多個FastCGI 應用程序。

??? 由此CGI就是所謂的短生存期應用程序,FastCGI就是所謂的長生存期應用程序。

??? 由于FastCGI程序并不需要不斷產生新進程,可以大大降低服務器的壓力。并且產生較高的應用效率。如今,流行的Java語言Servlet技術,在設計上就是參考FastCGI技術。

FastCGI 配置運行一般來說分三種,這三種都需要Apache的mod_fastcgi 進行處理。

1、Standalone FastCGI Server, 應該是獨立的服務器。首先是需要把fastcgi作為單獨的守護進程:

?

$ script/myapp_fastcgi.pl -l /tmp/myapp.socket -n 5

?

以下是這個fastcgi的守護進程的參數:

-d -daemon #作為守護進程

-p -pidfile #管理進程的PID寫入到到文件的名稱

-l -listen #SOCKET的路徑,機器名:端口, 或者端口

-n -nproc #起始接受請求的進程數

然后把下面的代碼加入Apache的HTTPD.CONF:

?

FastCgiExternalServer /tmp/myapp -socket /tmp/myapp.socket

Alias /myapp/ /tmp/myapp/

# Or,? 可以使用root的身份運行?????

Alias / /tmp/myapp/

# Optionally,(使用rewrite模塊)?????

RewriteRule ^/myapp$ myapp/ [R]

然后重啟Apache就OK了

?

2、Static mode:靜態模式, 一般是用于單一確定的模式,就是在Apache 的httpd.conf 中間加上:

?

FastCgiServer /usr/local/apache/count/count.fcg -processes 1

?

Alias /c /usr/local/apache/count/count.fcg

?

此處建議再使用REWRITE的方式 重寫整個的URL匹配, 使之看起來像一個靜態頁面。

?

RewriteRule read-(.+)-(.+)-(.+).html$ /c?id=$1&sid=$2&port=$3 [L]?

?

3、Dynamic mode:動態模式,可以使用各種各樣的fastcgi,加入到httpd.conf中間去,比如:

AddHandler fastcgi-script .fcgi

還有一個關鍵的設置:

?

<Directory /path/to/MyApp>

?????? Options +ExecCGI

</Directory>

?

?這個配置建議放在cgi-bin? 這種類似的目錄里面。

?? 請注意第二種,服務器起幾個進程,是由-processes 1 這個參數來控制的,所以起多少你可以自己來定,我們在下面的一個關鍵模塊中將使用這個模式。

?? 下面放一段FastCGI程序的C代碼,來說明一下:

?

#include <fcgi_stdio.h>

#include <string.h>

?

void main(void){

int count = 0;

while(FCGI_Accept() >= 0) {

printf("Content-type:text/html ");

printf(" ");

printf("<HTML> "

"<HEAD>?

"<TITLE>FastCGI</TITLE> "

"<META http-equiv="Content-Type" "

"content="text/html;?? charset=utf-8"> <body> "?"Hello world!<br> ");

printf("Request number %d.",count++);

printf("</body></html> ”);

}

exit(0);

}

?

這是一個很簡單的例子,就是簡單的計數, 大家可以注意這一句:while(FCGI_Accept() >= 0)

???這就是它和普通的短周期程序最大的不同,一般CGI都是運行完就退出了,這個FastCGI,在處理完一個請求完畢后,會回到初始狀態等待下一次請求;如果這個程序被設置成為只能啟動一個,那么無論是否訪問這個頁面,都是在前一個的基礎上加一,而不會又產生新的進程;從而后來者是從零開始。當然,很多人也都注意到,此處就是一個死循環在不斷處理;如果程序比較復雜,存在內存泄露的問題,此處產生的問題也要比普通CGI要嚴重得多,所以使用它對于程序員的要求也更高。

??? 上述方案應該是所有的Web應用解決方案中,執行效率和速度最高的。官方數據是說比一般的高15倍左右,在我的機器上測試,基本上每秒能夠處理大概2400次請求。

???再回到我們說的正題:奧運訂票系統的癱瘓,關于訪問量,當時的說法是800萬/小時,那么平均到每秒就是超過2200次。這對于訂票系統來說,確實是一個非常大的考驗。畢竟這種狀況下,數據庫是肯定承擔不住這個量級的訪問了。如何進行架構設計,是我們都需要面對的問題。

??? 如果設計要應對這種高負載、高訪問量的結構,首先考慮這個系統的需求。其實具體過程比較簡單:

1.用戶認證

2.查看所有可以訂票的項目和票的數量

3.選擇項目,放入購物車

4.確認并提交訂單

5.訂單成功扣款

過程雖然簡單,但其實里面的東西也不少。

???由于用戶的數據量很大,注冊用戶數百萬以上;而且這種系統,登錄用戶在操作時應該不存在普通應用的2/8原則。在搶票的當天,絕大部分注冊用戶都會登錄,而且時間會非常集中,所以并發會非常大。你如果預算充足,放一萬臺服務器來做這個事情,做一個分布算法,然后每臺服務不超過十萬個用戶,這樣你就能充分保證你的用戶感受和體驗。可我想實際上沒有哪個公司和系統會這么做,即使是財大氣粗的奧組委。

???這個時候,很多人可能會想:上面提到的FastCGI這種高效率的程序就是針對類似狀況的解決方案,其實這是很常見的錯誤。我想這個訂票之所以會癱瘓,就是由于部分設計過于高效,而部分不可能那么高效的緣故。比如登錄這個模塊的效率估計就非常高,因為登錄只是在數據庫對比一下用戶名和密碼,而且數據更新也不頻繁,完全可以用分布式數據庫來解決。但用戶登錄后,所有的壓力會全部壓在后面的功能上,從而造成系統的癱瘓。這個時候,由于人太多,你無論怎么高效,在執行到后面復雜的購買功能時,都會出現瓶頸。而如果真的放一萬臺服務,你的數據如何分布同步,然后真的做到先來先得,會很難,如果設計的不好,和抽簽也就沒什么兩樣了。

??? 所以這個系統設計的策略應該是:如何做到在保證用戶感受的情況下,合理控制進入系統的人數,這樣你后面的設計和開發的壓力會小的多,而且成本的控制非常清楚。

??? 那么剩下的做法就很清晰了:系統的重點是用戶登錄,而不是一般理解的后面購票提交的系統功能。如何控制進入的人數,我覺得不妨參考銀行的叫號方式來設計:系統先給用戶發號,然后當了解到有資源空出來時,再讓用戶登錄。

?

這個結構的重點就在呼號中心和序列號的分配上面。

1.?序列號分配中心,技術重點在于高效和唯一性。也就是說當用戶訪問數達到海量之后,你需要非常迅速地分配唯一的序列號給登錄的用戶。這種狀況下,其他很多技術無法承擔這種需求。開始提到的FastCGI,就是這個模式下的唯一選擇。我們在開始安裝的時候,就可以使用這種只起單個進程的模式,所以分配用戶的序列號只會是唯一的。由于FastCGI的高效率,從而保證登錄的用戶可以迅速分配到一個號,然后離開。當然如果你還不放心的話,還可以在前面再加一個負載均衡的設備,完成對幾個不同服務器負載分配,然后每個機器加不同的步長,并且起始數字不一樣。比如:如果你有2臺機器做發號工作,第一臺起始數字為1,第二臺為2,步長為二,就是每次累加2,這樣用戶在不同的機器上也會得到唯一的號,而效率就能提高兩倍。

???至于記錄用戶序列號的方式,可以用cookie記錄在客戶端,然后進行加密。用戶記錄后,進入呼號中心,比對手里的號和前面排隊的人數,然后提示用戶前面排隊人數。比方說,你上來就是排號在3千萬以后了,前面有2千多萬人,我想如果這個人頭腦正常的話,就不會說這個系統太爛,只能說自己起晚了,然后感嘆中國人實在是太多,就不會再上去反復不停地登錄。

2.?呼號中心,這里大概是最麻煩,也是最關鍵的地方。由于訂票系統是B/S結構,服務器端有動作的時候,如何通知客戶端是一個要點。也就是說,當有人訂票完畢,從系統中退出,此時,中控中心知道后,會通知呼號中心呼叫下一個。呼號中心如何找到應呼叫的號碼,有兩種解決方法,具體實現都不妨通過AJAX的局部刷新達成。

第一種,和叫號系統的號進行比對,如果發現匹配成功,就通知客戶端進入系統。

第二種,判斷這個用戶前面的排隊數量,如果發現為零,就觸發進入這個系統的動作。

???還要注意一點,就是刷新時間長短和叫號的失效問題。時間太短,服務器壓力會很大;時間太長又會容易造成這個用戶感覺沒有變化,從而感受很差。所以這個時間的設置,個人覺得在5-15秒之間調整會比較合適。然后壓力需要分攤,也就是叫號服務器需要設置多個。這樣的話,用戶刷新會命中不同的服務器,此時需要對數據的同步進行特殊處理,其架構如下:

??? 這個消息接受模塊可以有兩種模式取信息:短連接,每隔一段時間來傳遞信息;長連接,就是在消息接受和中控服務器中建立一個長效的消息通知機制。由于對于信息及時性的要求比較高,所以采用長連接比較合適。

???消息接受模塊和中控服務器之間需要進行序列號的交換。由于你不知道捏著這個號的用戶命中哪臺服務器,所以失效機制需要在幾個服務器上同時進行。也就是說,當一個用戶退出,中控服務器知道后,開始確認最后一個登錄號,然后發給所有前端,前端要能保證通知到用戶,然后向用戶發出通知,說明如果在給定次數內用戶還不進行登錄或者認證,就提示后端此號失效,系統再分配下一個號給前端進行通知,

??? 如果要設計得更加精巧,還可以建立前端服務器之間的消息通知機制。就是當一臺服務器發現這個號在自己上面,就通知幾個前端,不再對這個號進行判斷,盡量節約資源。

3.?中控服務器。我在開發社區和直播間的時候,都用到了這種方式,此處也用到了。不過在這個系統中,中控服務器不必使用單獨的物理服務器,這里可以只是一個模塊,它的主要用途是通知這些叫號服務器。由于數據很簡單,所以中控的分發比較容易,不用設計特別復雜的協議。

4.?認證中心:唯一需要改動的,就是判斷用戶的序列號是否可用并且是真正的號碼。

5.?購票中心:此處有很多種分布的方法,有很多可以借鑒的結構,這里就不贅述了。在這個架構中,購票唯一需要確認的就是可以同時承擔多少人同時在線購買

?

??? 前三個部分是這個架構的核心部分,由于進入的人數可以控制,后面的系統就還可以使用老的訂票系統,只用確認同時放進來多少人就可以,也就是窗口沒變,只是大家不再一擁而上,都是文明人,請排隊拿號。

當然后面的架構還可以重新進行優化和設計,從而盡可能提高放進來人的數量,在進行設計購票功能時還可以借鑒這方面的模式。比如:籃球是愛好觀眾比較多的運動,大家都想到現場看看科比同學的扣籃,進來人后,可能大家都會一擁而上先搶這個,從而造成局部的數據癱瘓,影響整個系統。此時也可以在里面暗含這個模塊。買票的人少,拿號看不出來,拿了就能進去;一旦人數到了極限,對不起,也請排隊。

??? 限制人員進入后,未進入的人和購買的人不在同一個系統中,從而不會妨礙進入的人,買的人也會很快解決,他們可以迅速完成訂單。提交后,系統發現這個人無法再訂其他球票的時候,就可以認為再放一個人進來,或者干脆做絕一點,馬上將其踢出去,以節約資源。

???而且,由于你可以控制進入的用戶數量,從而系統其他部分的設計簡單多了。多大的錢辦多少事,如果領導想快一點了事,預算充足,那么放入的人就多;如果心里面沒底,那么可以先放很少人進來,或者說大概估計一下,只放多少號,如就賣10萬張票,那么只放50萬個號,放完了就沒有了。用戶來晚了,連號都沒有,也只能慨嘆自己不夠及時,這樣比系統癱瘓要好得多。

??? 對于這個架構,其設計重點就是把系統整體的資源處于可控的狀態。很多類似系統,如:報名,考試,短時間搶購等等實際應用系統,都可以采用類似的方式解決。好的架構,并不是說能解決所有的問題,而是很清楚自己能做什么,不能做什么。


PHP的FastCGI

?PHP的FastCGI使你的所有php應用軟件通過mod_fastci運行,而不是mod_phpsusexec。FastCGI應用速度很快 是因為他們持久穩定。不必對每一個請求都啟動和初始化。這使得應用程序的開發成為可能,否則在CGI范例是不切實際的(例如一個大型的腳本,或者一個需要 連接單個或多個數據庫的應用)。


??? 1. FastCGI 像是一個常駐 (long-live) 型的 CGI,它可以一直執行著,只要激活后,不會每次都要花費時間去 fork 一次 (這是 CGI 最為人詬病的 fork-and-execute 模式)。

????2. FastCGI 可在任何平臺上使用,Netscape Enterprise 及 IIS 都有 FastCGI 的模塊可供使用,阿帕契 (Apache,以及利用 Apache 衍生出做的服務器) 上也有 mod_fastcgi 可用。

??? 3. FastCGI 支持 C/C++、Java、PHP、Python、Ruby、Perl,Tcl 等程序語言。

??? 4. FastCGI 的應用程序亦兼容于 CGI。即 FastCGI 的應用程序也可以當成 CGI 來執行。

??? 5. 現有的 CGI 程序要改寫成 FastCGI 非常簡單,最少可能只需要多加入三行程序代碼。

??? 6. FastCGI 的偵錯方式與 CGI 大同小異,只要帶入程序所需的環境變量及參數,即可在命令列模式執行或偵錯。

??? 7. FastCGI 應用程序的寫作方式與 CGI 類似,除了幾項原則要特別注意外,FastCGI 的寫作方式跟 CGI 幾乎一樣,與學習 Web Server API 比較起來, FastCGI 簡單多了。

??? 8. FastCGI 支授分布式運算 (distributed computing),即 FastCGI 程序可以在網站服務器以外的主機上執行并且接受來自其它網站服務器來的請求。

??? 好處


??? 1. PHP腳本運行速度更快(3到30倍)。PHP解釋程序被載入內存而不用每次需要時從存儲器讀取,極大的提升了依靠腳本運行的站點的性能。

??? 2. 需要使用更少的系統資源。由于服務器不用每次需要時都載入PHP解釋程序,你可以將站點的傳輸速度提升很高而不必增加cpu負擔。因為dll文件不再每次都載入了,那么數據庫的持久連接也將可以起到它設計初的效果。

??? 3. 不需要對現有的代碼作任何改變。


??? 潛在問題


??? 1. 對所有的子目錄(/home/USERNAME/public_html/php.ini)你只有一個可用的php.ini文件。這是優化網站代碼所必需的。如果你需要多個php.ini文件以適應不同的腳本需要,你可以在任何子目錄禁用PHP的快速CGI,而其余的地方則繼續有效。

??? 2. 你對PHP環境做的任何升級(如php.ini文件的改變)都有幾分鐘的延遲。這是因為為了更快的速度 你的php.ini文件已經被載入內存,而不是每次需要時再從存儲器重新讀取。


總結

以上是生活随笔為你收集整理的从奥运订票系统说起——谈FastCGI 与IT 架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。