前言
LAMP
LAMP(Linux-Apache-MySQL-PHP)網站架構是目前國際流行的Web架構,該架構包括:Linux作業系統,Apache網絡伺服器,MySQL資料庫,Perl、PHP或者Python程式設計語言,所有組成産品均是開源軟體,是國際上成熟的架構架構,很多流行的商業應用都是采取這個架構,和Java/J2EE架構相比,LAMP具有Web資源豐富、輕量、快速開發等特點,微軟的.NET架構相比,LAMP具有通用、跨平台、高性能、低價格的優勢,是以LAMP無論是性能、品質還是價格都是企業搭建網站的首選平台。
正文
L-Linux
Linux這個作業系統大家都再熟悉不過了、種類很多、版本也很多、各色各樣的什麼款的都有、看個人喜歡而選擇、這裡我們選用CentOS 6.5來說明問題。
A-Apache
apache是什麼玩意呢。
其實apache早期是美國的一個官方組織所研發的一款web伺服器、早期也就叫httpd、但是這個項目完成了之後、功能也很完善了、是以、大家都知道、一旦某個項目完成了之後就要解散組織了、那這些研發httpd的程式員就散發到各個軟體公司了、這些程式又都很喜歡這個軟體、不想讓自己的成果就這樣沒落了、httpd就像這些程式員的孩子一個、不想沒人管、于是他們就通過網絡互相組織起來維護這款web伺服器、一旦發現有漏洞、就打更新檔、需要新功能就開發、自發的組織起來、這就是早期的社群模型、是以在早期的httpd的基礎上給他打了很多的更新檔、使得這個伺服器的功能越來越強大、是以他們就把這個伺服器稱為充滿更新檔的伺服器(a pachey server)、後來、美國的武裝攻擊直升機叫apache、是以後來這個httpd伺服器就叫apache了。
自從apache出現之後、絕對是一個瘋狂的時期、出現後不久就迅速獲得了從們的青睐、因為他是開源軟體、被各家組織和公司所使用、可以到下面這個網站看看apache的市場占有比例。
http://www.netcraft.com
httpd其實是一種高度子產品化設計的、是以通常由核心和各種子產品所組成、這跟核心很相近、這個軟體也是由核心和各種外圍子產品組成的、核心可以了解為http的基本接收請求響應請求等、而子產品可以了解為:比如說一個使用者請求一個很大的頁面、那我們就想壓縮給客戶發送、那這個壓縮功能就是一個子產品、這種就是httpd的子產品分設計、他的子產品功能很多、這裡就不一一例舉了、而通常又稱為DSO(Dynamic Shared Object)模型、動态子產品對象或動态共享對象、用得着子產品就裝載子產品、即使編譯了用不着也可以不讓子產品被裝載。
httpd還有一個叫MP的機制(Multipath Processing Module)多道處理子產品、是httpd的一個特性、他不是一個子產品、是一種特性統稱、常用的子產品有:prefork、worker、event
prefork:叫預fork、他的工作機制是一個程序響應一個請求
worker:一個程序生成多個線程、一個線程響應一個請求
event:這是真正意義上的單線程響應多個請求、而且要基于事件驅動
M-mysql
一個關系型資料庫的基本結構到底是怎麼樣的呢:
1、在最底層表現為兩類檔案:一類叫資料檔案、使用者可能看到的是資料、但我們最終要存放到檔案中、另一類叫索引檔案、索引其實是表中資料的一部分、隻是把一某些字段抽取出來單獨做成一個檔案給他排好序、對查找資料有很大的提升、但寫性能降底了、這是在實體層面上實作的兩類檔案、這些個檔案也是存放在某個目錄當中的、對mysql而言、資料庫表現為單個目錄。
2、磁盤空間管理器:磁盤管理器是對資料檔案内部資料組織結構管理的工具、對資料來講、為了持久存儲、資料都在磁盤上、但是我們知道、任何程序操作資料都不能在磁盤中進行的、要在記憶體中進行的、向使用者傳回也是在記憶體中。
3、緩沖區管理器:是将磁盤中管理的資料緩存在記憶體中的、通常而言、記憶體都是小于磁盤的、記憶體空間可能是不夠我們的資料使用的、哪些資料需要清理、哪些資料需要寫入磁盤中去、這些都是緩沖區所要完成的工作。
4、存取方法接口:當我們從緩沖區中讀資料、寫資料、就得用到這個存取方法接口。
5、事務:所謂事務、就是一個事情一次或多次操作的組合、而一個事務的管理系統有可能支援事務、也可能不支援事務、所謂支援事務、就是他能夠把多個語句當做一個來管理、要麼同時執行、要麼同時不執行、如果一個關系型資料庫支援事務、那一定要滿足ACID(A:原子性C:一緻性I:隔離性D:持久性)的測試。
随機I/O對我們的機械式磁盤來講性能是非常差的、往磁盤裡寫資料、順序I/O是最快的、所謂順序I/O就是在磁盤中找一段連續的空間、當磁盤尋道完成以後、連續完成寫操作、這就叫順序I/O、那事務日志就是順序I/O的一種表現、我們通過事務日志将使用者存放的資料操作原封不動的直接寫到事務日志中去、當你的事務完成了就立即寫到磁盤上去、但放的不是磁盤資料檔案中、而是放到一個叫事務日志的檔案、叫事務日志。
在這個層面上、要完成事務的管理、就要有一個事務管理器了、其實早些年mysql不支援事務的、現在mysql的獨特結構有些存儲引擎支援了。
隔離:那如果一個使用者往某個表中修改資料時、其他的使用者是不能完成同一個表的操作的、那怎麼保證你在修改的時候别人不能改呢、是以事務管理器在依賴于鎖管理器、而對于鎖來講、還有一個叫粒度的概念、就要鎖多大範圍、比如操作一個使用者修改表中的某條資料、隻鎖定使用者修改的那條資料就可以了、其他的使用者都可以修改其實的資料、而在早先時鎖的時候是把整張表都鎖起來的、粒度很粗糙、這就意味着并發性很低。
假如說我們的事務剛好寫到日志中去、系統崩潰了、那資料隻在日志中有、在資料檔案中沒有、資料沒有那我們就認為這個資料是殘缺的、是以在開機時必須經把資料同步到資料檔案中去、而這個過程就叫恢資料複的過程、是以就要有一個恢複管理器了。
使用者完成資料庫操作靠的是sql(Struct Query Language結構化查詢語言)語句、這是一種程式設計語言、也是一個程式設計接口、或者說是一個指令接口、他定義了我們資料能夠接受一些類别的操作(DCL[Data Contorl Language 資料控制語言]\DDL[Data Defination Language 資料定義語言]\DML[Data Manipulation Language 資料操作語言])、而DDL就是用來建立表、索引等基本關系型資料庫的語句、如CREATE/ALTER/DROP、DML資料操作語言則是增删查改這類的語句INSERT/DELETE/SELECT/UPDATE、DCL資料控制語言則實作建立使用者、授權和權限收回的、/GRANT/REVOKE、以上的這些統統都是SQL的查詢引擎。
當這些語句寫入SQL時、需要有一個分析器來分析這些語句哪些是指令、哪些是參數、那分析完了之後就要執行了、那如果一個表中有多個索引、怎麼知道用哪個索引查詢效率最高、性能性優呢、這就要計劃一下了、得把所有可用的查詢計劃都查詢出來、用查詢計劃器來完成這個步驟、計劃結束之後從中選擇一個開銷最小的、然而開銷最小的也未必是最好的、那我們就得做一下優化了、就得用到一個優化器了、還有一個叫求解器、查詢的結果的。
當使用者并發多使用者請求時、mysql怎麼響應呢、mysql是單程序響應多使用者請求的、内部是靠線程來實作的、每一個使用者連接配接用一個線程來響應、他是單程序多線程模型的、當然、他的線程也是有上限的、mysql内部有一個叫線程池的概念、一個池子裡能裝的水是固定的了、那一個mysql的線程也是固定的、就要看你這個池的容量了、當你定義好這個線程池的大小時、就意味着你能夠接受多少個使用者并發的數量了、當然、這個池子的大小取決于系統資源的大小了、可以把他了解為中間鍵、是對連接配接管理的元件。
ODBC(Open DataBase Connectivity):開放資料庫互聯、這種元件是一種通用的非常底層的連接配接庫、這種庫使得你使用任何語言連接配接任何一種關系型資料庫都能夠通用。
32位的系統、32位的程式最大記憶體尋址能力是4G、但核心還要用去1G、是以單程序最大隻能運作3G、對于mysql來說最多隻能使用2.7G的記憶體、Intel公司早期的CPU産品的位址總線和位址寄存器的寬度為20位,即CPU的尋址能力為220=1048576位元組=1M位元組;286的位址總線和位址寄存器的寬度為24位,CPU的尋址能力為224=16M位元組;386及386以上的位址總線和位址寄存器的寬度為32位,CPU的尋址能力為232=4096M位元組=4G位元組。
在計算機内部資料在資料總線上傳遞的,每條傳輸線我們稱之為1位,各個傳輸線按序排列,他們之間是并行關系,位址總線也是一樣的,資料總線決定每次傳輸資料的大小,位址總線決定了cpu所能通路的最大記憶體空間的大小,控制總線反映了資料的狀态和傳輸方式,它是位址總線的擴充和補充。
<a href="http://s3.51cto.com/wyfs02/M00/23/36/wKiom1M1H9myi2kjAAGQ9fJgPuc857.jpg" target="_blank"></a>
P-php
一、PHP簡介
PHP是通用伺服器端腳本程式設計語言,其主要用于web開發以實作動态web頁面,它也是最早實作将腳本嵌入HTML源碼文檔中的伺服器端腳本語言之一。同時,php還提供了一個指令行接口,是以,其也可以在大多數系統上作為一個獨立的shell來使用。
Rasmus Lerdorf于1994年開始開發PHP,起初他是一組被Rasmus Lerdorf稱作個人首頁工具(Personal Home Page Tool) 的Perl腳本, 這些腳本可以用于顯示作者的履歷并記錄使用者對其網站的通路。後來,Rasmus Lerdorf使用C語言将這些Perl腳本重寫為CGI程式,還為其增加了運作Web forms的能力以及與資料庫互動的特性,并将其重命名為個人首頁面表單解析器(Personal Home Page/Forms Interpreter)或"PHP/FI"。此時,PHP/FI已經可以用于開發簡單的動态web程式了,這即是PHP 1.0。1995年6月,Rasmus Lerdorf把它的PHP釋出于comp.infosystems.www.authoring.cgi Usenet讨論組,從此PHP以開源的方式開始走進人們的視野并走進人們的生活。1997年,其2.0版本釋出。
1997年,兩名以色列程式員Zeev Suraski和Andi Gutmans重寫的PHP的分析器(parser)成為PHP發展到3.0的基礎,而且從此将PHP重命名為PHP: Hypertext Preprocessor。叫起文本預處理器。此後,這兩名程式員開始重寫整個PHP核心,并于1999年釋出了Zend Engine 1.0,這也意味着PHP 4.0的誕生。2004年7月,Zend Engine 2.0釋出,由此也将PHP帶入了PHP5時代。PHP5包含了許多重要的新特性,如增強的面向對象程式設計的支援、支援PDO(PHP Data Objects)擴充機制以及一系列對PHP性能的改進。是以PHP到5.0才算真正成熟起來、并且流行來。
二、PHP Zend Engine (PHP的引擎)
Zend Engine是開源的、PHP腳本語言的解釋器,它最早是由以色列理工學院(Technion)的學生Andi Gutmans和Zeev Suraski所開發,Zend也正是此二人名字的合稱。後來兩人聯合創立了Zend Technologies公司。
Zend Engine 1.0于1999年随PHP 4釋出,由C語言開發且經過高度優化,并能夠做為PHP的後端子產品使用。Zend Engine為PHP提供了記憶體和資源管理的功能以及其它的一些标準服務,其高性能、可靠性和可擴充性在促進PHP成為一種流行的語言方面發揮了重要作用。
Zend Engine的出現将PHP代碼的處理過程分成了兩個階段:首先是分析PHP代碼、把他做詞法分析、文法分析、語義分析等等并将其轉換為稱作Zend opcode的二進制格式(類似Java的位元組碼),雖然是個解析器、中間多了一個步驟就是編譯、他是個解析器、但能夠實作運作時編譯、先編譯再執行、他編譯的不一是個二進制程式、而是位元組碼程式。并将其存儲于記憶體中;第二階段是使用Zend Engine去執行這些轉換後的Opcode。
三、PHP的操作碼Opcode
Opcode是一種PHP腳本編譯後的中間語言,就像Java的ByteCode,或者.NET的MSL。PHP執行PHP腳本代碼一般會經過如下4個步驟(确切的來說,應該是PHP的語言引擎Zend):
1、Scanning(Lexing) —— 掃描 将PHP代碼轉換為語言片段(Tokens)
2、Parsing —— 分析 将Tokens轉換成簡單而有意義的表達式
3、Compilation —— 編譯 将表達式編譯成Opocdes
4、Execution —— 執行 順次執行Opcodes,每次一條,進而實作PHP腳本的功能
四、php的加速器
基于PHP的特殊擴充機制如opcode緩存擴充也可以将opcode緩存于php的共享記憶體中,進而可以讓同一段代碼的後續重複執行時跳過編譯階段以提高性能。由此也可以看出,這些加速器并非真正提高了opcode的運作速度,而僅是通過分析opcode後并将它們重新排列以達到快速執行的目的。
常見的加速器有:
APC(Alternative PHP Cahce)
eAccekerator
XCache
Zend Optimizer、Zend Guard Loader
NuSphere PhpExpress
PHP-5.3.3以上的版本才支援基于fastCGI運作于獨立主機上的版本
五、PHP源碼目錄結構
PHP的源碼在結構上非常清晰。其代碼根目錄中主要包含了一些說明檔案以及設計方案,并提供了如下子目錄:
1、build —— 顧名思義,這裡主要放置一些跟源碼編譯相關的檔案,比如開始建構之前的buildconf腳本及一些檢查環境的腳本等。
2、ext —— 官方的擴充目錄,包括了絕大多數PHP的函數的定義和實作,如array系列,pdo系列,spl系列等函數的實作。 個人開發的擴充在測試時也可以放到這個目錄,以友善測試等。
3、main —— 這裡存放的就是PHP最為核心的檔案了,是實作PHP的基礎設施,這裡和Zend引擎不一樣,Zend引擎主要實作語言最核心的語言運作環境。
4、Zend —— Zend引擎的實作目錄,比如腳本的詞法文法解析,opcode的執行以及擴充機制的實作等等。
5、pear —— PHP 擴充與應用倉庫,包含PEAR的核心檔案。
6、sapi —— 包含了各種伺服器抽象層的代碼,例如apache的mod_php,cgi,fastcgi以及fpm等等接口。
7、TSRM —— PHP的線程安全是建構在TSRM庫之上的,PHP實作中常見的*G宏通常是對TSRM的封裝,TSRM(Thread Safe Resource Manager)線程安全資料總管。
8、tests —— PHP的測試腳本集合,包含PHP各項功能的測試檔案。
9、win32 —— 這個目錄主要包括Windows平台相關的一些實作,比如sokcet的實作在Windows下和*Nix平台就不太一樣,同時也包括了Windows下編譯PHP相關的腳本。
A,M,P是怎麼關聯起來工作的呢:
php這個解析器本身不跟任何任務器資料庫打交道、需要打交道的是使用相關語言開發的應用程式、我們在應用程式中如果說實作了資料操作、如果說通過mysql來讀取或存儲資料的話才有可以用到mysql、否則是用不着的、所在并非有php就一定用到mysql。
apache + php結合的方式大概幾種:
第一種:把php編譯時直接編譯成apache的子產品、module子產品化的方式進行工作。
第二種:CGI、通用網關接口、apache基于CGI跟hph通信
第三種:fastcgi、他也是一種協定、在這種子產品下他們兩個是怎麼結合的
本來php是做為一個子產品或都是php解析器運作的、不是監聽在某個套接字上接收别人的請求的、而是讓别人調用為一個程序使用的、可能是做為别人的子程序在運作、但是工作在fastcgi這種子產品下的hph自行啟用為一個服務程序、他監聽在某個套接字上、随時可以接受來自用戶端的請求的、他也是有一個主程序的、為了可以響應多個使用者的請求、他會啟用多個子程序、這些子程序我們也可以稱為工作程序、他也是有空閑程序的、一但有客戶請求他馬上使用空閑的程序響應用戶端的請求、将結果傳回給前端的調用者、在php5.3.3版本之前他是沒有這個能力了、隻能工作在子產品和CGI的方式下、而在5.3.3之後這個子產品直接被收進php子產品中、這種子產品就叫php-fpm。
是以在以後編譯php時、要想跟apache結合、就要編譯成php-fpm、這是基于fastcgi工作的模式、并啟動這服務程序、也就意味着他是通過套接字跟前端的調用者通信、既然基于套按字通信了、那麼前端的web伺服器和後面的php伺服器完全可以工作在不同的主機上、實作了所謂的分層機制。
apache不會跟資料庫打交道、他是個靜态web伺服器、跟資料庫打交道的是應用程式、作為應用程式的源驅動能夠基于某個API跟伺服器之間建立會話、而後他會通過我們的mysql語句發送給資料庫、資料庫再将結果傳回給應用程式、不是php程序、而是php程序中所執行的代碼。
PHP跟mysql怎麼整合起來呢、php又怎麼被httpd所調用呢
首先httpd并不具備解析代碼的能力、他要依賴于php的解析器、接着php本身不依賴于mysql、他隻是一個解析器、能執行代碼就OK了、那他什麼時候用到mysql呢、如果要在mysql中存資料時才用到mysql、隻是當php中有運作mysql語句時才用到mysql。
php語言要想聯系mysql、通常用到php的驅動、rpm包的叫php_mysql、php跟mysql沒有一點關系、隻有程式員在php中編寫mysql語句時才連接配接mysql來執行sql語句的。
基于php-mysql去連接配接mysql隻使用一個函數mysql_connect();而mysql_connect()正是php-mysql提供的一個API、隻要指明要連接配接的伺服器即可。
結束:
以上都是LAMP的一些原理以及基礎、都是文字說明、很是枯燥無味、但我還是覺得整理出來并記錄下來會好點、等以後翻閱也友善點、下篇我們将來說說怎麼實作LAMP分主機關聯起來工作、LAMP也可以不分主機、可以放在同一台主機上也是可以工作的、這個完全沒有問題、不過當業務繁忙時一台主機伺服器恐怕是扛不住、是以要分主機實作。
本文轉自 wei0164 51CTO部落格,原文連結:http://blog.51cto.com/tanxw/1386048,如需轉載請自行聯系原作者