Apache ——飛機中的戰鬥機
在互聯網中瀏覽網頁都需要使用HTTP(超文本傳輸協議),而Apache只是HTTP協議的一個實現程序 , HTTPD作為其主程序運行,目前常用有兩個版本CentOS6(httpd 2.2)、CentOS7 (httpd 2.4)。
一次完整的HTTP請求(事務):
1)Client請求網頁資源、與Server建立連接(三次握手)、Server處理請求(允許或拒絕)。
2) 如果Server接受來自Client的請求,則根據Apache的多進程處理模型(MPM),挑選一個子進程或線程根據http Request 報文中的Headers 進行分析處理。
3)Server根據Request headers中定義的方法(method)去訪問並獲取資源。
4)構建響應報文(Http Response),使用MIME編碼方式將不同的資源類型編碼,也可能是重定向資源。
5)發送響應報文, 到此步驟如果是短連接方式,一次http請求的過程就完成了,如果是長連接方式則繼續請求資源。
6)記錄日誌。
Http Request報文:
<Method> <Request-URL> <Http_Version> <Headers>
<entity-body>
|
Method 表示Client對資源的請求方法,常見的有:
Get 下載資源
Put 將請求報文中的”entity-body” 上傳到服務器上
Head 從服務器獲取請求資源的響應頭部
Delete 在服務器上刪除資源
Options 請求資源可使用的Method
Trace 追蹤請求到達中間經過的代理服務器
Request-URL 表示資源在網絡中的位置
格式:
協議://用戶名:密碼@域名:端口號/目錄/文件名.文件後綴?參數=值#標誌
Http_Version 表示HTTP協議使用的版本號,通常為:
http/1.0
http/1.1
Headers 包含請求或響應資源時需要協商的信息
通用首部:
Data 創建時間
Connection 連接狀態是否為長連接
Via 顯示報文經過的中間節點,是否存在代理
Cache-control 控制緩存
請求首部:
Accept-charset Client表示自己能接受的字符編碼
Accept-Encoding Client表示自己能接收的編碼格式
Accept-Language Client表示自己能接受的語言
信息類請求:
Client-IP 客戶端IP地址
Host 表示請求服務器的名稱和端口
Referer 告訴服務器Client是從哪個連接跳轉過來的
User-Agent 表示客戶端代理程序
Http Response 報文:
<Version> <Status> <reason-phrase> <headers>
<entity-body> |
Version 為http協議的版本
Status 為本次響應結果的狀態碼
1XX: 100-101 信息類的響應碼
2XX: 200-206 成功類的響應碼
200 成功,OK
3XX: 300-305 重定向類的響應碼
301 請求的資源已被刪除,永久重定向
302 請求的資源已被刪除,臨時重定向
4XX: 400-415 錯誤類信息,客戶端錯誤
401 需要認證,提供用戶名、密碼
404 請求的網頁不存在
403 請求被禁止,Forbiden
5XX:500-505 錯誤類信息,服務端錯誤
500 服務器內部錯誤
Reason-phrase 為本次響應碼的簡要短語
Headers 響應頭部
信息類:
Age 資源的有效時間
Server 服務器的軟件名稱
協商首部:
Accept-ranges: 服務器可接受的請求範圍
Vary:服務器查看其它首部列表
安全響應首部:
Set-Cookie 向客戶端設置Cookie
Set-Cookie2 向客戶端設置Cookie2
長、短連接
通常一個網頁包含多個資源,如果每個資源都需要一次建立連接、HTTP Request、Response 、拆除連接,這就叫短連接,這種方式比較浪費資源。
長連接,此方式建立連接後可以進行多次請求、響應資源。 但如果在高並發模式下,使用長連接,而用戶又不請求資源因長連接方式占用著進程,別人也請求不了資源。
KeepAlive Off|ON ON表示開啟長連接、OFF表示關閉
MaxKeepAliveRequests 100 限制進程當請求量到100時,需要重新建立連接
KeepAliveTimeout 15 限制進程當超時15秒後,需要重新建立連接
修改Apahce 服務器為長連接方式: [root@7-1 ]# vim /etc/httpd/conf/httpd.conf KeepAlive on MaxKeepaliveRequests 100 KeepAliveTimeOut 10 長連接測試,可以對資源進行多次請求,連接不會斷: [root@7-1 conf]# telnet 172.16.1.50 80 Trying 172.16.1.50... Connected to 172.16.1.50. Escape character is '^]'. GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:50:49 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Content-Type: text/html
hello httpd 2.4
GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:51:02 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Content-Type: text/html
hello httpd 2.4 Connection closed by foreign host.
[root@7-1 ]# vim /etc/httpd/conf/httpd.conf KeepAlive OFF
[root@7-1 conf]# !sys systemctl restart httpd
短連接測試,一次連接只能有一個請求: [root@7-1 conf]# telnet 172.16.1.50 80 Trying 172.16.1.50... Connected to 172.16.1.50. Escape character is '^]'. GET / HTTP/1.1 HOST:172.16.1.50
HTTP/1.1 200 OK Date: Tue, 22 May 2018 11:54:26 GMT Server: Apache/2.4.33 (Unix) Last-Modified: Tue, 22 May 2018 01:25:57 GMT ETag: "11-56cc14cd527d5" Accept-Ranges: bytes Content-Length: 17 Connection: close Content-Type: text/html
hello httpd 2.4 Connection closed by foreign host. |
MPM (Multi-Processing Module) 多進程模型
1. perfork MPM
Perfork模型通過預先啟動進程,由一個單獨的控制進程(父進程)負責產生子進程,這些子進程用於監聽請求並作出應答。並且Apache總是試圖保持一些備用的(spare)或者是空閑的子進程用於迎接即將到來的請求。這樣客戶端就不需要在得到服務前等候子進程的產生,減少頻繁創建、銷毀進程的開銷。
優點:響應速度快、穩定
缺點:進程占用系統資源過多、不適合高並發環境。
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf <IfModule prefork.c> StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 </IfModule> |
StartServers 表示預先啟動的進程數,不包含主進程
MinSpareServers 表示最少空閑進程數
MaxSpareServers 表示最多空閑進程數
ServerLimit 用於限制MaxClient
MaxClient 表示能處理最大並發請求數
MaxRequestsPerChild 限制進程處理多少個請求之後自動銷毀,值為0 表示永不銷毀
2. woker MPM
woker模型使用多進程和多線程的混合方式,也需要由主進程事先fork創建子進程(數量少),每個子進程可以建立ThreadsPerChild數量的服務線程和一個監聽線程,該監聽線程監聽接入請求並將其傳遞給服務線程處理和應答。
之所以不完全使用多線程是因為線程之間內存共享,如果一個線程掛了,整個進程都掛了,所以還需要使用多進程,這樣一個進程奔潰也只影響一部分內容。
優點:使用線程方式占用資源少,線程之間共享內存,支持更高的並發。
缺點:線程共享,穩定性差; 在長連接模式下
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf <IfModule worker.c> StartServers 4 MaxClients 300 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 MaxRequestsPerChild 0 </IfModule> |
StartServers 表示啟動的進程數
MaxClient 表示能處理最大並發請求數
MiniSpareThreads 表示最少空閑的線程數
MaxSpareThreads 表示最大空閑的線程數
ThreadsPerChild 表示每個進程擁有對最大線程數
MaxRequestsPerChild 表示限制進程處理多少個請求之後自動銷毀,值為0 表示永不銷毀
3. event MPM
這個是Apache中最新的模式,在現在版本裏的已經是穩定可用的模式。它和worker模式很像,最大的區別在於,它解決了keep-alive場景下,長期被占用的線程的資源浪費問題(某些線程因為被keep-alive,空掛在哪裏等待,中間幾乎沒有請求過來,甚至等到超時)。event MPM中,會有一個專門的線程來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務線程,執行完畢後,又允許它釋放。這樣增強了高並發場景下的請求處理能力。
event MPM在遇到某些不兼容的模塊時,會失效,將會回退到worker模式,一個工作線程處理一個請求。官方自帶的模塊,全部是支持event MPM的。
Apache中的配置方式:
[root@el6 ]# vim /etc/httpd/conf/httpd.conf <IfModule mpm_event_module> StartServers 3 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 0 </IfModule> |
想知道當前HTTPD工作在什麽MPM模型下,使用以下命令查看
Httpd –M | grep mpm
Gzip 、 DEFLATE
DEFLATE是一個無專利的壓縮算法,它可以實現無損數據壓縮,有眾多開源的實現算法。該標準的實施庫大多數人用的是zlib的。zlib庫提供用於壓縮和解壓縮使用DEFLATE/INFLATE的數據。zlib庫還提供了一種數據格式,混淆的命名ZLIB,它包裝DEFLATE壓縮數據,具有報頭和校驗和。
GZIP是使用DEFLATE進行壓縮數據的另一個壓縮庫。事實上,GZIP的大多數實現實際使用zlib庫的內部進行DEFLATE/ INFLATE壓縮操作。GZIP產生其自己的數據格式,混淆的命名GZIP,它包裝DEFLATE壓縮數據,具有報頭和校驗和。
客戶端與服務器使用Accept-Encoding和Content-Encoding標頭完成協商壓縮方式。有兩種常用的HTTP壓縮:DEFLATE和GZIP。
Apache2.2加載模塊 Vim /etc/httpd/conf/httpd.conf LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so Apache2.4 加載模塊 Vim /etc/httpd/conf.modules.d/00-base.conf LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so |
DEFLATE 配置方式: [root@7-1 ]# vim /etc/httpd/conf/httpd.conf <IfModule mod_deflate.c> SetOutPutFilter DEFLATE SetEnvIfNoCase Request_URL .(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNocase Request_URL .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .(?:pdf|doc|avi|mov|mp3|rm)$ no-gzip dont-vary AddOutPutFilterByType DEFLATE text/* AddOutPutFilterByType DEFLATE application/x-javascript application/xml application/x-javascript DeflateCompressionLevel 9 </IfModule>
[root@7-1 conf]# !sys systemctl restart httpd
按F12打開Google瀏覽器的調試功能:
關閉壓縮功能: #<IfModule mod_deflate.c> # SetOutPutFilter DEFLATE # SetEnvIfNoCase Request_URL .(?:gif|jpe?g|png)$ no-gzip dont-vary # SetEnvIfNocase Request_URL .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary # SetEnvIfNoCase Request_URI .(?:pdf|doc|avi|mov|mp3|rm)$ no-gzip dont-vary # AddOutPutFilterByType DEFLATE text/* # AddOutPutFilterByType DEFLATE application/x-javascript application/xml application/x-javascript # DeflateCompressionLevel 9 # #</IfModule>
systemctl restart httpd
關閉Deflate功能後,發現響應頭部已經沒有gzip字樣,並且響應大小也從276變為465了 |
裝載模塊 mod_gzip 可能需要自己編譯,另外編譯過程依賴httpd-devel包 ,因為需要APSX |
Gzip配置方式: # mod_gzip mod_gzip_on Yes mod_gzip_dechunk Yes mod_gzip_item_include file .(html?|txt|css|js|php|pl)$ mod_gzip_item_include handler ^cgi-script$ mod_gzip_item_include mime ^text/.* mod_gzip_item_include mime ^application/x-javascript.* mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* |
Httpd配置文件組成:
/etc/httpd/conf/httpd.conf #主配置文件
/etc/httpd/conf.d/*.conf #額外提供的配置文件
[root@el6 ~]# grep 'Section' /etc/httpd/conf/httpd.conf
### Section 1: Global Environment 定義全局環境變量
### Section 2: 'Main' server configuration 定義Main Server站點
### Section 3: Virtual Hosts 定義虛擬主機,與Main Server沖突
站點訪問控制:
在httpd中可基於兩種類型的路徑指明對哪些資源進行訪問控制。
基於文件系統中的路徑控制:
<Directory “DIRECTORY_NAME”>
…
</Directory>
基於URL路徑控制:
<Location “URL_NAME”>
…
</Location>
在<Directory>、<Location>中可使用指令:
Options用於設定在定義的資源中,可使用選項
Options None ALL Indexes FollowSymLinks SymLinksIfOwnerMatch … None 表示不使用任何選項 ALL 表示使用所有選項 Indexes 表示使用”索引”,當目錄中沒有”DirectoryIndex”定義的主頁時,是否列出文件索引,在創建文件下載站點時有用。如果不生效,則將welcome頁面刪除。 FollowSymLinks 表示如果在網站目錄中有符號鏈接文件,是否跟蹤 SymLinksIfOwnerMatch 表示符號鏈接的屬主是本人時才跟蹤
|
基於源IP對資源做訪問控制:
Httpd2.2:
白名單,只允許被Allow from 匹配的地址訪問
Oder allow,deny
Allow from ip/net
黑名單,被Deny from匹配的地址都無權訪問資源
Oder deny,allow
Deny from IPADDR
IPADDR:
172.16.1.1 定義單個IP
172.16.0.0 根據地址主類自動判斷網段掩碼
172.16.0.0/16
172.16.0.0/255.255.0.0
Httpd2.4:
Require all granted 允許所有人訪問
Require all deny 拒絕所有人訪問
Require ip IPADDR 允許制定IP地址能訪問
IPADDR:
172.16.1.1 定義單個IP
172.16.0.0 根據地址主類自動判斷網段掩碼
172.16.0.0/16
172.16.0.0/255.255.0.0
註意:在Httpd2.4中,每個目錄都需要明確授權,否則是無法訪問的
基於賬號、密碼做訪問控制:
Basic——賬號、密碼明文傳輸方式認證:
AuthType Basic AuthName “ DOMAIN_NAME” #提示用戶,此資源為什麽需要認證 AuthUserFile “/PATH/TO/USER_FILE ” #用戶、密碼文件存放位置 Require user USERNAME1 USERNAME2 #允許那個用戶訪問 Require valid-user #允許AuthUserFile中所有有效用戶訪問
|
另外還可以基於組對用戶控制:
AuthType Basic AuthNmae “DOMAIN_NAME” AuthUserFile “/PATH/TO/GROUP_FILE” AuthGrupFile “/PATH/TO/GROUP_FILE” Require group group_name1 group_name2
|
GroupFile 定義格式:
組名:用戶名1 用戶名2
UserFile需要使用htpasswd 命令生成:
htpasswd -c -m /etc/httpd/conf/.htaccess USER_NAME
-c 表示首次需要創建該文件,添加用戶則不需要此選項
-m 表示存放的密碼使用md5加密存放
-s 表示存放的密碼使用sha1加密存放
-D 表示刪除指定用戶
Degist——賬號、密碼密文方式傳輸認證:
AuthType Degist AuthName “DOMAIN_NAME” AuthUserFile “/PATH/TO/USER_FILE” Require user USER_NAME1 USER_NAME2 |
USER_FILE需要使用htdigst命令生成:
Usage: htdigest [-c] passwordfile DOMAIN_NAME username
註意:DOMAIN_NAME要與配置文件中定義的AuthName匹配,否則驗證無法通過
路徑別名
Alias 用於在Apache 定義URL與本地文件系統中資源的映射關系。
Usage : Alias /URL /PATH/TO/SOMEDIR/
/URL 表示以根為起始位置的訪問入口
/PATH/TO/SOMEDIR/ 本地資源的路徑,路徑結尾有/ ,最後URL後也接/
例如:
Alias /doc /usr/share/doc
Alias /doc/ /usr/share/doc/
<Directory ‘/usr/share/doc’>
Optiosn indexes FollowSymlinks
Require all granted
</Directory>
設置默認字符集
AddDefaultCharset UTF-8
Server-status
Apache 內置的狀態頁。
<Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from localhost </Location> |
日誌:
錯誤日誌: /var/log/httpd/error_log
訪問日誌:/var/log/httpd/access_log
日誌中的內容都由一下配置定義:
ErrorLog "logs/error_log" LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %b" common CustomLog "logs/access_log" combined |
ErrorLog 用於設定訪問日誌的存放路徑
LogForat 用於自定義日誌格式,在Apache2.4中還支持在模塊定義日誌功能
%h ClientIP %l Client 遠程登錄名字 來自Identd %u 認證時Client使用的認證名字 %t Client訪問的時間 %r Request報文的第一行 %>s 記錄最終請求的狀態碼(如果有重定向) %b 傳送資源的大小 %{Referer}i 表示訪問的來源,上一個鏈接 %{User-Agent}i 表示用戶使用的Agent信息(瀏覽器) |
CustomLog 用於設定訪問日誌的存放路徑與日誌格式
虛擬主機:
註意:使用虛擬主機時,最好把Main Server停用,否則會沖突.
#DocumentRoot /var/www/html
定義虛擬主機的三種方式:
基於IP(前提是主機有多個IP地址):
Httpd2.4中定義虛擬主機: Httpd2.2中不需要Require all grantd <VirtualHost 192.168.1.1:80> DocumentRoot /www/vhdocs1/ DirectoryIndex index.html index.php Require all grantd </VirutalHost> <VirtualHost 192.168.1.2:80> DocumentRoot /www/vhdocs2/ DirectoryIndex index.html index.php Require all grantd </VirutalHost> |
基於端口:
Httpd2.4中定義虛擬主機: Httpd2.2中不需要Require all grantd Listen 80 Listen 8080 <VirtualHost *:80> DocumentRoot /www/vhdocs1/ DirectoryIndex index.html index.php Require all grantd </VirutalHost>
<VirtualHost *:8080> DocumentRoot /www/vhdocs2/ DirectoryIndex index.html index.php Require all grantd </VirutalHost>
|
基於域名:
Httpd2.2中還需要啟用一條命令: NameVirtualHost *:80 不需要Require all grantd Httpd2.4定義方式: <VirtualHost *:80> DocumentRoot /www/vhdocs1/ ServerName www.jying.com DirectoryIndex index.html index.php Require all grantd </VirutalHost>
<VirtualHost *:80> DocumentRoot /www/vhdocs2/ ServerName web.jying.com DirectoryIndex index.html index.php Require all grantd </VirutalHost> |
Apache ——飛機中的戰鬥機