在LInux服務器上實現(xiàn)web服務,常見無非也就是Apache、Nginx、Tomcat。
創(chuàng)新互聯(lián)建站是一家朝氣蓬勃的網(wǎng)站建設公司。公司專注于為企業(yè)提供信息化建設解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設計,網(wǎng)站模板,微信公眾號開發(fā),軟件開發(fā),小程序設計,10余年建站對木托盤等多個行業(yè),擁有豐富的網(wǎng)站營銷經(jīng)驗。三者之間的區(qū)別:
- Apache:支持的模塊比較多,采用servlet處理模型,同步阻塞模型,工作模式多變,對于高并發(fā)的場景處理速度比較慢,運行穩(wěn)定;
- Nginx :輕量級web服務器,自身支持模塊少,需要借助第三方模塊支持(Nginx官網(wǎng)就可以下載),采用epoll處理模式,異步非阻塞型,適合高并發(fā)場景,配置簡單;
- Tomcat:apache軟件基金會下開源的子項目,也成為容器,主要處理java語言編寫的頁面,也可以處理html頁面,并發(fā)連接小;
今天這篇博文主要就是圍繞apache-2.4.23版本展開的:
對apache不太了解的朋友可以參考博文:基于Apache搭建Web服務器詳解
這里就不具體介紹apache究竟是什么、它的起因什么的了。
博文大綱:
一、httpd-2.4.23版本特性
二、編譯安裝httpd-2.4.23
三、apche的三種工作模式
四、進程與線程的區(qū)別
新版本的httpd-2.4.23新增模塊:
- mod_proxy_fcgi(可提供fcgi代理);
- mod_ratelimit(限制用戶帶寬);
- mod_request(請求模塊,對請求進行過濾);
- mod_remoteip(匹配客戶端的IP地址);
對于基于IP的訪問控制進行了修改,不再支持allow、deny、order機制,而是統(tǒng)一使用require進行!
新增的特性有:
- MPM支持在運行時裝載;
- 支持envet工作模式;
- 支持異步讀寫功能;
- 每個模塊都可以指定輸出的日志級別;
- 增強版的表達式分析器;
- 請求配置:
, ; - 毫秒級別的keepalive timeout;
- 支持FQDN的虛擬主機;
- 支持自定義變量;
接下來開始安裝!
安裝環(huán)境:
[root@localhost ~]# rpm -q httpd
未安裝軟件包 httpd
//如果存在,使用“-e”選項進行卸載
apr是Apache可移植運行庫,是一個對操作系統(tǒng)條用的抽象庫,用于實現(xiàn)Apache內(nèi)部組件對操作系統(tǒng)的使用,提高系統(tǒng)的可移植性。
[root@localhost ~]# tar zxf apr-1.5.2.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/apr-1.5.2/
[root@localhost apr-1.5.2]# ./configure --prefix=/usr/local/apr && make && make install
[root@localhost ~]# tar zxf apr-util-1.5.4.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/apr-util-1.5.4/
[root@localhost apr-util-1.5.4]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && make && make install
[root@localhost ~]# tar zxf zlib-1.2.8.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/zlib-1.2.8/
[root@localhost zlib-1.2.8]# ./configure --prefix=/usr/local/zlib && make && make install
[root@localhost ~]# tar zxf pcre-8.39.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/pcre-8.39/
[root@localhost pcre-8.39]# ./configure -- prefix=/usr/local/pcre && make && make install
安裝apache-2.4.23版本時,會提示openssl自帶的版本過低,需要自行手動安裝新的版本。
[root@localhost ~]# tar zxf openssl-1.0.1u.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/openssl-1.0.1u/
[root@localhost openssl-1.0.1u]# ./config -fPIC --prefix=/usr/local/openssl enable-shared && make && make install
//PIC使.so文件的代碼段變?yōu)檎嬲饬x上的共享
//如果不加-fPIC,則加載.so文件的代碼段時,代碼段引用的數(shù)據(jù)對象需要重定位, 重定位會修改代碼段的內(nèi)容,這就造成每個使用這個.so文件代碼段的進程在內(nèi)核里都會生成這個.so文件代碼段的copy.每個copy都不一樣,取決于 這個.so文件代碼段和數(shù)據(jù)段內(nèi)存映射的位置.
[root@localhost ~]# tar zxf httpd-2.4.23.tar.gz -C /usr/src
[root@localhost ~]# cd /usr/src/httpd-2.4.23/
[root@localhost httpd-2.4.23]# ./configure --prefix=/usr/local/http-2.4.23 --enable-so --enable-cgi \
--enable-cgid --enable-ssl --with-ssl=/usr/local/openssl --enable-rewrite \
--with-pcre=/usr/local/pcre --with-z=/usr/local/zlib --with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util --enable-modules=most --enable-mods-shared=most \
--enable-mpms-shared=all --with-mpm=event --enable-proxy --enable-proxy-fcgi --enable-expires \
--enable-deflate && make && make install
各選項含義:
- --enable-so:支持動態(tài)共享模塊;
- --enable-rewrite:支持url重寫;
- --enable-ssl:支持ssl;
- --with-ssl=/usr/local/openssl:指定ssl安裝位置;
- --enable-cgi:開啟cgi通用網(wǎng)管接口;
- --enable-cgid:開啟cig通用網(wǎng)管接口管理程序;
- --enable-modules=most:編譯成二進制是安裝常用模塊;
- --enable-mpms-shared=all:安裝apache的所有工作模式;
- --with-mpm=event:指定默認的運行方式
- --with-pcre=/usr/local/pcre:支持 pcre ;
- --with-z=/usr/local/zlib:使用 zlib 壓縮庫;
- --with-apr=/usr/local/apr:指定 apr 的安裝路徑;
- --with-apr-util=/usr/local/apr-util:指定 apr-util 的安裝路徑;
- --enable-expires:支持緩存;
- --enable-deflate:支持壓縮;
[root@localhost httpd-2.4.23]# ln -s /usr/local/http-2.4.23/bin/* /usr/local/bin/
[root@localhost httpd-2.4.23]# cp /usr/local/http-2.4.23/bin/apachectl /etc/init.d/httpd
[root@localhost httpd-2.4.23]# vim /etc/init.d/httpd
#!/bin/bash //修改
#chkconfig: 35 85 15 //添加
………… //省略以下內(nèi)容
[root@localhost httpd-2.4.23]# chkconfig --add httpd
[root@localhost httpd-2.4.23]# systemctl start httpd
[root@localhost httpd-2.4.23]# netstat -anpt | grep 80
tcp6 0 0 :::80 :::* LISTEN 108903/httpd
[root@localhost ~]# httpd -M //可以查看到httpd服務啟動加載的模塊
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain. Set the 'ServerName' directive globally to suppress this message
//關于啟動服務時提示以上的信息,可以省略,也可修改其配置文件(/usr/local/http-2.4.23/conf/httpd.conf)文件找到“ServerName ”一行,根據(jù)實際情況進行修改
Loaded Modules:
core_module (static)
so_module (static)
http_module (static)
authn_file_module (shared)
authn_core_module (shared)
authz_host_module (shared)
authz_groupfile_module (shared)
authz_user_module (shared)
authz_core_module (shared)
access_compat_module (shared)
auth_basic_module (shared)
reqtimeout_module (shared)
filter_module (shared)
mime_module (shared)
log_config_module (shared)
env_module (shared)
headers_module (shared)
setenvif_module (shared)
version_module (shared)
mpm_prefork_module (shared)
unixd_module (shared)
status_module (shared)
autoindex_module (shared)
dir_module (shared)
alias_module (shared)
至此apache-2.4.23已經(jīng)安裝完成。
其工作方式:當Apache服務啟動后,mpm_prefork模塊會預先創(chuàng)建多個子進程(默認為5個),每個子進程只有一個線程,當接收到客戶端請求后,mpm_prefork模塊再將請求轉(zhuǎn)交給子進程進行處理,并且每個子進程同時只能用于單個請求。如果當前的請求數(shù)將超過預先創(chuàng)建的子進程數(shù)時,mpm_prefork模塊就會創(chuàng)建新的子進程來處理額外的請求。
如圖:
Apache總是試圖保持一些備用或空閑的子進程用于迎接即將到來的請求。這樣客戶端的請求就不需要在接收后等待子進程的產(chǎn)生。
由于在 mpm_prefork 模塊中,每個請求對應一個子進程,因此其占用的系統(tǒng)資源相對其他 兩種模塊而言較多。不過 mpm_prefork 模塊的優(yōu)點在于它的每個子進程都會獨立處理對應 的單個請求,這樣,如果其中一個請求出現(xiàn)問題就不會影響到其他請求。Prefork 在效率上 要比 Worker 要高,但是內(nèi)存使用大得多不擅長處理高并發(fā)的場景。
開啟prefork模式的方法:
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/httpd.conf
//編寫httpd的主配置文件,修改一下內(nèi)容
Include conf/extra/httpd-mpm.conf //默認存在刪除“#”號即可
#LoadModule mpm_event_module modules/mod_mpm_event.so
//添加#號
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
//默認存在,刪除#號即可!
#LoadModule mpm_worker_module modules/mod_mpm_worker.so
//這三行便是apache的三種工作模式,可根據(jù)實際情況進行切換
[root@localhost ~]# systemctl restart httpd //重新啟動httpd服務
[root@localhost ~]# systemctl start httpd //手動再啟動一下
[root@localhost ~]# httpd -V //查看httpd的工作模式
//找到這一行即可
Server MPM: prefork //可以看到現(xiàn)在Apache工作在prefork模式
與prefork模式有關的配置文件如下:
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf
//設置prefork模式也就只有這幾個參數(shù),具體含義:
//這就是prefork工作模式的參數(shù)-
StartServers 5 //apache啟動時默認開啟的子進程數(shù)
MinSpareServers 5 //最小的閑置子進程數(shù)
MaxSpareServers 10 //大的閑置子進程數(shù)
MaxRequestWorkers 250 // 設置了允許同時的大接入請求數(shù)量
MaxConnectionsPerChild 0 //0表示每個子進程處理完數(shù)據(jù)后進程永不銷毀,設置成非0時,可防止內(nèi)存泄漏,服務器在負載小時自動減少自己進程數(shù)
關于其配置內(nèi)容可參考圖片:
//注 1:MaxRequestWorkers 是這些指令中最為重要的一個,設定的是 Apache 可以同時處理 的請求,是對 Apache 性能影響大的參數(shù)。如果請求總數(shù)已達到這個值(可通過 ps -ef|grep http|wc -l 來確認),那么后面的請求就要排隊,直到某個已處理請求完畢。這就是系統(tǒng)資源 還剩下很多而 HTTP 訪問卻很慢的主要原因。雖然理論上這個值越大,可以處理的請求就越 多,建議將初始值設為(以 Mb 為單位的大物理內(nèi)存/2),然后根據(jù)負載情況進行動態(tài)調(diào)整。 比如一臺 4G 內(nèi)存的機器,那么初始值就是 4000/2=2000
注 2:prefork 控制進程在最初建立“StartServers”個子進程后,為了滿足 MinSpareServers 設置的需要創(chuàng)建一個進程,等待一秒鐘,繼續(xù)創(chuàng)建兩個,再等待一秒鐘,繼續(xù)創(chuàng)建四個……如 此按指數(shù)級增加創(chuàng)建的進程數(shù),最多達到每秒 32 個,直到滿足 MinSpareServers 設置的值為止。這種模式 可以不必在請求到來時再產(chǎn)生新的進程,從而減小了系統(tǒng)開銷以增加性能。 MaxSpareServers 設置了大的空閑進程數(shù),如果空閑進程數(shù)大于這個 值,Apache 會自動 kill 掉一些多余進程。這個值不要設得過大,但如果設的值比 MinSpareServers 小,Apache 會自 動把其調(diào)整為 MinSpareServers+1。如果站點負載較大,可考慮同時加大 MinSpareServers 和 MaxSpareServers。
注 3:ServerLimit 和 MaxClients(MaxRequestWorkers)有什么區(qū)別呢? 是因為在 apache1 時代,控制大進程數(shù)只有 MaxClients 這個參數(shù),并且這個參數(shù)大值為 256,并且是寫死了的,試圖設置為超過 256 是無效的,這是由于 apache1 時代的服務器硬 件限制的。但是 apache2 時代由于服務器硬件的升級,硬件已經(jīng)不再是限制,所以使用 ServerLimit 這個參數(shù)來控制大進程數(shù),ServerLimit 值>=MaxClient 值才有效。ServerLimit 要放在 MaxClients 之前,值要不小于 MaxClients
優(yōu)點:成熟,兼容所有新老模塊。進程之間完全獨立,使得它非常穩(wěn)定。同時,不需要擔心線程安全的問題。(我們常用的mod_php,PHP的拓展不需要支持線程安全)
缺點:一個進程相對占用更多的系統(tǒng)資源,消耗更多的內(nèi)存。而且,它并不擅長處理高并發(fā)請求,在這種場景下,它會將請求放進隊列中,一直等到有可用進程,請求才會被處理。
Worker 模式(多線程多進程): 和 prefork 模式相比,worker 使用了多進程和多線程的混合模式,worker 模式也同樣會先預派生一些子進程,然后每個子進程創(chuàng)建一些線程,同時包括一個監(jiān)聽線程,每個請求過來會 被分配到一個線程來服務。線程比起進程會更輕量,因為線程是通過共享父進程的內(nèi)存空間, 因此,內(nèi)存的占用會減少一些,在高并發(fā)的場景下會比 prefork 有更多可用的線程,表現(xiàn)會 更優(yōu)秀一些;另外,如果一個線程出現(xiàn)了問題也會導致同一進程下的線程出現(xiàn)問題,如果是 多個線程出現(xiàn)問題,也只是影響 Apache 的一部分,而不是全部。由于用到多進程多線程, 需要考慮到線程的安全了,在使用 keep-alive 長連接的時候,某個線程會一直被占用,即使 中間沒有請求,需要等待到超時才會被釋放(該問題在 prefork 模式下也存在) 總的來說,prefork 方式速度要稍高于 worker,然而它需要的 cpu 和 memory 資源也稍多于 woker。如圖:
Apache總是試圖維持一個備用(spare)或是空閑的服務線程池。這樣,客戶端無須等待新線程或新進程的建立即可得到處理。在Unix中,為了能夠綁定80端口,父進程一般都是以root身份啟動,隨后,Apache以較低權限的用戶建立子進程和線程。User和Group指令用于配置Apache子進程的權限。雖然子進程必須對其提供的內(nèi)容擁有讀權限,但應該盡可能給予他較少的特權。另外,除非使用了suexec(負責處理CGI和SSI程序的請求,確保網(wǎng)頁使用者能以該目錄或程序的用戶ID來執(zhí)行遠程程序。) ,否則,這些指令配置的權限將被CGI腳本所繼承。
線程比起進程會更輕量,因為線程通常會共享父進程的內(nèi)存空間,因此,內(nèi)存的占用會減少一些,在高并發(fā)的場景下,表現(xiàn)得比 prefork模式好。
有些人會覺得奇怪,那么這里為什么不直接使用多線程呢?主要是需要考慮穩(wěn)定性,如果一個線程異常掛了,會導致父進程連同其他正常的子線程都掛了(它們都是同一個進程下的)。多進程+多線程模式中,各個進程之間都是獨立的,如果某個線程出現(xiàn)異常,受影響的只是Apache的一部分服務,而不是整個服務。其他進程仍然可以工作。
有關work模式的配置:
//自行修改httpd主配置文件,切換模式并重啟服務,接下來
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf
//這是worker工作模式的參數(shù)
StartServers 3 //apache啟動時默認開始的子進程數(shù)
MinSpareThreads 75 //最小空閑數(shù)量的工作線程-
MaxSpareThreads 250 //大空閑數(shù)量的工作線程-
ThreadsPerChild 25 //每個子進程產(chǎn)生的線程數(shù)量
MaxRequestWorkers 400 //每個進程大接受的請求數(shù)量
MaxConnectionsPerChild 0 //表示永不銷毀
有關work模式的詳細介紹請參考圖片:
Worker模式下所能同時處理的請求總數(shù)是由子進程總數(shù)乘以ThreadsPerChild 值決定的,應該大于等于MaxRequestWorkers。如果負載很大,現(xiàn)有的子進程數(shù)不能滿足時,控制進程會派生新的子進程。默認大的子進程總數(shù)是16,加大時 也需要顯式聲明ServerLimit(大值是20000)。需要注意的是,如果顯式聲明了ServerLimit,那么它乘以 ThreadsPerChild的值必須大于等于MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數(shù)倍,否則 Apache將會自動調(diào)節(jié)到一個相應值。
優(yōu)點:占據(jù)更少的內(nèi)存,高并發(fā)下表現(xiàn)更優(yōu)秀。
缺點:必須考慮線程安全的問題,因為多個子線程是共享父進程的內(nèi)存地址的。如果使用keep-alive的長連接方式,也許中間幾乎沒有請求,這時就會發(fā)生阻塞,線程被掛起,需要一直等待到超時才會被釋放。如果過多的線程,被這樣占據(jù),也會導致在高并發(fā)場景下的無服務線程可用。(該問題在prefork模式下,同樣會發(fā)生)。
這是Apache最新的工作模式,它和worker模式很像,不同的是在于它解決了keep-alive長連接的時候占用線程資源被浪費的問題,在event工作模式中,會有一些專門的線程用來管理這些keep-alive類型的線程,當有真實請求過來的時候,將請求傳遞給服務器的線程,執(zhí)行完畢后,又允許它釋放。這增強了在高并發(fā)場景下的請求處理。如圖:
有關Event MPM模式的配置:
//自行修改httpd主配置文件,切換模式并重啟服務,接下來
[root@localhost ~]# vim /usr/local/http-2.4.23/conf/extra/httpd-mpm.conf
StartServers 3
MinSpareThreads 75
MaxSpareThreads 250
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
//其各項配置內(nèi)容與work模式十分相似,這里就不多說了!
線程就是指進程內(nèi)的一個執(zhí)行單元,也是進程內(nèi)的可調(diào)度實體。
線程與進程的區(qū)別:
- 地址空間:進程內(nèi)的一個執(zhí)行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;
- 資源擁有:進程是資源分配和擁有的單位,同一個進程內(nèi)的線程共享進程的資源;
- 線程是處理器調(diào)度的基本單位,但進程不是;
- 二者均可并發(fā)執(zhí)行;
進程和線程都是由操作系統(tǒng)所體會的程序運行的基本單元,系統(tǒng)利用該基本單元實現(xiàn)系統(tǒng)對應用的并發(fā)性。
進程和線程的區(qū)別在于:
簡而言之,一個程序至少有一個進程,一個進程至少有一個線程。
線程的劃分尺度小于進程,使得多線程程序的并發(fā)性高。
另外,進程在執(zhí)行過程中擁有獨立的內(nèi)存單元,而多個線程共享內(nèi)存,從而極大地提高了程
序的運行效率。
———————— 本文至此結(jié)束,感謝閱讀 ————————
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。