前言:
Apache是一種開源的HTTP伺服器軟體,可以在大多數主流的計算機作業系統中運作(包括UNIX、Linux及Windows),再加上其支援多平台且具有良好的安全性被廣泛使用,随着網絡技術的普及和不斷發展,以及Web技術的不斷完善,Web服務已經成為網際網路上最重要的服務形式之一。
正文:
httpd:俗稱apache
httpd其實是一種高度子產品化設計的、通常由核心和各種子產品所組成
DSO:(Dynamic Shared Object)動态子產品對象或動态共享對象、用得着子產品就裝載子產品、用不着也可以不讓子產品被裝載。
httpd原理詳解
http:hypertext transport protocol 超文本傳輸協定
超文本:所謂的文本就是純ASCII碼的、遵循html(hypertext mark language 超文本标記語言)所研發的文本
httpr封包有兩種:請求封包和響應封包
http請求封包格式:
<method> <request-URL> <version>
<headers>
空白行
<entity-body>
http響應封包格式:
<version> <status> <reason-phrase>
<method>: 請求方法, 希望伺服器端執行的動作,如GET、HEAD、POST等
<request-url>: 請求的資源,可以是相對路徑,也是完整的URL
<version>:協定版本,格式HTTP/<major>.<minor>,如http/1.0、表明用1.0的版本
<headers>:HTTP首部、首部又可以分為三類、分别是為通用首部、請求首部和響應首部
<status>: 狀态碼,1xx,2xx,3xx,4xx,5xx這種就是狀态碼
<reason-phrase>:原因短語,數字狀态碼易讀資訊
<entity-body>: 主體部分、包含我們請求的内容
http是無狀态的、什麼是無狀态的呢、就是伺服器端并不知道兩次請求是同一台主機、他并不會記錄下來請求者的身份等相關資訊、一次請求的事務結束後即行斷開。
IP封包的傳送:
在網絡上傳送資料、資料全在本地被切割成IP封包、當以過路由裝置時還會再次切片成更小的IP封包、而在本地上分割成的是16位的長度、是以他的最大範圍在65535位元組、但是封包有首部長度、65535減去IP首部就是封包的有效載荷、是以要小于65535。
真正的封包在在網絡上傳輸時要經過路由裝置、路由或交換機、而這些路由裝置有實體層傳輸資料時有個一叫MTU的概念、即最大傳輸單元、而這個最大傳輸單元比較通行的是1500個位元組、還有更小的、當封包經過這些路由裝置時、65535的封包又被切片成N個1500位元組的分片封包、在沒有到達目标主機之前他們不會合并。
封包傳送協定:
在傳輸層能夠控制封包的格式的有兩個協定、TCP和UDP兩種、其中TCP是面向連接配接的協定、其中這個要在傳輸方和接收方建立一個虛連接配接、而UDP是無連接配接的協定。
而基于TCP連接配接有要三次握手四次斷開:
<a href="http://s3.51cto.com/wyfs02/M01/23/05/wKiom1MuokyD0xWTAAP3LrkFN2Q330.jpg" target="_blank"></a>
httpd子產品化工作方式:
httpd的常用子產品化工作類型、即MPM:
MPM 是什麼呢: Multipath processing Module 是多程序子產品、他的種類大緻有:prefork MPM、worker MPM、BeOS MPM、NetWare MPM、OS/2 MPM、WinNT MPM
MPM機制:(Multipath Processing Module)多道處理子產品、是httpd的一個特性、他不是一個子產品、是一種特性統稱、常用的子產品有prefork、worker、event。
prefork:
prefork表現為一個程序處理一個請求、他是基于select()這種事件分離器來工作的、而select()他的工作描述符最大不能超出1024個、那也就意味着perfork最大隻能同時接收1024個請求、而這個已經是理論上限了,web伺服器在工作時、他不是由web伺服器這個主程序直接響應使用者請求的、而是當使用者請求進來、主程序就會生成子程序進行響應、就是所謂的程序複制。
那什麼是程序複制:
核心為了追蹤每個程序、在核心空間中有一個叫tack_struct的任務結構、為了追蹤程序把任務結構放在一個叫雙向連結清單中、而後給生成的子程序劃分記憶體、配置設定記憶體。
在功能上就是使用Apache的運作方式,一個父程序,然後根據設定以及連接配接情況生成相應的子程序數。這種模式可靠性和健壯性都是最好的。但是在性能上,開銷過大。達不到我們這些“吸血鬼”的要求了,如果連接配接數過多的話,會導緻我們無法遠端登陸,一定要等到連接配接數下降後才能連接配接,這也是最讓我頭痛的事情。
特性:快,因為它每個子程序沒有管理多個子線程的負擔、穩定,因為某個請求出問題,不會影響到其他程序,因為他們擁有獨立的位址空間,變量和記憶體、可用于非線程安全的第三方子產品,比如可以使用非線程安全的mod_php子產品,但在大量并發的情況下,會迅速大量消耗資源。
worker:
混合線程/程序的MPM。一個父程序,後面是帶有線程的子程序。每個子程序的線程數是固定且相同的。這是最“平庸”的一個模式,但也是使用人最多的一種模式。因為它性能等各方面比較均衡。性能上要比prefork好一些,隻是犧牲了一點點的健壯性和可靠性而已。一般推薦使用這個選項。
worker表現為一個程序生成多個線程、一個線程響應一個請求
event:
真正意義上的一個線程響應多個請求、而且要基于事件驅動(event-driven)事件驅動、主要目的在于實作單線程響應多個請求、event 在程序和線程的模式上和worker一樣,差別在于線程隻負責處理請求本身,當請求處理完該線程立即可以回收,http的連接配接管理交給父程序。worker模式的時候,如果該http連接配接的keepalive設定的比較長的話,即使該請求已經處理完,也不能回收,因為http連接配接沒中斷,這樣就需要維持更多的線程。
httpd的常用的功能特性:
支援路徑别名:alias
支援使用者認證:基本認證和摘要認證authentication
支援虛拟主機:virtual host 在一個實體主機上提供多個站點的
支援負載均衡:是反向代理的一個子特性
支援使用者站點:目前使用者都可以在自己的家目錄下建立自己的站點
支援CGI:Common Gateway Interface、通用網官接口
編譯安裝HTTPD 2.4.9版本
服務腳本:/etc/rc.d/init.d/httpd
腳本配置檔案路徑:/etc/sysconfig/httpd
運作目錄:/etc/httpd
配置檔案:
主配置:/etc/httpd/conf/httpd.conf
擴充配置:/etc/httpd/conf.d/*.conf
監聽的Socket: tcp的80, 443是https/tcp的監聽端口
在核心中使用小于1023的端口的隻有管理者
文檔根目錄:/var/www/html
CGI目錄:/var/www/cgi-bin/
依賴于更高版本的apr和apr-util。apr全稱為apache portable runtime(apache運作時移植工具)、是讓apache跨平台的工具、是個底層庫。
<a href="http://s3.51cto.com/wyfs02/M00/23/05/wKiom1MungKDlWBbAAEtNSILUU0710.jpg" target="_blank"></a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<code>(1) 解決依賴關系</code>
<code> </code><code>prel相容的正規表達式庫</code>
<code> </code><code># yum -y install pcre-devel</code>
<code> </code><code># yum -y groupinstall "Server Platform Development"</code>
<code> </code><code># yum -y groupinstall "Development tools"</code>
<code>(2) 編譯安裝apr-1.5.0</code>
<code> </code><code># tar xf apr-1.5.0.tar.bz2</code>
<code> </code><code># cd apr-1.5.0</code>
<code> </code><code># ./configure --prefix=/usr/local/apr</code>
<code> </code><code># make && make install</code>
<code>(3) 編譯安裝apr-util-1.5.3</code>
<code> </code><code># tar xf apr-util-1.5.3.tar.bz2</code>
<code> </code><code># cd apr-util-1.5.3</code>
<code> </code><code># ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr/</code>
<code>(4) httpd編譯安裝</code>
<code> </code><code># tar xf httpd-2.4.9.tar.bz2</code>
<code> </code><code># cd httpd-2.4.9</code>
<code> </code><code># ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd24 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ --enable-modules=most --enable-mpms-shared=all --with-mpm=event</code>
<code>--prefix=</code><code>/usr/local/apache</code><code>:指定安裝路徑、不使用預設路徑</code>
<code>--sysconfdir=</code><code>/etc/httpd24</code><code>:指定配置檔案的路徑、24表示版本、為了不跟我本機上的2.2的重複</code>
<code>--</code><code>enable</code><code>-so:表示基于DSO動态加載子產品的</code>
<code>--</code><code>enable</code><code>-ssl:這項是支援https協定的</code>
<code>--</code><code>enable</code><code>-cgi:支援CGI機制的</code>
<code>--</code><code>enable</code><code>-rewrite:支援URL重寫的</code>
<code>--with-zlib:zlib是一個網絡上發送資料封包時的一個通用壓縮庫的API</code>
<code>--with-pcre:通常支援Perl所用到的一個庫</code>
<code>--with-apr=</code><code>/usr/local/apr</code><code>:指定新的apr的路徑</code>
<code>--with-apr-util=</code><code>/usr/local/apr-util/</code><code>:指定新的apr-util的路徑</code>
<code>--</code><code>enable</code><code>-modules=most:most表示啟用大多數常用的子產品</code>
<code>--</code><code>enable</code><code>-mpms-shared=all:所有的MPM子產品都編譯</code>
<code>--with-mpm=event:明确指定啟用event子產品</code>
後續的配置:
1) 導出頭檔案
# ln -sv /usr/local/apache/include /usr/include/httpd
2) 導出庫檔案
沒生成就不用導出了
3) 導出man手冊
# vim /etc/man.config
MANPATH /usr/local/apache/man
4) 輸出二進制程式
# vim /etc/profile.d/httpd.sh
export PATH=/usr/local/apache/bin:$PATH
安裝配置好之後我們檢視一下剛安裝好的HTTPD版本:
# httpd -v
<a href="http://s3.51cto.com/wyfs02/M01/23/05/wKiom1MunhjxQaQ4AACgdp-sLKc392.jpg" target="_blank"></a>
最後可以啟動了、再檢視一下端口是否在監聽狀态了、當然你還可以給他提供一個服務腳本:
# apachectl start
# ss -tnl
====================================分隔線==============================================
I/O中的幾個基本概念:
阻塞:當一個程序發起I/O調用時、如果被調用的那個I/O沒有完成、意味着目前程序要轉為睡眠狀态、或者說被挂起、不能執行其他指令
非阻塞:當程序發起I/O調用時,如果被調用的I/O沒有完成,他不會阻塞目前程序、而是立即傳回一個未完成的結果給用戶端、叫忙等待。
同步:程序發起一個過程(或者功能、函數)調用後、在沒得到結果之前、該調用不會傳回。
異步:程序發起一個過程調用後、即使調用者不能立即得到結果、但調用卻會傳回,傳回是未完成的狀态、當調用完成後、核心會自行通知調用者、告訴結果已經OK了。
I/O模型有五種:
1、同步阻塞:一次I/O大概分兩個階段:一是等待資料從磁盤到核心記憶體、二是等待資料從核心記憶體中複制資料到程序記憶體、當我們的調用者(程序)發起調用請求之後、我們的資料在傳回之前調用者不能去幹别的事、隻能在等着、程序一旦發起調用、資料從磁盤到核心記憶體這段時間、程序是在等着、被阻塞了、同樣的、資料從核心記憶體到程序記憶體還得等着、是以這兩個階段都在阻塞狀态。是以一個程序隻能接收一個請求、因為他被阻塞了。
2、同步非阻塞:當一個使用者請求進來時、他請求一個web資源、這個資源在磁盤上、同樣的要發起核心調用、是以第一在資料沒有傳回之前、核心不會傳回程序的調用請求、而程序一次一次的過來問好了沒、核心就是沒有傳回、當核心資料準備好了後把資料複制到程序記憶體時、其實這步也是阻塞。
3、I/O複用:在核心中提供一個獨特的I/O子產品、他可以跟核心打交道、同時他能幫助程序監測核心中某一調用是否完成了、而不用程序自己去問核心了、是以、在某個I/O結束之前、這個獨特的I/O子產品是不會傳回的、而我們的程序隻跟這個獨特的I/O子產品打交道就可以了、調用時直接向這個獨特I/O子產品調用就可以了、而不用向核心發起調用了、這個I/O子產品可以同時監測多個I/O完成情況、而不是一次隻能監控一個了
4、異步:當一個程序發起I/O調用時、程序不會在等待、而核心接收到I/O調用時、就會去磁盤加載資料、當資料加載到核心記憶體時、核心會自己把資料複制到程序記憶體、當這兩步都完成了之後核心就會發一個信号給程序、告訴程序說請求的資料已經放到程序記憶體中了、你自己想怎麼用就怎麼用吧。這才是真正的異步。
5、什麼叫信号驅動:當一個程序發起I/O調用時、資料要從磁盤到核心、此為第一階段、當資料到核心時、核心要把資料複制到程序核心、此為第二階段、而當資料從磁盤到核心記憶體時、核心發向程序發出一個信号、告訴程序說資料已經準備好了、這種發信号的機制叫信号驅動、但是資料還沒有到程序記憶體、這時程序一樣是在阻塞、等待資料從核心記憶體中複制到程序記憶體。
如果隻通知一次的叫邊緣觸發
如果第一次發信号程序沒有響應、第二次信号發程序還是沒有響應....這種叫水準觸發
如果說當資料加載到核心記憶體時、不把資料複制到程序記憶體了、叫程序直接去核心記憶體去拿資料、這是不是省了複制資料到程序記憶體這步了、那這種機制叫記憶體映射(mmap)。
結束:
歸納總結了一些HTTPD的常用的概念以及一些特性、好像有點亂、但感覺還是總結得比較詳細的、希望大神不要吐槽哦、多多指點、這裡還沒完、下篇将介紹對httpd配置檔案的詳細.....感謝關注!
本文轉自 wei0164 51CTO部落格,原文連結:http://blog.51cto.com/tanxw/1381806,如需轉載請自行聯系原作者