以前無論在nokia還是tencent都是做移動用戶端開發,那時候也都是用編譯型的c++語言。但是來到baidu後做的卻是後台開發,此時所用所要關注的都是以前不曾接觸過的,主要是各種伺服器指令碼和資料庫技術。當然:對這些技術的使用本身而言:網上N多文章,也很多相關的書。問題是:沒有幾本書可以把相互之間的關係解釋清楚,比如:webserver和php指令碼的關係;php底層實現;mysql底層實現等等。。這些都鮮有人去專門論述。而剛開始接觸這些的時候因為對底層實現不瞭解,我一直對一些內部機制很是困惑,總覺得有些地方是連貫不起來的,這逼著我不得不去瞭解一些原理性的東西,看源碼,看一些大牛的blog等等··· 接下來就把我的一些想法記錄於部落格,歡迎大家拍磚。
這一篇就說一下:web-server和指令碼還有資料庫的關係吧:
一般做web開發大家都習慣裝一個wamp後者lamp。就是web-server,php和mysql的集合。問題是:為什麼要裝一個web-server?按照原先寫c++的思維:我就有個c++的編譯器,然後就可以寫c++了啊,幹嗎還有裝一個web-server?? 再者:web-server是什麼東西?是伺服器還是什嗎?
自我理解:類似c++這樣的編譯型語言,在執行之前都是將源檔案整個都編譯好,其是一種編譯後執行的過程;而解釋性語言則是邊編譯邊執行的。那這就意味著:運行一個php指令碼(解釋性語言)時,必須要有一個解譯器在跑著。只有這樣才能做到邊解釋邊執行。
問題是:這個解譯器存在於哪裡?我們是不是直接在伺服器上裝一個然後啟動它呢?啟動之後怎麼處理呢?畢竟會有很多使用者同時過來執行同一個php指令碼。解譯器一個時刻只能解釋一個php指令碼,那其餘請求指令碼只能排隊,這顯然是不能接受的。好吧:為瞭解決這個問題,我們給解譯器增加點功能,讓其有個進程(線程)管理功能。從而每個指令碼請求都單獨建一個進程(線程)來處理,這樣就ok了。問題是:php解譯器僅僅是解譯器,並沒有增加這個功能。而伺服器上又是可能運行多種類型的指令碼的,我們不可能沒換一種就為一種指令碼再裝一個線程(進程)管理功能的應用程式。 於是本著抽取簡化的原則:人們設計了webserver。
首先:web-server是一個軟體。他一個功能就是:他負責載入指令碼解譯器並運行,並負責管理各個請求的線程(進程)。
具體一點:
①:web-server是模組化構建的,比如:php解譯器是其中的一個模組,web-server負責載入並執行它。當有php請求到來時:它會調用這個php解譯器模組去解釋執行請求對應的指令碼。
②:一旦一個php請求到來之後:web-server會為這個請求建立一個進程(線程)《說明:是進程還是線程取決於版本還有各種因素》。從而被請求的這個php指令碼就是運行在這個進程(線程)中的。運行完了則web-server會回收這個進程,要麼銷毀要麼放到進程緩衝池中。
所以總結來說:指令碼是運行在web-server中的,前者依賴於後者!!
那資料庫呢?因為我們可能在指令碼中請求了資料庫,這時候不可避免要和資料庫打交道。當在web-server一個進程中運行了php指令碼時:發現其要請求資料庫,這個時候其首先要串連資料庫,這就產生一個對資料庫的串連。而mysql本身也是一種服務,它並不依賴於web-server,可以說它是和web-server平級的東西。它有個模組負責監聽對它發起的各種串連。於是當php運行對它發起一個串連的時候:mysql監聽到了這個串連,一旦監聽到了則它會專門為這個串連建立一個線程來進行處理!處理完這個串連中的所有請求之後才會回收這個線程。
--------------------------------------------------------------------------------------------------------------------------
總體來說:
①:指令碼是依賴於web-server存在的,沒一個指令碼請求的處理線程都是web-server來建立的。
②:web-server和mysql是同層級的概念,都是一種服務。 而php指令碼則是依賴於web-server存在的,都無法建立自己的線程。
③:對mysql,要區分開 串連 和 線程 這兩個概念,也要區分開:串連 和 查表 這兩個概念。其實這些一說出來都很明白不同,但是不去細想的話總是磕磕絆絆。
----------------------------------------------------------------------------------------------------------------------------
那再說一下一個php請求,web-server是給它分配一個進程呢?還是一個線程呢?這個其實取決於版本以及你的選擇。老版本x系統下只有進程,沒有線程,所以那時候:都是用的進程。但是後來的新版本都是支援線程的,此時是不是就分配的線程呢?呵呵~這又牽扯一個問題:php是線程不安全的,如何解決下一篇文章再介紹吧。