亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

directory search
首頁 版本說明 從1.3升級到2.0 編譯時配置的改變 運行時配置的改變 雜項變化 第三方模塊 從 2.0 升級到 2.2 編譯時配置的改變 運行時配置的改變 雜項變化 第三方模塊 Apache 2.1/2.2 版本的新特性 核心增強 模塊增強 程序增強 針對模塊開發(fā)者的變化 Apache 2.0 版本的新特性 核心的增強 模塊的增強 Apache許可證 參考手冊 編譯與安裝 針對心急者的概述 要求 下載 解壓 配置源代碼樹 編譯 安裝 配置 測試 升級 啟動 Apache是怎樣啟動的 啟動時發(fā)生錯誤 隨系統(tǒng)啟動時啟動 額外信息 停止與重新啟動 簡介 立即停止 優(yōu)雅重啟 立即重啟 優(yōu)雅停止 附錄:信號和競爭條件 運行時配置指令 主配置文件 配置文件的語法 模塊 指令的作用域 .htaccess文件 配置段 配置段(容器)的類型 文件系統(tǒng)和網(wǎng)絡(luò)空間 虛擬主機 代理 允許使用哪些指令? 配置段的合并 內(nèi)容緩沖 簡介 緩沖概述 安全方面的考慮 文件句柄緩沖 內(nèi)存緩沖 磁盤緩沖 服務(wù)器全局配置 服務(wù)器標識 文件定位 限制資源的使用 日志文件 安全警告 錯誤日志 訪問日志 日志滾動 管道日志 虛擬主機 其他日志文件 從URL到文件系統(tǒng)的映射 相關(guān)模塊和指令 DocumentRoot DocumentRoot以外的文件 用戶目錄 URL重定向 反向代理 重寫引擎 File Not Found 安全方面的提示 保持不斷更新和升級 ServerRoot目錄的權(quán)限 服務(wù)器端包含 關(guān)于CGI 未指定為腳本的CGI 指定為腳本的CGI 其他動態(tài)內(nèi)容的來源 系統(tǒng)設(shè)置的保護 默認配置下服務(wù)器文件的保護 觀察日志文件 動態(tài)共享對象(DSO) 實現(xiàn) 用法概要 背景知識 優(yōu)點和缺點 內(nèi)容協(xié)商 關(guān)于內(nèi)容協(xié)商 Apache中的內(nèi)容協(xié)商 協(xié)商的方法 打亂品質(zhì)值 透明內(nèi)容協(xié)商的擴展 超鏈和名稱轉(zhuǎn)換說明 緩沖說明 更多信息 自定義錯誤響應(yīng) 行為 配置 自定義錯誤響應(yīng)與重定向 地址和端口綁定 概述 針對IPv6的特殊考慮 怎樣與虛擬主機協(xié)同工作 多路處理模塊(MPM) 簡介 選擇一個MPM 默認的MPM 環(huán)境變量 設(shè)置環(huán)境變量 使用環(huán)境變量 用于特殊目的的環(huán)境變量 示例 處理器的使用 什么是處理器? 例子 程序員注意事項 過濾器 Apache2中的過濾器 智能過慮 使用過濾器 CGI腳本的Suexec執(zhí)行 開始之前 suEXEC的安全模型 配置和安裝suEXEC 啟用和禁用suEXEC 使用suEXEC 調(diào)試suEXEC 謹防Jabberwock:警告和舉例 性能調(diào)整 硬件和操作系統(tǒng) 運行時的配置 編譯時的配置 附錄:蹤跡的詳細分析 URL重寫指南 mod_rewrite簡介 實踐方案 URL的規(guī)劃 內(nèi)容的處理 對訪問的限制 其他 虛擬主機文檔 總述 虛擬主機支持 配置指令 基于主機名的虛擬主機 基于域名的虛擬主機和基于IP的虛擬主機比較 使用基于域名的虛擬主機 與舊版瀏覽器的兼容性 基于IP地址的虛擬主機 系統(tǒng)需求 如何配置Apache 設(shè)置多個守護進程 配置擁有多個虛擬主機的單一守護進程 動態(tài)配置大量虛擬主機 動機 概述 簡單的動態(tài)虛擬主機 一個實際的個人主頁系統(tǒng) 在同一個服務(wù)器上架設(shè)多個主機的虛擬系統(tǒng) 更為有效的基于IP地址的虛擬主機 使用老版本的Apache 使用mod_rewrite實現(xiàn)簡單的動態(tài)虛擬主機 使用mod_rewrite的個人主頁系統(tǒng) 使用獨立的虛擬主機配置文件 虛擬主機的普通配置示例 在一個IP地址上運行多個基于域名的web站點 在多于一個IP的情況下使用基于域名的虛擬主機 在不同的IP的地址(比如一個內(nèi)部和一個外部地址)上提供相同的內(nèi)容 在不同的端口上運行不同的站點 建立基于IP的虛擬主機 混用基于端口和基于IP的虛擬主機 混用基于域名和基于IP的虛擬主機 將虛擬主機和代理模塊一起使用 使用默認虛擬主機 將一個基于域名的虛擬主機移植為一個基于IP的虛擬主機 使用ServerPath指令 深入討論虛擬主機的匹配 解析配置文件 虛擬主機匹配 小技巧 文件描述符限制 關(guān)于DNS和Apache 一個簡單示例 拒絕服務(wù) "主服務(wù)器"地址 避免這些問題的小技巧 附錄:進一步的提示 常見問題 概述 SSL/TLS 加密 概述 文檔 mod_ssl 緒論 密碼技術(shù) 證書 安全套接字層(SSL) 參考 兼容性 配置指令 環(huán)境變量 自定義日志功能 如何... 加密方案和強制性高等級安全 客戶認證和訪問控制 常見問題解答 About The Module Installation Configuration Certificates The SSL Protocol mod_ssl Support 如何.../指南 概述 認證 相關(guān)模塊和指令 簡介 先決條件 啟用認證 允許多人訪問 可能存在的問題 其他認證方法 更多信息 CGI動態(tài)頁面 簡介 配置Apache以允許CGI 編寫CGI程序 程序還是不能運行! 幕后是怎樣操作的? CGI模塊/庫 更多信息 服務(wù)器端包含 簡介 什么是SSI? 配置服務(wù)器以允許SSI 基本SSI指令 附加的例子 我還能設(shè)置其它什么? 執(zhí)行命令 高級SSI技術(shù) 總結(jié) .htaccess文件 .htaccess文件 工作原理和使用方法 (不)使用.htaccess文件的場合 指令的生效 認證舉例 服務(wù)器端包含(SSI)舉例 CGI舉例 疑難解答 用戶網(wǎng)站目錄 用戶網(wǎng)站目錄 用UserDir設(shè)置文件路徑 限定哪些用戶可以使用此功能 啟用對每個用戶都有效的cgi目錄 允許用戶改變配置 對特定平臺的說明 概述 Microsoft Windows 其他平臺 在Microsoft Windows中使用Apache 對操作系統(tǒng)的要求 下載 Apache for Windows 安裝 Apache for Windows 配置 Apache for Windows 以服務(wù)方式運行 Apache for Windows 作為控制臺程序運行Apache 測試安裝 編譯Windows下的Apache 系統(tǒng)要求 命令行編譯 Developer Studio集成開發(fā)環(huán)境的工作區(qū)編譯 項目組件 在Novell NetWare平臺上使用Apache Requirements Downloading Apache for NetWare Installing Apache for NetWare Running Apache for NetWare Configuring Apache for NetWare Compiling Apache for NetWare 在HP-UX中運行Apache The Apache EBCDIC Port Overview of the Apache EBCDIC Port Design Goals Technical Solution Porting Notes Document Storage Notes Apache Modules' Status Third Party Modules' Status 服務(wù)器與支持程序 概述 httpd 語法 選項 ab 語法 選項 Bugs apachectl 語法 選項 apxs 語法 選項 舉例 configure 語法 選項 環(huán)境變量 dbmmanage 語法 選項 Bugs htcacheclean 語法 選項 返回值 htdbm 語法 選項 Bugs 返回值 舉例 安全方面的考慮 限制 htdigest 語法 選項 htpasswd 語法 選項 返回值 舉例 安全方面的考慮 限制 logresolve 語法 選項 rotatelogs 語法 選項 Portability suexec 語法 選項 其他程序 log_server_status split-logfile 雜項文檔 概述 相關(guān)標準 HTTP推薦標準 HTML推薦標準 認證 語言/國家代碼 Apache 模塊 描述模塊的術(shù)語 說明 狀態(tài) 源代碼文件 模塊標識符 兼容性 描述指令的術(shù)語 說明 語法 默認值(Default) 作用域(Context) 覆蓋項(Override) 狀態(tài) 模塊(Module) 兼容性(Compatibility) Apache核心(Core)特性 AcceptFilter AcceptPathInfo AccessFileName AddDefaultCharset AddOutputFilterByType AllowEncodedSlashes AllowOverride AuthName AuthType CGIMapExtension ContentDigest DefaultType <Directory> <DirectoryMatch> DocumentRoot EnableMMAP EnableSendfile ErrorDocument ErrorLog FileETag <Files> <FilesMatch> ForceType HostnameLookups <IfDefine> <IfModule> Include KeepAlive KeepAliveTimeout <Limit> <LimitExcept> LimitInternalRecursion LimitRequestBody LimitRequestFields LimitRequestFieldSize LimitRequestLine LimitXMLRequestBody <Location> <LocationMatch> LogLevel MaxKeepAliveRequests NameVirtualHost Options Require RLimitCPU RLimitMEM RLimitNPROC Satisfy ScriptInterpreterSource ServerAdmin ServerAlias ServerName ServerPath ServerRoot ServerSignature ServerTokens SetHandler SetInputFilter SetOutputFilter TimeOut TraceEnable UseCanonicalName UseCanonicalPhysicalPort <VirtualHost> Apache MPM 公共指令 AcceptMutex CoreDumpDirectory EnableExceptionHook GracefulShutdownTimeout Group Listen ListenBackLog LockFile MaxClients MaxMemFree MaxRequestsPerChild MaxSpareThreads MinSpareThreads PidFile ReceiveBufferSize ScoreBoardFile SendBufferSize ServerLimit StartServers StartThreads ThreadLimit ThreadsPerChild ThreadStackSize User Apache MPM beos MaxRequestsPerThread CoreDumpDirectory Group Listen ListenBacklog MaxClients MaxMemFree MaxSpareThreads MinSpareThreads PidFile ReceiveBufferSize ScoreBoardFile SendBufferSize StartThreads User Apache MPM event AcceptMutex CoreDumpDirectory EnableExceptionHook Group Listen ListenBacklog LockFile MaxClients MaxMemFree MaxRequestsPerChild MaxSpareThreads MinSpareThreads PidFile ScoreBoardFile SendBufferSize ServerLimit StartServers ThreadLimit ThreadsPerChild ThreadStackSize User Apache MPM netware MaxThreads Listen ListenBacklog MaxMemFree MaxRequestsPerChild MaxSpareThreads MinSpareThreads ReceiveBufferSize SendBufferSize StartThreads ThreadStackSize Apache MPM os2 Group Listen ListenBacklog MaxRequestsPerChild MaxSpareThreads MinSpareThreads PidFile ReceiveBufferSize SendBufferSize StartServers User Apache MPM prefork 工作方式 MaxSpareServers MinSpareServers AcceptMutex CoreDumpDirectory EnableExceptionHook Group Listen ListenBacklog LockFile MaxClients MaxMemFree MaxRequestsPerChild PidFile ReceiveBufferSize ScoreBoardFile SendBufferSize ServerLimit StartServers User Apache MPM winnt Win32DisableAcceptEx CoreDumpDirectory Listen ListenBacklog MaxMemFree MaxRequestsPerChild PidFile ReceiveBufferSize ScoreBoardFile SendBufferSize ThreadLimit ThreadsPerChild ThreadStackSize Apache MPM worker 工作方式 AcceptMutex CoreDumpDirectory EnableExceptionHook Group Listen ListenBacklog LockFile MaxClients MaxMemFree MaxRequestsPerChild MaxSpareThreads MinSpareThreads PidFile ReceiveBufferSize ScoreBoardFile SendBufferSize ServerLimit StartServers ThreadLimit ThreadsPerChild ThreadStackSize User Apache Module mod_actions Action指令 Script指令 Apache Module mod_alias 處理順序 Alias AliasMatch Redirect RedirectMatch RedirectPermanent RedirectTemp ScriptAlias ScriptAliasMatch Apache Module mod_asis 用法 Apache Module mod_auth_basic AuthBasicAuthoritative AuthBasicProvider Apache Module mod_auth_digest 使用摘要認證 配合 MS Internet Explorer 6 工作 AuthDigestAlgorithm AuthDigestDomain AuthDigestNcCheck AuthDigestNonceFormat AuthDigestNonceLifetime AuthDigestProvider AuthDigestQop AuthDigestShmemSize Apache Module mod_authn_alias 示例 <AuthnProviderAlias> Apache Module mod_authn_anon 示例 Anonymous Anonymous_LogEmail Anonymous_MustGiveEmail Anonymous_NoUserID Anonymous_VerifyEmail Apache Module mod_authn_dbd 配置示例 AuthDBDUserPWQuery AuthDBDUserRealmQuery Apache Module mod_authn_dbm AuthDBMType AuthDBMUserFile Apache Module mod_authn_default AuthDefaultAuthoritative Apache Module mod_authn_file AuthUserFile Apache Module mod_authnz_ldap Contents Operation The require Directives 舉例 Using TLS Using SSL Using Microsoft FrontPage with mod_authnz_ldap AuthLDAPBindDN AuthLDAPBindPassword AuthLDAPCharsetConfig AuthLDAPCompareDNOnServer AuthLDAPDereferenceAliases AuthLDAPGroupAttribute AuthLDAPGroupAttributeIsDN AuthLDAPRemoteUserIsDN AuthLDAPUrl AuthzLDAPAuthoritative Apache Module mod_authz_dbm AuthDBMGroupFile AuthzDBMAuthoritative AuthzDBMType Apache Module mod_authz_default AuthzDefaultAuthoritative Apache Module mod_authz_groupfile AuthGroupFile AuthzGroupFileAuthoritative Apache Module mod_authz_host Allow Deny Order Apache Module mod_authz_owner 配置示例 AuthzOwnerAuthoritative Apache Module mod_authz_user AuthzUserAuthoritative Apache Module mod_autoindex Autoindex Request Query Arguments AddAlt AddAltByEncoding AddAltByType AddDescription AddIcon AddIconByEncoding AddIconByType DefaultIcon HeaderName IndexIgnore IndexOptions IndexOrderDefault IndexStyleSheet ReadmeName Apache Module mod_cache Related Modules and Directives 配置示例 CacheDefaultExpire CacheDisable CacheEnable CacheIgnoreCacheControl CacheIgnoreHeaders CacheIgnoreNoLastMod CacheLastModifiedFactor CacheMaxExpire CacheStoreNoStore CacheStorePrivate Apache Module mod_cern_meta MetaDir MetaFiles MetaSuffix Apache Module mod_cgi CGI 環(huán)境變量 CGI 腳本的調(diào)試 ScriptLog ScriptLogBuffer ScriptLogLength Apache Module mod_cgid ScriptSock ScriptLog ScriptLogBuffer ScriptLogLength Apache Module mod_charset_lite Common Problems CharsetDefault CharsetOptions CharsetSourceEnc Apache Module mod_dav Enabling WebDAV Security Issues Complex Configurations Dav DavDepthInfinity DavMinTimeout Apache Module mod_dav_fs DavLockDB Apache Module mod_dav_lock DavGenericLockDB Apache Module mod_dbd Connection Pooling Apache DBD API SQL Prepared Statements DBDExptime DBDKeep DBDMax DBDMin DBDParams DBDPersist DBDPrepareSQL DBDriver Apache Module mod_deflate 配置舉例 啟用壓縮 代理服務(wù)器 DeflateBufferSize DeflateCompressionLevel DeflateFilterNote DeflateMemLevel DeflateWindowSize Apache Module mod_dir DirectoryIndex DirectorySlash Apache Module mod_disk_cache CacheDirLength CacheDirLevels CacheMaxFileSize CacheMinFileSize CacheRoot Apache Module mod_dumpio 啟用dumpio支持 DumpIOInput DumpIOOutput Apache Module mod_echo ProtocolEcho Apache Module mod_env PassEnv SetEnv UnsetEnv Apache Module mod_example Compiling the example module Using the mod_example Module Example Apache Module mod_expires 交替間隔語法 ExpiresActive ExpiresByType ExpiresDefault Apache Module mod_ext_filter 舉例 ExtFilterDefine ExtFilterOptions Apache Module mod_file_cache Using mod_file_cache CacheFile MMapFile Apache Module mod_filter Smart Filtering Filter Declarations Configuring the Chain Examples Protocol Handling FilterChain FilterDeclare FilterProtocol FilterProvider FilterTrace Apache Module mod_headers 處理順序 前處理和后處理 舉例 Header RequestHeader Apache Module mod_ident IdentityCheck IdentityCheckTimeout Apache Module mod_imagemap New Features Imagemap File Example Mapfile Referencing your mapfile ImapBase ImapDefault ImapMenu Apache Module mod_include Enabling Server-Side Includes PATH_INFO with Server Side Includes Basic Elements Include Variables Variable Substitution Flow Control Elements SSIEndTag SSIErrorMsg SSIStartTag SSITimeFormat SSIUndefinedEcho XBitHack Apache Module mod_info 安全問題 選擇哪些信息可以被顯示 已知的局限 AddModuleInfo Apache Module mod_isapi 用法 附加注釋 程序員注記 ISAPIAppendLogToErrors ISAPIAppendLogToQuery ISAPICacheFile ISAPIFakeAsync ISAPILogNotSupported ISAPIReadAheadBuffer Apache Module mod_ldap 示例配置 LDAP 連接池 LDAP 緩沖 使用SSL/TLS SSL/TLS 證書 LDAPCacheEntries LDAPCacheTTL LDAPConnectionTimeout LDAPOpCacheEntries LDAPOpCacheTTL LDAPSharedCacheFile LDAPSharedCacheSize LDAPTrustedClientCert LDAPTrustedGlobalCert LDAPTrustedMode LDAPVerifyServerCert Apache Module mod_log_config 定制日志文件格式 安全考慮 BufferedLogs CookieLog CustomLog LogFormat TransferLog Apache Module mod_log_forensic 定制日志文件格式 安全考慮 ForensicLog Apache Module mod_logio 定制日志文件格式 Apache Module mod_mem_cache MCacheMaxObjectCount MCacheMaxObjectSize MCacheMaxStreamingBuffer MCacheMinObjectSize MCacheRemovalAlgorithm MCacheSize Apache Module mod_mime 帶多擴展名的文件 內(nèi)容編碼 字符集和語言 AddCharset AddEncoding AddHandler AddInputFilter AddLanguage AddOutputFilter AddType DefaultLanguage ModMimeUsePathInfo MultiviewsMatch RemoveCharset RemoveEncoding RemoveHandler RemoveInputFilter RemoveLanguage RemoveOutputFilter RemoveType TypesConfig Apache Module mod_mime_magic "Magic文件"的格式 性能問題 注意 MimeMagicFile Apache Module mod_negotiation 類型表 MultiViews CacheNegotiatedDocs ForceLanguagePriority LanguagePriority Apache Module mod_nw_ssl NWSSLTrustedCerts NWSSLUpgradeable SecureListen Apache Module mod_proxy 正向和反向代理 簡單示例 控制對代理服務(wù)器的訪問 緩慢啟動 局域網(wǎng)代理 協(xié)議調(diào)整 請求體 AllowCONNECT NoProxy <Proxy> ProxyBadHeader ProxyBlock ProxyDomain ProxyErrorOverride ProxyIOBufferSize <ProxyMatch> ProxyMaxForwards ProxyPass ProxyPassReverse ProxyPassReverseCookieDomain ProxyPassReverseCookiePath ProxyPreserveHost ProxyReceiveBufferSize ProxyRemote ProxyRemoteMatch ProxyRequests ProxyTimeout ProxyVia Apache Module mod_proxy_ajp Overview of the protocol Basic Packet Structure Request Packet Structure Response Packet Structure Apache Module mod_proxy_balancer Load balancer scheduler algorithm Request Counting Algorithm Weighted Traffic Counting Algorithm Enabling Balancer Manager Support Apache Module mod_proxy_connect Apache Module mod_proxy_ftp 為什么xxx類型的文件不能從FTP下載? 如何強制文件xxx使用FTP的ASCII形式下載? 我如何使用FTP上傳? 我如何能訪問我自己home目錄以外的FTP文件? 我如何才能在瀏覽器的URL框中隱藏FTP的明文密碼? Apache Module mod_proxy_http Apache Module mod_rewrite 特殊字符的引用 環(huán)境變量 實用方案 RewriteBase RewriteCond RewriteEngine RewriteLock RewriteLog RewriteLogLevel RewriteMap RewriteOptions RewriteRule Apache Module mod_setenvif BrowserMatch BrowserMatchNoCase SetEnvIf SetEnvIfNoCase Apache Module mod_so 為Windows創(chuàng)建可加載模塊 LoadFile LoadModule Apache Module mod_speling CheckSpelling Apache Module mod_ssl 環(huán)境變量 Custom Log Formats SSLCACertificateFile SSLCACertificatePath SSLCADNRequestFile SSLCADNRequestPath SSLCARevocationFile SSLCARevocationPath SSLCertificateChainFile SSLCertificateFile SSLCertificateKeyFile SSLCipherSuite SSLCryptoDevice SSLEngine SSLHonorCipherOrder SSLMutex SSLOptions SSLPassPhraseDialog SSLProtocol SSLProxyCACertificateFile SSLProxyCACertificatePath SSLProxyCARevocationFile SSLProxyCARevocationPath SSLProxyCipherSuite SSLProxyEngine SSLProxyMachineCertificateFile SSLProxyMachineCertificatePath SSLProxyProtocol SSLProxyVerify SSLProxyVerifyDepth SSLRandomSeed SSLRequire SSLRequireSSL SSLSessionCache SSLSessionCacheTimeout SSLUserName SSLVerifyClient SSLVerifyDepth Apache Module mod_status Enabling Status Support 自動更新 Machine Readable Status File ExtendedStatus Apache Module mod_suexec SuexecUserGroup Apache Module mod_unique_id Theory Apache Module mod_userdir UserDir Apache Module mod_usertrack Logging 2-digit or 4-digit dates for cookies? CookieDomain CookieExpires CookieName CookieStyle CookieTracking Apache Module mod_version <IfVersion> Apache Module mod_vhost_alias 目錄名稱的轉(zhuǎn)換 示例 VirtualDocumentRoot VirtualDocumentRootIP VirtualScriptAlias VirtualScriptAliasIP 開發(fā)者文檔 Overview Topics External Resources Apache API notes Basic concepts How handlers work Resource allocation and resource pools Configuration Debugging Memory Allocation in APR Available debugging options Allowable Combinations Activating Debugging Options Documenting Apache 2.0 Apache 2.0 Hook Functions Creating a hook function Hooking the hook Converting Modules from Apache 1.3 to Apache 2.0 The easier changes ... The messier changes... Request Processing in Apache 2.0 The Request Processing Cycle The Request Parsing Phase The Security Phase The Preparation Phase The Handler Phase How Filters Work in Apache 2.0 Filter Types How are filters inserted? Asis Explanations 詞匯和索引 詞匯表 模塊索引 指令索引 指令速查 譯者聲明
characters

性能方面的提示

Apache2.0是一個多用途的web服務(wù)器,其設(shè)計在靈活性、可移植性和性能中求得平衡。雖然沒有在設(shè)計上刻意追求性能指標,但是Apache2.0仍然在許多現(xiàn)實環(huán)境中擁有很高的性能。

相比于Apache 1.3 ,2.0版本作了大量的優(yōu)化來提升處理能力和可伸縮性,而且大多數(shù)的改進在默認狀態(tài)下就可以生效。但是,在編譯時和運行時,都有許多可以顯著提高性能的選擇。本文闡述在安裝Apache2.0時,服務(wù)器管理員可以改善性能的各種方法。其中,部分配置選擇可以使httpd更好地利用硬件和操作系統(tǒng)的兼容性,其他則是以功能換取速度。

硬件和操作系統(tǒng)

影響web服務(wù)器性能的最大的因素是內(nèi)存。一個web服務(wù)器應(yīng)該從不使用交換機制,因為交換產(chǎn)生的滯后使用戶總感覺"不夠快",所以用戶就可能去按"停止"和"刷新",從而帶來更大的負載。你可以,也應(yīng)該,控制MaxClients的設(shè)置,以避免服務(wù)器產(chǎn)生太多的子進程而發(fā)生交換。這個過程很簡單:通過top命令計算出每個Apache進程平均消耗的內(nèi)存,然后再為其它進程留出足夠多的內(nèi)存。

其他因素就很普通了,裝一個足夠快的CPU,一個足夠快的網(wǎng)卡,幾個足夠快的硬盤,這里說的"足夠快"是指能滿足實際應(yīng)用的需求。

操作系統(tǒng)是很值得關(guān)注的又一個因素,已經(jīng)被證實的很有用的經(jīng)驗有:

  • 選擇能夠得到的最新最穩(wěn)定的版本并打好補丁。近年來,許多操作系統(tǒng)廠商都提供了可以顯著改善性能的TCP協(xié)議棧和線程庫。

  • 如果你的操作系統(tǒng)支持sendfile()系統(tǒng)調(diào)用,則務(wù)必安裝帶有此功能的版本或補丁(對Linux來說,就是使用Linux2.4或更高版本,對Solaris8的早期版本,則需要安裝補丁)。在支持sendfile的系統(tǒng)中,Apache2可以更快地發(fā)送靜態(tài)內(nèi)容而且占用較少的CPU時間。

運行時的配置

HostnameLookups 和其他DNS考慮

在Apache1.3以前的版本中,HostnameLookups默認被設(shè)為 On 。它會帶來延遲,因為對每一個請求都需要作一次DNS查詢。在Apache1.3中,它被默認地設(shè)置為 Off 。如果需要日志文件提供主機名信息以生成分析報告,則可以使用日志后處理程序logresolve ,以完成DNS查詢,而客戶端無須等待。

推薦你最好是在其他機器上,而不是在web服務(wù)器上執(zhí)行后處理和其他日志統(tǒng)計操作,以免影響服務(wù)器的性能。

如果你使用了任何"Allow from domain"或"Deny from domain"指令(也就是domain使用的是主機名而不是IP地址),則代價是要進行兩次DNS查詢(一次正向和一次反向,以確認沒有作假)。所以,為了得到最高的性能,應(yīng)該避免使用這些指令(不用域名而用IP地址也是可以的)。

注意,可以把這些指令包含在<Location /server-status>段中使之局部化。在這種情況下,只有對這個區(qū)域的請求才會發(fā)生DNS查詢。下例禁止除了.html.cgi以外的所有DNS查詢:

HostnameLookups off
<Files ~ "\.(html|cgi)$">
HostnameLookups on
</Files>

如果在某些CGI中偶爾需要DNS名稱,則可以調(diào)用gethostbyname來解決。

FollowSymLinks 和 SymLinksIfOwnerMatch

如果網(wǎng)站空間中沒有使用 Options FollowSymLinks ,或使用Options SymLinksIfOwnerMatch ,Apache就必須執(zhí)行額外的系統(tǒng)調(diào)用以驗證符號連接。文件名的每一個組成部分都需要一個額外的調(diào)用。例如,如果設(shè)置了:

DocumentRoot /www/htdocs
<Directory />
Options SymLinksIfOwnerMatch
</Directory>

在請求"/index.html"時,Apache將對"/www"、"/www/htdocs"、"/www/htdocs/index.html"執(zhí)行lstat()調(diào)用。而且lstat()的執(zhí)行結(jié)果不被緩存,因此對每一個請求都要執(zhí)行一次。如果確實需要驗證符號連接的安全性,則可以這樣:

DocumentRoot /www/htdocs
<Directory />
Options FollowSymLinks
</Directory>

<Directory /www/htdocs>
Options -FollowSymLinks +SymLinksIfOwnerMatch
</Directory>

這樣,至少可以避免對DocumentRoot路徑的多余的驗證。注意,如果AliasRewriteRule中含有DocumentRoot以外的路徑,那么同樣需要增加這樣的段。為了得到最佳性能,應(yīng)當(dāng)放棄對符號連接的保護,在所有地方都設(shè)置FollowSymLinks ,并放棄使用SymLinksIfOwnerMatch 。

AllowOverride

如果網(wǎng)站空間允許覆蓋(通常是用.htaccess文件),則Apache會試圖對文件名的每一個組成部分都打開.htaccess ,例如:

DocumentRoot /www/htdocs
<Directory />
AllowOverride all
</Directory>

如果請求"/index.html",則Apache會試圖打開"/.htaccess"、"/www/.htaccess"、"/www/htdocs/.htaccess"。其解決方法和前面所述的 Options FollowSymLinks 類似。為了得到最佳性能,應(yīng)當(dāng)對文件系統(tǒng)中所有的地方都使用 AllowOverride None 。

內(nèi)容協(xié)商

實踐中,內(nèi)容協(xié)商的好處大于性能的損失,如果你很在意那一點點的性能損失,則可以禁止使用內(nèi)容協(xié)商。但是仍然有個方法可以提高服務(wù)器的速度,就是不要使用通配符,如:

DirectoryIndex index

而使用完整的列表,如:

DirectoryIndex index.cgi index.pl index.shtml index.html

其中最常用的應(yīng)該放在前面。

還有,建立一個明確的type-map文件在性能上優(yōu)于使用"Options MultiViews",因為所有需要的信息都在一個單獨的文件中,而無須搜索目錄。請參考內(nèi)容協(xié)商文檔以獲得更詳細的協(xié)商方法和創(chuàng)建type-map文件的指導(dǎo)。

內(nèi)存映射

在Apache2.0需要搜索被發(fā)送文件的內(nèi)容時,比如處理服務(wù)器端包含時,如果操作系統(tǒng)支持某種形式的mmap() ,則會對此文件執(zhí)行內(nèi)存映射。

在某些平臺上,內(nèi)存映射可以提高性能,但是在某些情況下,內(nèi)存映射會降低性能甚至影響到httpd的穩(wěn)定性:

  • 在某些操作系統(tǒng)中,如果增加了CPU,mmap還不如read()迅速。比如,在多處理器的Solaris服務(wù)器上,關(guān)閉了mmap ,Apache2.0傳送服務(wù)端解析文件有時候反而更快。

  • 如果你對作為NFS裝載的文件系統(tǒng)中的一個文件進行了內(nèi)存映射,而另一個NFS客戶端的進程刪除或者截斷了這個文件,那么你的進程在下一次訪問已經(jīng)被映射的文件內(nèi)容時,會產(chǎn)生一個總線錯誤。

如果有上述情況發(fā)生,則應(yīng)該使用 EnableMMAP off 關(guān)閉對發(fā)送文件的內(nèi)存映射。注意:此指令可以被針對目錄的設(shè)置覆蓋。

Sendfile

在Apache2.0能夠忽略將要被發(fā)送的文件的內(nèi)容的時候(比如發(fā)送靜態(tài)內(nèi)容),如果操作系統(tǒng)支持sendfile() ,則Apache將使用內(nèi)核提供的sendfile()來發(fā)送文件。

在大多數(shù)平臺上,使用sendfile可以通過免除分離的讀和寫操作來提升性能。然而在某些情況下,使用sendfile會危害到httpd的穩(wěn)定性

  • 一些平臺可能會有Apache編譯系統(tǒng)檢測不到的有缺陷的sendfile支持,特別是將在其他平臺上使用交叉編譯得到的二進制文件運行于當(dāng)前對sendfile支持有缺陷的平臺時。

  • 對于一個掛載了NFS文件系統(tǒng)的內(nèi)核,它可能無法可靠的通過自己的cache服務(wù)于網(wǎng)絡(luò)文件。

如果出現(xiàn)以上情況,你應(yīng)當(dāng)使用"EnableSendfile off"來禁用sendfile 。注意,這個指令可以被針對目錄的設(shè)置覆蓋。

進程的建立

在Apache1.3以前,MinSpareServers, MaxSpareServers, StartServers的設(shè)置對性能都有很大的影響。尤其是為了應(yīng)對負載而建立足夠的子進程時,Apache需要有一個"漸進"的過程。在最初建立StartServers數(shù)量的子進程后,為了滿足MinSpareServers設(shè)置的需要,每一秒鐘只能建立一個子進程。所以,對一個需要同時處理100個客戶端的服務(wù)器,如果StartServers使用默認的設(shè)置5,則為了應(yīng)對負載而建立足夠多的子進程需要95秒。在實際應(yīng)用中,如果不頻繁重新啟動服務(wù)器,這樣還可以,但是如果僅僅為了提供10分鐘的服務(wù),這樣就很糟糕了。

"一秒鐘一個"的規(guī)定是為了避免在創(chuàng)建子進程過程中服務(wù)器對請求的響應(yīng)停頓,但是它對服務(wù)器性能的影響太大了,必須予以改變。在Apache1.3中,這個"一秒鐘一個"的規(guī)定變得寬松了,創(chuàng)建一個進程,等待一秒鐘,繼續(xù)創(chuàng)建第二個,再等待一秒鐘,繼而創(chuàng)建四個,如此按指數(shù)級增加創(chuàng)建的進程數(shù),最多達到每秒32個,直到滿足MinSpareServers設(shè)置的值為止。

從多數(shù)反映看來,似乎沒有必要調(diào)整MinSpareServers, MaxSpareServers, StartServers 。如果每秒鐘創(chuàng)建的進程數(shù)超過4個,則會在ErrorLog中產(chǎn)生一條消息,如果產(chǎn)生大量此消息,則可以考慮修改這些設(shè)置??梢允褂?code class="module">mod_status的輸出作為參考。

與進程創(chuàng)建相關(guān)的是由MaxRequestsPerChild引發(fā)的進程的銷毀。其默認值是"0",意味著每個進程所處理的請求數(shù)是不受限制的。如果此值設(shè)置得很小,比如30,則可能需要大幅增加。在SunOS或者Solaris的早期版本上,其最大值為10000以免內(nèi)存泄漏。

如果啟用了持久鏈接,子進程將保持忙碌狀態(tài)以等待被打開連接上的新請求。為了最小化其負面影響,KeepAliveTimeout的默認值被設(shè)置為5秒,以謀求網(wǎng)絡(luò)帶寬和服務(wù)器資源之間的平衡。在任何情況下此值都不應(yīng)當(dāng)大于60秒,參見most of the benefits are lost。

編譯時的配置

選擇一個MPM

Apache 2.x 支持插入式并行處理模塊,稱為多路處理模塊(MPM)。在編譯Apache時你必須選擇也只能選擇一個MPM,這里有幾個針對非UNIX系統(tǒng)的MPM:beos, mpm_netware, mpmt_os2, mpm_winnt。對類UNIX系統(tǒng),有幾個不同的MPM可供選擇,他們都會影響到httpd的速度和可伸縮性:

  • workerMPM使用多個子進程,每個子進程中又有多個線程。每個線程處理一個請求。該MPM通常對高流量的服務(wù)器是一個不錯的選擇。因為它比preforkMPM需要更少的內(nèi)存且更具有伸縮性。
  • preforkMPM使用多個子進程,但每個子進程并不包含多線程。每個進程只處理一個鏈接。在許多系統(tǒng)上它的速度和workerMPM一樣快,但是需要更多的內(nèi)存。這種無線程的設(shè)計在某些情況下優(yōu)于workerMPM:它可以應(yīng)用于不具備線程安全的第三方模塊(比如php3/4/5),且在不支持線程調(diào)試的平臺上易于調(diào)試,而且還具有比workerMPM更高的穩(wěn)定性。

關(guān)于MPM的更多內(nèi)容,請參考其文檔。

模塊

既然內(nèi)存用量是影響性能的重要因素,你就應(yīng)當(dāng)盡量去除你不需要的模塊。如果你將模塊編譯成DSO ,取消不必要的模塊就是一件非常簡單的事情:注釋掉LoadModule指令中不需要的模塊。

如果你已經(jīng)將模塊靜態(tài)鏈接進Apache二進制核心,你就必須重新編譯Apache并去掉你不想要的模塊。

增減模塊牽涉到的一個問題是:究竟需要哪些模塊、不需要哪些模塊?這取決于服務(wù)器的具體情況。一般說來,至少要包含下列模塊:mod_mime, mod_dir, mod_log_config 。你也可以不要mod_log_config ,但是一般不推薦這樣做。

原子操作

一些模塊,比如mod_cacheworker使用APR(Apache可移植運行時)的原子API。這些API提供了能夠用于輕量級線程同步的原子操作。

默認情況下,APR在每個目標OS/CPU上使用其最有效的特性執(zhí)行這些操作。比如許多現(xiàn)代CPU的指令集中有一個原子的比較交換(compare-and-swap, CAS)操作指令。在一些老式平臺上,APR默認使用一種緩慢的、基于互斥執(zhí)行的原子API以保持對沒有CAS指令的老式CPU的兼容。如果你只打算在新式的CPU上運行Apache,你可以在編譯時使用 --enable-nonportable-atomics 選項:

./buildconf
./configure --with-mpm=worker --enable-nonportable-atomics=yes

--enable-nonportable-atomics 選項只和下列平臺相關(guān):

  • SPARC上的Solaris
    默認情況下,APR使用基于互斥執(zhí)行的原子操作。如果你使用 --enable-nonportable-atomics 選項,APR將使用SPARC v8plus操作碼來加快基于硬件的CAS操作。注意,這僅對UltraSPARC CPU有效。
  • x86上的Linux
    默認情況下,APR在Linux上使用基于互斥執(zhí)行的原子操作。如果你使用 --enable-nonportable-atomics 選項,APR將使用486操作碼來加快基于硬件的CAS操作。注意,這僅對486以上的CPU有效。

mod_status 和 "ExtendedStatus On"

如果Apache在編譯時包含了mod_status ,而且在運行時設(shè)置了"ExtendedStatus On",那么Apache會對每個請求調(diào)用兩次gettimeofday()(或者根據(jù)操作系統(tǒng)的不同,調(diào)用times())以及(1.3版之前)幾個額外的time()調(diào)用,使?fàn)顟B(tài)記錄帶有時間標志。為了得到最佳性能,可以設(shè)置"ExtendedStatus off"(這也是默認值)。

多socket情況下的串行accept

警告

這部分內(nèi)容尚未完全根據(jù)Apache2.0中的變化進行更新 。一些信息依然有效,使用中請注意。

這里要說的是 Unix socket API 的一個缺點。假設(shè)web服務(wù)器使用了多個Listen語句監(jiān)聽多個端口或者多個地址,Apache會使用select()以檢測每個socket是否就緒。select()會表明一個socket有至少一個連接正等候處理。由于Apache的模型是多子進程的,所有空閑進程會同時檢測新的連接。一個很天真的實現(xiàn)方法是這樣的(這些例子并不是源代碼,只是為了說明問題而已):

for (;;) {
for (;;) {
fd_set accept_fds;

FD_ZERO (&accept_fds);
for (i = first_socket; i <= last_socket; ++i) {
FD_SET (i, &accept_fds);
}
rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
if (rc < 1) continue;
new_connection = -1;
for (i = first_socket; i <= last_socket; ++i) {
if (FD_ISSET (i, &accept_fds)) {
new_connection = accept (i, NULL, NULL);
if (new_connection != -1) break;
}
}
if (new_connection != -1) break;
}
process the new_connection;
}

這種天真的實現(xiàn)方法有一個嚴重的"饑餓"問題。如果多個子進程同時執(zhí)行這個循環(huán),則在多個請求之間,進程會被阻塞在select ,隨即進入循環(huán)并試圖accept此連接,但是只有一個進程可以成功執(zhí)行(假設(shè)還有一個連接就緒),而其余的則會被阻塞accept 。這樣,只有那一個socket可以處理請求,而其他都被鎖住了,直到有足夠多的請求將它們喚醒。此"饑餓"問題在PR#467中有專門的講述。目前至少有兩種解決方案。

一種方案是使用非阻塞型socket ,不阻塞子進程并允許它們立即繼續(xù)執(zhí)行。但是這樣會浪費CPU時間。設(shè)想一下,select有10個子進程,當(dāng)一個請求到達的時候,其中9個被喚醒,并試圖accept此連接,繼而進入select循環(huán),無所事事,并且其間沒有一個子進程能夠響應(yīng)出現(xiàn)在其他socket上的請求,直到退出select循環(huán)。總之,這個方案效率并不怎么高,除非你有很多的CPU,而且開了很多子進程。

另一種也是Apache所使用的方案是,使內(nèi)層循環(huán)的入口串行化,形如(不同之處以高亮顯示):

for (;;) {
accept_mutex_on ();
for (;;) {
fd_set accept_fds;

FD_ZERO (&accept_fds);
for (i = first_socket; i <= last_socket; ++i) {
FD_SET (i, &accept_fds);
}
rc = select (last_socket+1, &accept_fds, NULL, NULL, NULL);
if (rc < 1) continue;
new_connection = -1;
for (i = first_socket; i <= last_socket; ++i) {
if (FD_ISSET (i, &accept_fds)) {
new_connection = accept (i, NULL, NULL);
if (new_connection != -1) break;
}
}
if (new_connection != -1) break;
}
accept_mutex_off ();
process the new_connection;
}

函數(shù)accept_mutex_onaccept_mutex_off實現(xiàn)了一個互斥信號燈,在任何時刻只被為一個子進程所擁有。實現(xiàn)互斥的方法有多種,其定義位于src/conf.h(1.3以前的版本)或src/include/ap_config.h(1.3或以后的版本)中。在一些根本沒有鎖定機制的體系中,使用多個Listen指令就是不安全的。

AcceptMutex指令被用來改變在運行時使用的互斥方案。

AcceptMutex flock

這種方法調(diào)用系統(tǒng)函數(shù)flock()來鎖定一個加鎖文件(其位置取決于LockFile指令)。

AcceptMutex fcntl

這種方法調(diào)用系統(tǒng)函數(shù)fcntl()來鎖定一個加鎖文件(其位置取決于LockFile指令)。

AcceptMutex sysvsem

(1.3及更新版本)這種方案使用SysV風(fēng)格的信號燈以實現(xiàn)互斥。不幸的是,SysV風(fēng)格的信號燈有一些副作用,其一是,Apache有可能不能在結(jié)束以前釋放這種信號燈(見ipcs()的man page),另外,這種信號燈API給與網(wǎng)絡(luò)服務(wù)器有相同uid的CGI提供了拒絕服務(wù)攻擊的機會(所有CGI,除非用了類似suexeccgiwrapper)。鑒于此,在多數(shù)體系中都不用這種方法,除了IRIX(因為前兩種方法在IRIX中代價太高)。

AcceptMutex pthread

(1.3及更新版本)這種方法使用了POSIX互斥,按理應(yīng)該可以用于所有完整實現(xiàn)了POSIX線程規(guī)范的體系中,但是似乎只能用在Solaris2.5及更新版本中,甚至只能在某種配置下才正常運作。如果遇到這種情況,則應(yīng)該提防服務(wù)器的掛起和失去響應(yīng)。只提供靜態(tài)內(nèi)容的服務(wù)器可能不受影響。

AcceptMutex posixsem

(2.0及更新版本)這種方法使用了POSIX信號燈。如果一個運行中的線程占有了互斥segfault ,則信號燈的所有者將不會被恢復(fù),從而導(dǎo)致服務(wù)器的掛起和失去響應(yīng)。

如果你的系統(tǒng)提供了上述方法以外的串行機制,那就可能需要為APR增加代碼(或者提交一個補丁給Apache)。

還有一種曾經(jīng)考慮過但從未予以實施的方案是使循環(huán)部分地串行化,即只允許一定數(shù)量的進程進入循環(huán)。這種方法僅在多個進程可以同時進行的多處理器的系統(tǒng)中才是有價值的,而且這樣的串行方法并沒有占用整個帶寬。它也許是將來研究的一個領(lǐng)域,但是由于高度并行的網(wǎng)絡(luò)服務(wù)器并不符合規(guī)范,所以其被優(yōu)先考慮的程度會比較低。

當(dāng)然,為了得到最佳性能,最后就根本不使用多個Listen語句。但是上述內(nèi)容還是值得讀一讀。

單socket情況下的串行accept

上述對多socket的服務(wù)器進行了一流的講述,那么對單socket的服務(wù)器又怎樣呢?理論上似乎應(yīng)該沒有什么問題,因為所有進程在連接到來的時候可以由accept()阻塞,而不會產(chǎn)生進程"饑餓"的問題,但是在實際應(yīng)用中,它掩蓋了與上述非阻塞方案幾乎相同的問題。按大多數(shù)TCP棧的實現(xiàn)方法,在單個連接到來時,內(nèi)核實際上喚醒了所有阻塞在accept的進程,但只有一個能得到此連接并返回到用戶空間,而其余的由于得不到連接而在內(nèi)核中處于休眠狀態(tài)。這種休眠狀態(tài)為代碼所掩蓋,但的確存在,并產(chǎn)生與多socket中采用非阻塞方案相同的負載尖峰的浪費。

同時,我們發(fā)現(xiàn)在許多體系結(jié)構(gòu)中,即使在單socket的情況下,實施串行化的效果也不錯,因此在幾乎所有的情況下,事實上就都這樣處理了。在Linux(2.0.30,雙Pentium pro 166/128M RAM)下的測試顯示,對單socket,串行化比不串行化每秒鐘可以處理的請求少了不到3%,但是,不串行化對每一個請求多了額外的100ms的延遲,此延遲可能是因為長距離的網(wǎng)絡(luò)線路所致,并且僅發(fā)生在LAN中。如果需要改變對單socket的串行化,可以定義SINGLE_LISTEN_UNSERIALIZED_ACCEPT ,使單socket的服務(wù)器徹底放棄串行化。

延遲的關(guān)閉

正如draft-ietf-http-connection-00.txt section 8所述,HTTP服務(wù)器為了可靠地實現(xiàn)此協(xié)議,需要單獨地在每個方向上關(guān)閉通訊(重申一下,一個TCP連接是雙向的,兩個方向之間是獨立的)。在這一點上,其他服務(wù)器經(jīng)常敷衍了事,但從1.2版本開始被Apache正確實現(xiàn)了。

但是增加了此功能以后,由于一些Unix版本的短見,隨之也出現(xiàn)了許多問題。TCP規(guī)范并沒有規(guī)定FIN_WAIT_2必須有一個超時,但也沒有明確禁止。在沒有超時的系統(tǒng)中,Apache1.2經(jīng)常會陷于FIN_WAIT_2狀態(tài)中。多數(shù)情況下,這個問題可以用供應(yīng)商提供的TCP/IP補丁予以解決。而如果供應(yīng)商不提供補丁(指SunOS4 -- 盡管用戶們持有允許自己修補代碼的許可證),那么只能關(guān)閉此功能。

實現(xiàn)的方法有兩種,其一是socket選項SO_LINGER ,但是似乎命中注定,大多數(shù)TCP/IP棧都從未予以正確實現(xiàn)。即使在正確實現(xiàn)的棧中(指Linux2.0.31),此方法也被證明其代價比下一種方法高昂。

Apache對此的實現(xiàn)代碼大多位于函數(shù)lingering_close(位于http_main.c)中。此函數(shù)大致形如:

void lingering_close (int s)
{
char junk_buffer[2048];

/* shutdown the sending side */
shutdown (s, 1);

signal (SIGALRM, lingering_death);
alarm (30);

for (;;) {
select (s for reading, 2 second timeout);
if (error) break;
if (s is ready for reading) {
if (read (s, junk_buffer, sizeof (junk_buffer)) <= 0) {
break;
}
/* just toss away whatever is here */
}
}

close (s);
}

此代碼在連接結(jié)束時多了一些開銷,但這是可靠實現(xiàn)所必須的。由于HTTP/1.1越來越流行,而且所有連接都是穩(wěn)定的,此開銷將由更多的請求共同分擔(dān)。如果你要玩火去關(guān)閉這個功能,可以定義NO_LINGCLOSE ,但絕不推薦這樣做。尤其是,隨著HTTP/1.1中管道化穩(wěn)定連接的啟用,lingering_close已經(jīng)成為絕對必須。而且,管道化連接速度更快,應(yīng)該考慮予以支持。

Scoreboard 文件

Apache父進程和子進程通過scoreboard進行通訊。通過共享內(nèi)存來實現(xiàn)當(dāng)然是最理想的。在我們曾經(jīng)實踐過或者提供了完整移植的操作系統(tǒng)中,都使用共享內(nèi)存,其余的則使用磁盤文件。磁盤文件不僅速度慢,而且不可靠(功能也少)。仔細閱讀你的體系所對應(yīng)的src/main/conf.h文件,并查找USE_MMAP_SCOREBOARDUSE_SHMGET_SCOREBOARD 。定義其中之一(或者分別類似HAVE_MMAP和HAVE_SHMGET),可以使共享內(nèi)容的相關(guān)代碼生效。如果你的系統(tǒng)提供其他類型的共享內(nèi)容,則需要修改src/main/http_main.c文件,并把必需的掛鉤添加到服務(wù)器中。(也請發(fā)送一個補丁給我們)

注意:在對Linux的Apache1.2移植版本之前,沒有使用內(nèi)存共享,此失誤使Apache的早期版本在Linux中表現(xiàn)很差。

DYNAMIC_MODULE_LIMIT

如果你不想使用動態(tài)加載模塊(或者是因為看見了這段話,或者是為了獲得最后一點點性能上的提高),可以在編譯服務(wù)器時定義 -DDYNAMIC_MODULE_LIMIT=0 ,這樣可以節(jié)省為支持動態(tài)加載模塊而分配的內(nèi)存。

附錄:蹤跡的詳細分析

在Solaris8的MPM中,Apache2.0.38使用一個系統(tǒng)調(diào)用以收集蹤跡:

truss -l -p httpd_child_pid.

-l 參數(shù)使truss記錄每個執(zhí)行系統(tǒng)調(diào)用的LWP(lightweight process--Solaris核心級線程)的ID。

其他系統(tǒng)可能使用不同的系統(tǒng)調(diào)用追蹤工具,諸如strace, ktrace, par ,其輸出都是相似的。

下例中,一個客戶端向httpd請求了一個10KB的靜態(tài)文件。對非靜態(tài)或內(nèi)容協(xié)商請求的記錄會有很大不同(有時也很難看明白)。

/67:    accept(3, 0x00200BEC, 0x00200C0C, 1) (sleeping...)
/67:    accept(3, 0x00200BEC, 0x00200C0C, 1)            = 9

下例中,監(jiān)聽線程是 LWP #67 。

注意對accept()串行化支持的匱乏。與這個特殊平臺對應(yīng)的MPM在默認情況下使用非串行的accept ,除了在監(jiān)聽多個端口的時候。
/65:    lwp_park(0x00000000, 0)                         = 0
/67:    lwp_unpark(65, 1)                               = 0

接受了一個連接后,監(jiān)聽線程喚醒一個工作線程以處理此請求。下例中,處理請求的那個工作線程是 LWP #65 。

/65:    getsockname(9, 0x00200BA4, 0x00200BC4, 1)       = 0

為了實現(xiàn)虛擬主機,Apache需要知道接受連接的本地socket地址。在許多情況下,有可能無須執(zhí)行此調(diào)用(比如沒有虛擬主機,或者Listen指令中沒有使用通配地址),但是目前并沒有對此作優(yōu)化處理。

/65:    brk(0x002170E8)                                 = 0
/65:    brk(0x002190E8)                                 = 0

brk()調(diào)用是從堆中分配內(nèi)存的,它在系統(tǒng)調(diào)用記錄中并不多見,因為httpd在多數(shù)請求處理中使用了自己的內(nèi)存分配器(apr_poolapr_bucket_alloc)。下例中,httpd剛剛啟動,所以它必須調(diào)用malloc()以分配原始內(nèi)存塊用于自己的內(nèi)存分配器。

/65:    fcntl(9, F_GETFL, 0x00000000)                   = 2
/65:    fstat64(9, 0xFAF7B818)                          = 0
/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B910, 2190656) = 0
/65:    fstat64(9, 0xFAF7B818)                          = 0
/65:    getsockopt(9, 65535, 8192, 0xFAF7B918, 0xFAF7B914, 2190656) = 0
/65:    setsockopt(9, 65535, 8192, 0xFAF7B918, 4, 2190656) = 0
/65:    fcntl(9, F_SETFL, 0x00000082)                   = 0

接著,工作線程使客戶端連接處于非阻塞模式。setsockopt()getsockopt()調(diào)用是Solaris的libc對socket執(zhí)行fcntl()所必須的。

/65:    read(9, " G E T   / 1 0 k . h t m".., 8000)     = 97

工作線程從客戶端讀取請求。

/65:    stat("/var/httpd/apache/httpd-8999/htdocs/10k.html", 0xFAF7B978) = 0
/65:    open("/var/httpd/apache/httpd-8999/htdocs/10k.html", O_RDONLY) = 10

這里,httpd被配置為"Options FollowSymLinks"和"AllowOverride None"。所以,無須對每個被請求文件路徑中的目錄執(zhí)行lstat(),也不需要檢查.htaccess文件,它簡單地調(diào)用stat()以檢查此文件是否存在,以及是一個普通的文件還是一個目錄。

/65:    sendfilev(0, 9, 0x00200F90, 2, 0xFAF7B53C)      = 10269

此例中,httpd可以通過單個系統(tǒng)調(diào)用sendfilev()發(fā)送HTTP響應(yīng)頭和被請求的文件。Sendfile因操作系統(tǒng)會有所不同,有些系統(tǒng)中,在調(diào)用sendfile()以前,需要調(diào)用write()writev()以發(fā)送響應(yīng)頭。

/65:    write(4, " 1 2 7 . 0 . 0 . 1   -  ".., 78)      = 78

write()調(diào)用在訪問日志中對請求作了記錄。注意,其中沒有對time()的調(diào)用的記錄。與Apache1.3不同,Apache2.0使用gettimeofday()以查詢時間。在有些操作系統(tǒng)中,比如Linux和Solaris,gettimeofday有一個優(yōu)化的版本,其開銷比一個普通的系統(tǒng)調(diào)用要小一點。

/65:    shutdown(9, 1, 1)                               = 0
/65:    poll(0xFAF7B980, 1, 2000)                       = 1
/65:    read(9, 0xFAF7BC20, 512)                        = 0
/65:    close(9)                                        = 0

工作線程對連接作延遲的關(guān)閉。

/65:    close(10)                                       = 0
/65:    lwp_park(0x00000000, 0)         (sleeping...)

最后,工作線程關(guān)閉發(fā)送完的文件和塊,直到監(jiān)聽進程把它指派給另一個連接。

/67:    accept(3, 0x001FEB74, 0x001FEB94, 1) (sleeping...)

其間,監(jiān)聽進程可以在把一個連接指派給一個工作進程后立即接受另一個連接(但是如果所有工作進程都處于忙碌狀態(tài),則會受MPM中的一些溢出控制邏輯的制約)。雖然在此例中并不明顯,在工作線程剛接受了一個連接之后,下一個accept()會(在高負荷的情況下更會)立即并行產(chǎn)生。

Previous article: Next article: