您當(dāng)前所在位置:
首頁 →
服務(wù)器 →
WEB服務(wù)器 →
在Apache HTTPD中使用DSO(編譯)
在Apache HTTPD中使用DSO(編譯)
時間:2015-06-28 00:00:00
來源:IT貓撲網(wǎng)
作者:網(wǎng)管聯(lián)盟
我要評論(0)
- Apache HTTP 服務(wù)器是一個模塊化(或說積木式)的程序,管理員可以選擇一些模塊來增加服務(wù)器的某些功能。這些模塊,可以在創(chuàng)建服務(wù)器程序時靜態(tài)地編譯到httpd服務(wù)器的二進制代碼中,也可以編譯成一些獨立于服務(wù)器程序的Dynamic Shared Objects (DSOs)文件。DSO 文件可以在編譯服務(wù)器程序時創(chuàng)建,也可以在以后利用Apache擴展工具apxs來單獨創(chuàng)建。
這篇文檔,將描述如何使用DSO 模塊,以及其背后的原理。
實現(xiàn)
Apache HTTPD對DSO 的支持,即對單個模塊的動態(tài)加載,是基于一個叫mod_so的模塊來實現(xiàn)的,此時mod_so必須被靜態(tài)地編譯到HTTP服務(wù)器內(nèi)核中。這是除了core以外唯一不能以dso方式編譯的模塊。實際操作時,其它的Apache模塊可以在編譯服務(wù)器程序時通過單獨指定來將其編譯為DSO文件,正如安裝文檔中講述的,此時configure的設(shè)置參數(shù)應(yīng)為--enable-xxxx=shared(xxxx為模塊的名字,如rewrite等)。 當(dāng)一個模塊被編譯為一個名為mod_foo.so的DSO文件后,就可以在httpd.conf文件中用mod_so的LoadModule命令,告訴服務(wù)器在啟動或重新啟動時將此模塊加載。
為了簡化創(chuàng)建Apache模塊(尤其是第三方模塊)的DSO文件的過程,apache提供了一個新工具名叫apxs(APache eXtenSion)。它可以脫離apache的源碼將模塊編譯成DSO文件。它的實現(xiàn)思路非常簡單: 在安裝Apache時,configure腳本的 make install 過程會安裝Apache的C頭文件,并在apxs程序(apxs是一個perl腳本)中對依賴于具體平臺的編譯器和連接器設(shè)置一些標(biāo)志(Flag),以供創(chuàng)建DSO文件。通過這種方式,用戶就可以利用apxs在沒有Apache源碼樹且無需針對當(dāng)前平臺的編譯器和連接器進行配置(以生成DSO格式目標(biāo)文件)的情況下編譯Apache模塊了。
使用概要說明
1.創(chuàng)建和安裝一個 Apache發(fā)布的(distributed) 模塊,比方說將mod_foo.c編譯成mod_foo.so:
$ ./configure --prefix=/path/to/install --enable-foo=shared
$ make install
2.創(chuàng)建和安裝一個第三方的Apache模塊,比方說將mod_foo.c編譯成mod_foo.so:
$ ./configure --add-module=module_type:/path/to/3rdparty/mod_foo.c --enable-foo=shared
$ make install
3.為以后安裝(非HTTPD編譯時安裝)模塊配置Apache:
$ ./configure --enable-so
$ make install
(要編譯全部Aapache模塊,用./configure --enable-mods-shared=all --with-egd --with-devrandom --enable-so,但對experimental一類的模塊,需要特別指定,如./configure --enable-mods-shared=all --with-egd --with-devrandom --enable-so --enable-cache=shared --enable-disk_cache=shared --enable-mem_cache=shared --enable-proxy=shared --enable-proxy_connect=shared --enable-proxy_ftp=shared --enable-proxy_http=shared --enable-file_cache=shared --enable-charset_lite=shared --enable-case_filter=shared --enable-case_filter_in=shared --enable-ssl=shared 。具體有哪些模塊可以編譯而沒有打開編譯開關(guān),可在前面的那個configure運行的最后看看哪一個是no.)
4.利用apxs在沒有Apache源碼樹的情況下,創(chuàng)建和安裝第三方的Apache模塊:
$ cd /path/to/3rdparty
$ apxs -c mod_foo.c
$ apxs -i -a -n foo mod_foo.la
在所有的情況下,當(dāng)一個模塊編譯完成后,必須在httpd.conf使用LoadModule命令在告訴 Apache激活這個模塊。
背景知識
在現(xiàn)代的Unix的派生版本中,有一種非常好的機制,叫做Dynamic Shared Objects (DSO) 的動態(tài)連接/和加載,它提供了一種方法,將一段代碼編譯成一種特殊格式后可在一個可執(zhí)行程序運行時將這段程序加載到它的地址空間中。
這種加載通過可以通過兩種方式做到: 在一個可執(zhí)行程序開始運行后通過一個叫l(wèi)d.so的系統(tǒng)程序自動加載,或在可執(zhí)行程序內(nèi)部通過Unix加載器(loader)的系統(tǒng)編程接口的系統(tǒng)調(diào)用dlopen()/dlsym()來手工加載。
在第一種方式中,DSO通常被叫作共享庫或DSO庫,以libfoo.so或libfoo.so.1.2的形式命名。它們被存放在系統(tǒng)目錄中(通常是/usr/lib),它們與可執(zhí)行程序的聯(lián)系是在編譯這個可執(zhí)行程序時,通過傳遞給連接器一個-lfoo參數(shù)來建立的。這里對庫的引用直接編碼在可執(zhí)行程序中,因而在程序運行時,Unix加載器會通過以下途徑尋找libfoo.so:在系統(tǒng)目錄/usr/lib下,在通過-R連接參數(shù)傳遞給連接器后被編碼在可執(zhí)行程序中的路徑中,在通過環(huán)境變量LD_LIBRARY_PATH指定的目錄中。加載器會解析出來那些在可執(zhí)行程序中使用但是在DSO定義的標(biāo)志(symbol)。
可執(zhí)行程序中的標(biāo)志,通常不會被DSO引用(因為它是一個可重用的基本代碼庫),因而就不再進行進一步的解析。可執(zhí)行程序自己不需要做任何事情就可以使用來自DSO的標(biāo)志,因為Unix加載器已經(jīng)做了相關(guān)的解析工作。(實際上,加載ld.so的代碼是使用動態(tài)庫的可執(zhí)行程序啟動代碼的一部分). 動態(tài)加載基本代碼庫的優(yōu)點是很明顯的:庫的代碼只需在一個系統(tǒng)庫(如libc.so)中保存一次,這樣可以節(jié)省每個程序的磁盤空間。
在第二種方式中,DSO通常被叫作共享對象或DSO文件,命名它們時可以使用任意的擴展名,雖然規(guī)范的命名是foo.so的樣子。這些文件通常存放在程序所在的目錄(或子目錄)中,它們與執(zhí)行它們的程序沒有自動建立的聯(lián)系。相反,可執(zhí)行程序在運行時通過dlopen手工將DSO加載。此時,來自DSO供執(zhí)行程序用的標(biāo)志沒有被解析。相反,Unix加載器自動解析所有DSO中使用的來自可執(zhí)行程序和它已經(jīng)加載的DSO 庫的標(biāo)志(尤其是來自無處不在的libc.so的所有標(biāo)志)。在這種方式中,DSO取得可執(zhí)行程序的標(biāo)志集合的信息,就象是被靜態(tài)地連接到可執(zhí)行程序中一樣。
最后,為利用DSO's API,可執(zhí)行程序須通過dlsym()來解析來自DSO的特定標(biāo)志,供在以后的分派表等處使用。也就是說:可執(zhí)行程序要想使用來自DSO的標(biāo)志,須手工解析它。這樣一種機制的優(yōu)點,不需要的程序段不必加載(因而可以節(jié)省內(nèi)存的使用) ,直到我們討論的程序需要它時。當(dāng)需要時,這些程序段可以被動態(tài)的加載,來擴展基本程序的功能。
雖然DSO機制聽起來簡單,用起來只少有一個比較困難的步驟,就是當(dāng)用DSO來擴展程序的功能時(第二種方式)時,對來自可執(zhí)行程序、供DSO使用的標(biāo)志的解析。為什么呢? 因為"反向解析" DSO 使用的來自可執(zhí)行程序標(biāo)志集合的標(biāo)志是與函數(shù)庫的設(shè)計相逆的 (函數(shù)庫沒有任何關(guān)于那些使用它的程序的信息),而且沒有平臺提供這種功能,這也不是一個標(biāo)準(zhǔn)化的功能。實際上,可執(zhí)行程序的全局標(biāo)志常常不能再次輸出,因而也無法供DSO使用。要利用DSO來動態(tài)擴展一個程序的功能,找到一種方法來強制連接器輸出所有全局標(biāo)志是必須解決的主要問題。
共享庫的方法就是一個典型,因為它是DSO機制最初設(shè)計的目標(biāo),因而它被用于操作系統(tǒng)提供的幾乎所有類型的函數(shù)庫中。從另一方面來說,利用共享對象來擴展功能的程序并不是很多。
到1998年,只有很少的軟件包在程序運行時利用DSO機制來擴展它們的功能:Perl 5(通過它的XS機制和DynaLoader模塊), Netscape Server,等。從版本1.3開始, Apache 也加入了這個群體,因為Apache早就用模塊的概念來擴展它的功能,且在內(nèi)容利用基于分派鏈(dispatch-list-based )的方法來將外部的模塊連接到Apache的核心功能中。因此,Apache實際上注定要用DSO來在運行時加載模塊的。
長處和不足
上述的基于DSO的功能有以下優(yōu)點:
服務(wù)器在運行時更加靈活,因為實際的服務(wù)器進程可以通過配置文件的LoadModule命令動態(tài)的組配,而不必在編譯時通過配置參數(shù)指定。例如,通過這種方式,雖然只安裝了一次,但服務(wù)器可以以多種形態(tài)運行(如標(biāo)準(zhǔn)版本或SSL版本,簡化版本或增強版本[含mod_perl,php3等])
即使在安裝完成后,服務(wù)器仍可以很方便地用第三方的模塊進行功能擴展。這至少對銷售商的軟件支持有幫助,他們可以創(chuàng)建一個apache的核心程序包,和一個包含PHP3, mod_perl, mod_fastcgi等擴展功能的擴展包。
更容易地開發(fā) Apache模塊原型,因為借用DSO和apxs,你可以脫離Apache的源碼而只需apxs -i命令就可以開發(fā)和編譯模塊,利用apachectl restart 命令,就可以讓新開發(fā)的模塊在在apache服務(wù)器中運行。
DSO 也有下列不足:
DSO并不是在任何平臺都可以使用,因為有一些平臺不支持動態(tài)將一段代碼加載到另一個程序的地址空間中。
服務(wù)器在啟動時慢大約20%,因為加載器要作標(biāo)志解析。
在運行時,在有些平臺上服務(wù)器大約慢5%,因為PIC( position independent code )代碼需要更復(fù)雜的組配技巧來解決相對地址的問題,而對絕對地址的情況沒有這種開銷所以會快一些。
因為并不是所有的平臺都支持DSO模塊連接(ld -lfoo)其它基于DSO的庫(如基于out的平臺通常不提供這個功能而基于ELF的平臺則可以),所以不能將DSO機制用于所有類型的模塊。換句話說,可以編譯為DSO文件的模塊限制為那些:引用的標(biāo)志只來自apache內(nèi)核、來自C函數(shù)庫(libc)、來自其它的Aapche內(nèi)核使用的動態(tài)或靜態(tài)庫、或含有PIC代碼的靜態(tài)庫文件(libfoo.a)。使用其它代碼的唯一機會,要么確定apache內(nèi)核已經(jīng)對此引用,要能自己通過dlopen()加載代碼。關(guān)鍵詞標(biāo)簽:編譯,使用,程序,DSO,模
相關(guān)閱讀
熱門文章
ISAPI Rewrite實現(xiàn)IIS圖片防盜鏈
IIS6.0下配置MySQL+PHP5+Zend+phpMyAdmin
在Windows服務(wù)器上快速架設(shè)視頻編解碼器全攻略
win2000server IIS和tomcat5多站點配置
人氣排行
XAMPP配置出現(xiàn)403錯誤“Access forbidden!”的解決辦法
WIN2003 IIS6.0+PHP+ASP+MYSQL優(yōu)化配置
訪問網(wǎng)站403錯誤 Forbidden解決方法
如何從最大用戶并發(fā)數(shù)推算出系統(tǒng)最大用戶數(shù)
Server Application Unavailable的解決辦法
報錯“HTTP/1.1 400 Bad Request”的處理方法
Windows Server 2003的Web接口
http 500內(nèi)部服務(wù)器錯誤的解決辦法(windows xp + IIS5.0)