前言
前言有點長,請耐心看看,也許對你有用呢…
一個多月前,我在寫一篇初始化腳本里面就寫過了什麼一鍵編譯安裝apache,那只是實現了最最基礎
的web頁面功能,簡單的幾行代碼,其實只能起到一定的學習作用,然而在生產中意義是不大的,因爲,
根據實際需要的不同,他們的htppd服務基本都是自定義的,基礎的功能已經不能滿足他們的需求,
他們注重的細節,是每一個頁面的權限,是如何細分每一個功能。
在初創公司,政府網頁,或是沒有什麼流量的小型網站,因爲沒有太多過於複雜的功能需求,也沒有可
怕的用戶併發量,只需要提供最基礎的功能,他們追求的是穩定,一般都會直接使用rpm安裝的方式使
用老舊版本的htppd服務,而且用不了幾臺服務器就能解決。
而在中大型互聯網公司或是電商網站,他們因爲會有恐怖的用戶併發量,他們可能所需要的服務器是一
個天文數字,而且,多用lvs做開始的調度器,然後用nigix做反向代理,再用apache做web服務器,然
後再使用memcached做緩存服務器,在使用php或是perl或是python來處理動態資源,最後使用mysql
或是mariadb來做數據庫(市場的走向是mariadb)。
可以簡單的說成:LNAMPM,這只是一個輪廓,如果再往細分那要用到的東西就太多了…
而這一篇博客我所要講述的就是其中的:
apache做爲web服務器的一些功能的實現,
與如何自定義編譯安裝apache。
httpd的基礎配置介紹
安裝
# yum install httpd
# rpm -qc httpd //查看安裝程序生成的配置文件
基礎配置文件
配置文件:
/etc/httpd/conf/httpd.conf
/etc/httpd/conf.d/*.conf //爲主配置文件提供額外的配置片段。當一個程序的配置文件過大的時候往往就會將其切割成多個片段進行維護
注:httpd的主配置文件並沒有在/etc/httpd下面,而是在/etc/httpd/conf目錄下,是因爲它將/etc/httpd目錄作爲
程序的安裝目錄,也就是程序運行的根目錄。在主配置文件中有定義。
服務腳本:
一般就是服務的啓動或者關閉
/etc/rc.d/init.d/httpd
腳本的配置文件:/etc/sysconfig/httpd
主程序文件:服務程序
/usr/sbin/httpd //默認使用的是prefork
/usr/sbin/httpd.event
/usr/sbin/httpd.worker
日誌文件目錄:
/var/log/httpd
access_log: 訪問日誌(至關重要,用於大數據)
error_log: 錯誤日誌(web服務器啓動或者停止過程中產生的錯誤信息,以及運行過程中的錯誤或者警告信息)
站點文檔目錄:
/var/www/html
httpd常用配置
修改監聽的IP和Port
可以在住配置文件裏面直接修改,也可以在conf.d/目錄下自己以.conf結尾的方式自定義的寫一小段代碼文件,我比較
推薦後者,方便管理,不用老是去主配置文件裏面,面對那一大堆代碼去搜索。
在主配置文件中有這麼一小段代碼:
#
#Listen 12.34.56.78:80
Listen 80
可以直接修改,也可以在去conf.d下創建個文件單獨管理。
1、修改了監聽的端口之後只能重啓
2、省略IP表示監聽本機所有IP
3、Listen可重複監聽多次
持久連接
Persistent Connection: 連接建立,每個資源獲取完成後不會斷開連接,而是繼續等待其他的請求完成
每個客戶端連接到服務器都要進行三次握手四次斷開,這樣會浪費大量的時間,所以就推出了持久連接。但是有副作用
如何斷開:
數量限制:100
時間限制:可配置
副作用:對併發訪問量較大的服務器,持久連接功能會使有些請求得不到響應
折中辦法:使用較短的持久連接時間
httpd-2.4 支持毫秒級持久時間
代碼片:
# vim /etc/httpd/conf/httpd.conf
keepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 15
MPM,多道處理模塊
prefork, worker, event
httpd-2.2不支持同時編譯多個模塊,所以只能編譯時選定一個,rpm安裝的包提供三個二進制程序文件,分別用於實現對不同MPM機制的實現,確認方法:
# ps aux | grep httpd
默認爲/usr/sbin/httpd, 其使用prefork
查看模塊列表:
查看靜態編譯模塊(如果使用的是event模式,那麼則要使用httpd.event -l查看)
# httpd -l
Compiled in modules:
core.c
prefork.c
http_core.c
mod_so.c
查看動態加載模塊:
# httpd -M
更換httpd程序的工作模式:
# vim /etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.worker //取消註釋,將從prefork變成worker模式
HTTPD=/usr/sbin/httpd.event //將worker變成event,表示httpd從worker模式變成event模式
重啓才能生效
prefork的配置:
<IfModule prefork.c>
StartServers 8 //服務器啓動時,啓動的進程數
MinSpareServers 5 //最小空閒進程數
MaxSpareServers 20 //最大空閒進程數
ServerLimit 256 //服務器進程的最大數目值
MaxClients 256 //最大併發請求數
MaxRequestsPerChild 4000 //服務器進程能夠響應的最大請求數目
</IfModule>
worker的配置:
<IfModule worker.c>
StartServers 4
MaxClients 300
MinSpareThreads 25
MaxSpareThreads 75 //最大空閒線程數
ThreadsPerChild 25 //每個進程所能夠啓用的線程數
MaxRequestsPerChild 0 // 每個線程所能夠響應的最大請求數,0表示不作限制
</IfModule>
DSO:動態裝/卸載模塊的實現
# httpd -M //查看內核編譯以及沒有編譯的httpd模塊
配置指令實現模塊加載
LoadModule <mod_name> <mod_path>
也可以直接在配置文件中註釋或者取消註釋實現模塊的裝/卸載
配置之後平滑重啓:
# service httpd reload
定義”Main” server的文檔頁面路徑
代碼片:
[ root@centos6 /etc/httpd/conf ]# vim httpd.conf
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/var/www/html" //修改成你想要的路徑,一般都是在conf.d目錄下,自定義根路徑。
站點訪問控制
可基於兩種類型的路徑指明對哪些資源進行訪問控制
文件系統路徑:
<Directory ""> </Directory> 基於對目錄的訪問控制
<File ""> </File> 基於對文件的訪問控制
<FileMatch ""> </FileMatch> 基於正則表達式。但是建議不要使用,因爲效率低
URL路徑:
<Location ""> </Location> 基於位置來實現訪問
訪問控制機制:
基於來源地址:但是風險比較大,
基於賬號
Directory中”基於來源地址”實現訪問控制
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
(1) Options: 定義用戶在對該目錄下的資源進行訪問時的訪問機制
所有可用特性:Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
Indexs: 頁面索引(這是一項很有用但是很危險的選項,如果是一個提供下載的網站,那麼又非常有用)
FollowSymLinks: 是否允許跟蹤符號鏈接
All:表示開啓options中所有的選項(測試環境中使用這個)
None:表示禁止options中所有的選項(生產環境中一般用這個)
一般的一個網站都有自己定義的默認主頁面,定義在DocumentRoot路徑下的兩個文件
(index.html,index.html.var),如果沒有這兩個文件,那麼在訪問該站點時系統會自動顯示
默認的歡迎信息(/etc/httpd/conf.d/welcome.conf)。如果這個文件也沒有,而且選項Indexs是
啓用的,那麼系統就會將你在該目錄下<Directory "/var/www/html">
的所有文件全部列出來,
可以下載,可以查看。
所有這是一個很危險的用法,但是當我們要用這個網站提供下載的時候又非常有用。
實現方式如下:以/var/www/html路徑爲例.
1、刪除或者重命名/var/www/html下的index.html/index.html.var文件
# mv /var/www/html/index.html{,.bak}
2、刪除或者重命名/etc/httpd/conf.d/welcome.conf
# mv /etc/httpd/conf.d/welcome.conf{,.bak}
3、在主配置文件中將Indexs啓用起來
<Directory "/var/www/html">
Options Indexs
</Directory>
4、重讀配置文件
# service httpd reload
(2) AllowOverride None(無關緊要,一般都是none)
(3) 基於來源地址的訪問控制機制
Order: 檢查次序(allow和deny誰在後面,就是誰對全局進行默認設定)
Order allow, deny //白名單,默認deny(禁止)
Order deny, allow //黑名單,默認allow(允許)
Allow from
Deny from
設置白名單/黑名單之後也可以通過Allow from/Deny from設置特殊的ip,例如:
Order allow, deny 表示禁止所有主機訪問
Deny from 192.168.64.129 表示禁止該ip訪問
Allow from 192.168.64.128 表示允許該ip訪問
來源地址的寫法:
192.168 表示該網絡地址中的所有主機
192.168.0.0
192.168.0.0/16
192.168.0.0/255.255.0.0
如果是不同的ip則使用多次Allow/Deny
定義默認主頁面
[ root@centos6 /etc/httpd/conf ]# vim httpd.conf
DirectoryIndex index.html index.html.var //設置你想要定義的文件爲默認主頁面文件
日誌設定
[ root@centos6 /var/log/httpd ]# ls
access_log error_log
錯誤日誌:
ErrorLog logs/error_log
日誌級別(由低到高):debug, info, notice, warn, error, crit, alert, emerg.
LogLevel warn:默認爲warn,表示從wran到emerg級別的日誌都會被記錄
訪問日誌:
CustomLog logs/access_log combined(表示使用combined日誌格式記錄)
日誌記錄格式:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
%h: 客戶端IP地址
%I: 不怎麼重要,一般都是空
%u:基於認證的用戶,一般也是空
%t: 服務器收到請求的時間
%r: 請求報文的首行信息
%>s: 響應狀態碼
%b:響應報文的大小,大小是字節,不包括響應報文首部
%{Referer}i:請求報文當中"referer"首部的值,當前資源的訪問入口,即從哪個頁面中的超鏈接跳轉而來
%{User-Agent}i:請求報文當中"User-Agent"首部的值,即發出請求用到的應用程序
自己對照着/var/log/httpd/access_log中的記錄信息
路徑別名
在配置文件中的Alias中創建一個別名映射Alias /index.html “/var/www/html/1.html”
將/var/www/html/index.html映射到/var/www/html/1.html上
注:從上面的例子可以看出,要映射的路徑是相對路徑,想對於你定義的DocumentRoot。
而映射之後的路徑一定是絕對路徑,而且要加引號 。
設定默認字符集
[ root@centos6 /etc/httpd/conf ]# vim httpd.conf
AddDefaultCharset UTF-8
(一般稍微有點規模的網站都是用的支持UTF-8格式,可以顯示中文)
基於用戶的訪問控制(重要)
這個訪問控制就是讓用戶輸入用戶名與密碼,才能訪問該路徑下的資源。,如果是一個大型的項目的話一般都是基於表單認證(用戶通過網頁進入了某一個網站,而要想訪問這個網站必須輸入用戶名和密碼)的方式進行認證,而不是基於httpd網頁進行認證。
認證類型:
basic:明文
digest:消息摘要
(雖然這個是加密的,但是很多老版本不支持這個功能,所以一般都是明文的)
basic認證:
(1)定義安全域(按以下格式在主配置文件中任何地方輸入)
<Directory "">
Options None
AllowOverride None
AuthType Basic //基於basic認證
AuthName "String" //提示名稱
AuthUserFile "/etc/httpd/conf.d/.htpasswd" //用戶名放置的位置,一般都是這個目錄
Require user username1.. //用戶白名單
Require valid-user //表示允許所有的用戶登錄
</Directory>
(2) 提供賬號和密碼存儲(文本文件)
使用htpasswd命令進行管理
htpasswd [options] passwordfile username
-c: 自動創建passwordfile,因此,僅應該在添加第一個用戶時使用
-m:md5加密用戶密碼
-s:sha1加密用戶密碼
-D:刪除指定用戶s
# htpasswd -c -m /etc/httpd/conf.d/.htpasswd tom
# htpasswd -m /etc/httpd/conf.d/.htpasswd jerry
注:這裏只有第一次創建這個文件的時候才需要使用-c選項.
(3) 實現基於組進行認證
<Directory "">
Options None
AllowOverride None
AuthType Basic //基於basic認證
AuthName "String" //提示名稱
AuthUserFile "/etc/httpd/conf.d/.htpasswd" //用戶名放置的位置,一般都是這個目錄
AuthGroupFile "/etc/httpd/conf.d/.htgroup" //組存放的位置
Require group GROUP1...
</Directory>
(a) 創建組文件
# vim /etc/httpd/conf.d/.htgroup
webadmin: tom jerry
(b) 修改配置文件
AuthUserFIle "/etc/httpd/conf.d/.htpasswd"
AuthGroupFile "/etc/httpd/conf.d/.htgroup"
Require group webadmin
虛擬主機
有三種實現方案:
基於ip:爲每個虛擬主機準備至少一個ip地址(實際用的比較少)
基於port:爲每個虛擬主機準備至少一個專用port(實際用的更少)
基於hostname:爲每個虛擬主機準備至少一個專用hostname(常用)
注意:可以混合使用上述三種方式中任意方式。一般虛擬主機不與中心主機混用,所以,要使用虛擬主機,先禁用中心主機。
還有注意DNS的配置。
基於虛擬主機的hostname的那個可以使用三臺機器來做,第一臺最DNS服務器,第二臺做web虛擬主機,第三臺做客戶機。
禁用中心主機方式:註釋DocumentRoot
實現方式:
首先註釋DocumentRoot
a) 基於ip實現虛擬主機
(1) 爲主機配置多塊網卡
# ip addr add 192.168.64.127/24 dev eth0
# ip addr //只能用這個命令才能查看增加的ip
(2) 修改主配置文件,添加虛擬主機
<VirtualHost 192.168.64.129:80>
ServerName web1.magedu.com
DocumentRoot "/web/web1"
</VirtualHost>
<VirtualHost 192.168.64.128:80>
ServerName web2.magedu.com
DocumentRoot "/web/web2/htdocs"
</VirtualHost>
<VirtualHost 192.168.64.127:80>
ServerName web3.magedu.com
DocumentRoot "/web/web3/htdocs"
</VirtualHost>
(3) 檢查語法
# httpd -t
(4) 重載
# service httpd reload
(5) 驗證
# curl http://192.168.64.128
# telnet 192.168.64.128 80
b) 基於port實現虛擬主機,與基於ip實現虛擬主機相同,最後就是要重啓一下httpd,注意是重啓。
c) 基於hostname實現虛擬主機。這是當下常用的方法
(1) 註釋主配置文件中第1000行中的NameVirtualHost,並將其IP:Port修改成與虛擬主機一樣
NameVirtualHost 192.168.64.129:80
(2) 修改主配置文件,添加基於hostname的虛擬主機
<VirtualHost 192.168.64.129:80>
ServerName web1.magedu.com
DocumentRoot "/web/web1"
</VirtualHost>
<VirtualHost 192.168.64.129:80>
ServerName web2.magedu.com
DocumentRoot "/web/web2/htdocs"
</VirtualHost>
<VirtualHost 192.168.64.129:80>
ServerName web3.magedu.com
DocumentRoot "/web/web3/htdocs"
</VirtualHost>
(3) 檢查語法與重載
(4) 這也是很關鍵的一點
# vim /etc/hosts
192.168.64.129 web1.magedu.com web2.magedu.com web3.magedu.com
'''
當我們實現基於hostname的虛擬主機時,其他客戶端想通過hostname訪問就必須用到DNS域名解析。但是這個比較麻煩,最簡單的辦法就是在客戶端修改hosts文件。注意,這裏是客戶端,而不是服務端
'''
(5) 驗證
# curl http://web1.magedu.com
虛擬主機中的日誌可以專門定義,實現方式如下:
<VirtualHost 192.168.64.129:80>
ServerName web3.magedu.com
DocumentRoot "/web/web3/htdocs"
CustomLog /var/log/httpd/web3_access_log //注意,這裏不加引號
ErroLog /var/log/httpd/web3_error_log
</VirtualHost>
使用 mod_deflate 模塊壓縮頁面優化傳輸速度
使用場景:
(1) 節約帶寬,額外消耗CPU;同時,可能有些較老的瀏覽器不支持
(2) 壓縮適用於壓縮的資源,例如文本文件
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
注:在conf.d目錄下創建一個文件,把代碼寫進去就可以了,
記得一硬要用httpd -t 先檢查一邊語法後再重啓。
以上的配置都是指的是CentOS6上面的配置。
而在CentOS7上
httpd-2.4新特性:
(1) MPM支持運行DOS機制
(2) 支持event MPM
(3) 支持異步讀寫
(4) 支持每模塊及每個目錄分別使用各自的日誌級別
(5) 每請求配置,<if>
(6) 增強版的表達式分析器
(7) 支持毫秒級的keepalive timeout
(8) 基於FQDN的虛擬主機不再需要NameVirtualHost指令
(9) 支持用戶自定義變量
新模塊:
(1) mod_proxy_fcgi
(2) mod_ratelimit
(3) mod_remoteip
修改了一些配置機制:
不再支持使用Order, Deny, Allow來基於IP的訪問控制機制
編譯安裝apache
在CentOS6上面使用rpm安裝的apache版本是十分老舊的版本。
[ root@centos6 /etc/httpd/conf.d/conf ]# rpm -q httpd
httpd-2.2.15-59.el6.centos.x86_64
在CentOS7上rpm安裝的是較新的apache版本。
[ root@ygl ~ ]# rpm -q httpd
httpd-2.4.6-45.el7.centos.x86_64
而接下來,我將直接在CentOS6上安裝最新版的apache,
只是起到一個學習的作用,講道理,在CentOS6上強行裝最新版的apache
那個莫名其妙的bug啊,深坑啊,是真的多….
準備工作
首先CentOS6默認的apr版本是:
apr-1.3.9, apr-util-1.3.9
而安裝最新的httpd-2.4.28依賴於於apr-1.4+, apr-util-1.4+。
下載源代碼
httpd-2.4.28.tar.bz2
apr-1.6.2.tar.bz2
apr-util-1.6.0.tar.bz2
解壓與編譯安裝
①:首先我們要安裝開發環境包組:
yum groupinstall "Development tools"
②:然後安裝其他我實驗時候發現缺少的包,你也可以什麼時候報錯,
看提示再來裝這些包,我就一次性都提前安上了。
yum install openssl-devel pcre-devel expat-devel
注:友情提示,就算你是一臺最小化安裝的機器,剛開始是沒有安裝apr這些包的,但是開發包組Development tools,裏面會帶有apr1.3.9版本的包…
因爲我在實驗的時候總會出些很奇怪的bug,我直接卸載了老版本的apr,然後bug玄學消失了…
但是在編譯安裝的時候是指定了路徑的,按道理來說是不會有任何衝突的…
③:解壓所有壓縮包
tar xvf apr-1.6.2.tar.gz apr-util-1.6.0.tar.gz httpd-2.4.28.tar.bz2
④:配置
cd apr-1.6.2
./configure --prefix=/app/apr
make & make install
cd ../apr-util-1.6.0
./configure --prefix=/app/apr-util --with-apr=/app/apr
make & make install
useradd -r -d /app/website -s /sbin/nologin apache
cd ../httpd-2.4.28
./configure --prefix=/app/httpd24 --enable-so --enable-ssl --enable-cgi --enable-rewrite --with-zlib --with-pcre --with-apr=/app/apr/ --with-apr-util=/app/apr-util/ --enable-modules=most --enable-mpms-shared=all --with-mpm=prefork
make & make install
⑤:修改apache服務所有者和所屬組
[ root@YGL /app/httpd24/logs ]# vim /app/httpd24/conf/httpd.conf
#User daemon
#Group daemon
user apache
group apache
⑥:加PATH變量
[ root@YGL /app/httpd24/logs ]# vim /etc/profile.d/httpd24
.sh
PATH=/app/httpd24/bin:$PATH
⑦:配置服務腳本,設置開機啓動。
從另一臺CentOS6上面用scp把/etc/init.d/httpd的腳本複製過來,在修改..
注:這是偷懶的做法,也可以自己編寫…
[ root@YGL /etc/profile.d ]# vim /etc/init.d/httpd24
apachectl=/app/httpd24/bin/apachectl
httpd=${HTTPD-/app/httpd24/bin/httpd}
pidfile=${PIDFILE-/app/httpd24/logs/httpd.pid}
lockfile=${LOCKFILE-/var/lock/subsys/httpd24}
然後加入開機啓動列表裏面
chkconfig --add httpd24
chkconfig httpd24 on
service httpd24 start
⑧:測試
關了防火牆,還有SELINUX,用瀏覽器訪問一下,
或是使用curl測試一下就好了…
ღ ღ ღ 如果覺得文章對您有用,不妨贊一下ღ ღ ღ