NGINX從入門到放棄(原理與編譯安裝)

原理

  

進程與線程

  
  進程是具有一定獨立功能的在計算機運行的程序的實體,進程開始是程序運行的基本單位,在支持線程的系統下,線程纔是基本的運行單位,進程作爲線程的容器。程序本身是指令,數據和數據結構的集合,進程纔是真正運行的實例。一個程序可能會與多個進程存在關係,每個進程都可以以同步或者異步的方式獨立運行。現代計算機系統可以在同一段的時間內將多個程序進行加載,藉由時分複用在一個處理器上表現出多個進程同時運行的感覺——即宏觀上的並行;微觀上串行。使用多線程技術的操作系統,程序的平行線程,可在多 CPU 主機或網絡上真正同時運行,變相提高了芯片的性能。
  

web服務的工作方式

  

常見的3中模型

  
  web服務器響應用戶的請求,必須以某種方式工作在套接字上。一般情況下會採用以下3中方式:多進程方式,多線程方式,異步方式。
  

  1. 多進程方式:爲每個請求啓動一個進程來處理。但是在操作系統中,生成進程,銷燬進程都會大量消耗cpu資源,因此一旦負載提高時候,性能會出現明顯的下降。
    優點:穩定 由於採用的是獨立的進程響應請求,進程之前的獨立性保障了一旦單個進程出現問題,不會影響到其他進程的正常運行,因此具有很強的穩定性。
    缺點:資源佔用高當服務器負載較高時,同樣由於每個進程負責響應一個用戶的請求,用戶請求數量較多,進程生成數量也會增多,進程資源申請,進程生成,進程切換都會消耗更多的資源。同時進程之間的隔離性也會造成大量的內存重複資源佔用大量內存空間。
      
    2.多線程方式:一個進程中生成多個線程,由線程來負責處理用戶的請求,由於線程的開銷會小於進程,同時進程作爲線程的容器,所以在一定的程度上,進程的資源也可以被線程所共享,一定程度上節約了內存空間。
    優點:資源開銷小線程間部分數據可以共享,且線程切換消耗明顯小於進程。
    缺點:穩定性線程之前的頻繁的切換,有一定的可能性會造成線程的抖動,而且線程過多也會在一定程度上造成服務器的不穩定。
      
    3.異步方式使用了非阻塞方式來處理用戶請求,開銷最小。但是異步方式雖然效率很高,多任務之前的調度一旦出現問題,可能會導致整體的故障,所以使用異步方式,一般會是一些功能相對簡單,且代碼中沒有影響調度的錯誤的程序。
    優點:性能極好一個進程或者線程來處理多個請求,沒有額外開銷,性能優異,資源佔用少。
    缺點:穩定性一旦出現問題,可能導致大量請求無法處理。

web請求的工作流程

NGINX從入門到放棄(原理與編譯安裝)
1.客戶端發起請求到服務器的對外網卡;
2.服務器網卡收到請求後轉交給內核處理;
3.內核根據請求的對應套接字,將請求交給工作在用戶空間的web服務器進程;
4.web服務器進程根據用戶的請求,向內核申請系統調用,申請獲得對應的資源(例如靜態頁面資源);
5.內核根據web服務器的請求發現它申請的是是一個磁盤文件,因此通過調用磁盤驅動程序連接磁盤;
6.內核調度磁盤,獲取所需要的資源;
7.內核將資源存放在自己的緩衝區內,接下來通知web服務器進程來獲取資源;
8.web服務器進程通過系統調用獲得資源;
9.web服務器進程生成響應報文,通過系統調用發給內核來響應用戶的請求;
10.內核將響應的報文發往網卡;
11.網卡將響應數據包發送給用戶,響應結束。

  
總結
  客戶端向服務器端發送web請求的過程有兩個I/O的過程,1.客戶端請求的網絡I/O;2.web服務器請求頁面的I/O。
  

I/O模型介紹

  由於web服務器進程無法直接訪問磁盤,而是要申請系統調用因此每次IO,都要經由兩個階段:
  第一步:將數據從磁盤文件先加載至內核內存空間(緩衝區),等待數據準;
備完成,時間較長
  第二步:將數據從內核緩衝區複製到用戶空間的進程的內存中,時間較短。
具體可以參考下圖:
NGINX從入門到放棄(原理與編譯安裝)
根據數據傳輸階段可以將I/O動作分爲五類模式:
1.阻塞I/O
2.非阻塞I/O
3.I/O複用
4.信號驅動
5.異步I/O

阻塞和非阻塞

阻塞/非阻塞:關注調用者在等待結果返回之前所處的狀態
阻塞:blocking,指IO操作需要徹底完成後才返回到用戶空間,調用結果返回之前,調用者被掛起;
非阻塞:nonblocking,指IO操作被調用後立即返回給用戶一個狀態值,無需等到IO操作徹底完成,最終的調用結果返回之前,調用者不會被掛起。

同步和異步

同步/異步:關注的是消息通信機制
同步:synchronous,調用者等待被調用者返回消息,才能繼續執行
異步:asynchronous,被調用者通過狀態、通知或回調機制主動通知調用者被調用者的運行狀態

同步阻塞I/O模型

NGINX從入門到放棄(原理與編譯安裝)
同步阻塞I/O模型是最爲簡單的I/O模型,用戶線程在內核進行I/O操作時被阻塞;
用戶線程通過系統調用read發起I/O讀操作,由用戶空間轉到內核空間,內核等待數據包到達後,然後將接受到的數據拷貝到用戶空間,進而完成read操作;
用戶需要等待read將數據讀取到buffer後,才能繼續處理接收的數據。整個I/O請求的過程中,用戶線程是被阻塞的。導致了用戶在發起I/O請求後到獲取到數據之間的時間段內,無法做任何事情,這樣對cpu是個嚴重的浪費。

同步非阻塞I/O模型

NGINX從入門到放棄(原理與編譯安裝)
用戶線程發起I/O請求後,會立即返回一個響應,但是並未獲取到任何數據,用戶線程需要不斷的發起I/O請求,直到數據正式到達,才能夠真正讀取到數據,繼續執行接下來的操作。即這是一種“輪詢”機制;
整個I/O請求的過程之中,雖然用戶線程每次發出I/O請求後可以立刻得到響應,但是爲了等到數據,仍然需要不斷的去輪詢,重複請求,進而消耗了大量cpu資源;
同步非阻塞I/O是一種非常浪費cpu資源的方式,實際中很少會使用,而是會在其他I/O模型之中使用非阻塞I/O這個模型。

I/O多路複用模型

NGINX從入門到放棄(原理與編譯安裝)
多個連接公用一個等待機制,會阻塞進程,但是進程是阻塞在select或者poll上,並不是阻塞在真正的I/O上。
用戶首先將需要進行的I/O操作添加到select上,繼續執行其他的工作(異步),同時等待着select系統調用返回,當數據到達時候,I/O被激活,select函數返回,用戶線程正式發起read請求,讀取數據並且繼續運行。
從流程上看,使用了select函數進行I/O請求和同步阻塞模型沒有大的區別,甚至還多了添加監視I/O,以及調用select函數等的額外附加操作,效率上相對低下,而且發生了兩次的阻塞,但是,第一次阻塞在select上時候,select函數可以監控多個I/O是否已經有I/O操作準備就緒,即可達到在同一個線程內同時處理多個I/O請求的目的。而不同於阻塞I/O,一次僅僅能夠監控一個I/O。
雖然I/O多路複用允許同時處理多個I/O請求,但是每個I/O請求的過程還是阻塞的(在select函數上進行阻塞),平均時間甚至比同步阻塞I/O模式還長。如果用戶線程僅僅是註冊自己需要的I/O請求,然後去做自己的事情,等到數據到來後再進行處理,則可以提高cpu的利用率
I/O多路複用模型是最常使用的I/O模型,但是其異步程度有限,因爲它使用了會阻塞線程的select系統調用,因此,I/O多路複用技術也只能被稱爲,異步阻塞I/O模型,並非真正的異步I/O。

IO多路複用是指內核一旦發現進程指定的一個或者多個IO條件準備讀取,就通知該進程,IO多路複用適用如下場合:
1.當客戶端處理多個描述符時(一般是交互式輸入和網絡套接口),必須使用I/O複用
2.當一個客戶端同時處理多個套接字時,此情況可能的但很少出現
3.當一個TCP服務器既要處理監聽套接口,又要處理已連接套接口,一般也要用到I/O
複用
4.當一個服務器即要處理TCP,又要處理UDP,一般要使用I/O複用
5.當一個服務器要處理多個服務或多個協議,一般要使用I/O複用

信號驅動I/O模型

NGINX從入門到放棄(原理與編譯安裝)
信號驅動IO:signal-driven I/O
用戶進程可以通過sigaction系統調用註冊一個信號處理程序,然後主程序可以繼續向下執行,當有IO操作準備就緒時,由內核通知觸發一個SIGIO信號處理程序執行,然後將用戶進程所需要的數據從內核空間拷貝到用戶空間。
此模型的優勢在於等待數據報到達期間進程不被阻塞。用戶主程序可以繼續執行,只要等待來自信號處理函數的通知。
該模型並不常用。

異步I/O模型

NGINX從入門到放棄(原理與編譯安裝)
異步IO與信號驅動IO最主要的區別是信號驅動IO是由內核通知何時可以進行IO操作,而異步IO則是由內核告訴我們IO操作何時完成了。具體來說就是,信號驅動IO當內核通知觸發信號處理程序時,信號處理程序還需要阻塞在從內核空間緩衝區拷貝數據到用戶空間緩衝區這個階段,而異步IO直接是在第二個階段完成後內核直接通知可以進行後續操作了

相比於IO多路複用模型,異步IO並不十分常用,不少高性能併發服務程序使用IO多路複用模型+多線程任務處理的架構基本可以滿足需求。況且目前操作系統對異步IO的支持並非特別完善,更多的是採用IO多路複用模型模擬異步IO的方式(IO事件觸發時不直接通知用戶線程,而是將數據讀寫完畢後放到用戶指定
的緩衝區中)

五種模型的對比

NGINX從入門到放棄(原理與編譯安裝)

I/O模型的具體實現

I/O模型的實現主要依賴於以下幾種方式:
Select:linux實現,對應I/O複用模型,BSD4.2最早實現
Poll: linux實現,對應I/O複用模型,System V Unix最早實現
Epoll: linux實現,對應I/O複用模型,具有信號驅動I/O模型的一部分特性
Kqueue: FreeBSD實現,對應I/O複用模型,具有信號驅動I/O的某些特性
/dev/poll: SUN的Solaris實現,對應I/O複用模型,具有信號驅動的I/O模型的一部分特性
Iocp: windows實現,對應異步I/O模型。

注意
雖然Windows的Locp最爲優秀,但是,目前很少有支持asynchronous I/O的系統,但是由於其系統本身的侷限性,大型服務器還是在Linux和UNIX下。而且正如上面所述,kqueue、epoll、/dev/poll 與 IOCP相比,就是多了一層從內核copy數據到應用層的阻塞,從而不能算作asynchronous I/O類。但是,這層小小的阻塞無足輕重。

select、poll與epoll

Select:
POSIX所規定,目前幾乎在所有的平臺上支持,其良好跨平臺支持也是
它的一個優點,本質上是通過設置或者檢查存放fd標誌位的數據結構來進行下一步處理
缺點:
1.單個進程可監視的fd數量被限制,即能監聽端口的數量有限

cat /proc/sys/fs/file-max

2.對socket是線性掃描,即採用輪詢的方法,效率較低
3.select 採取了內存拷貝方法來實現內核將 FD 消息通知給用戶空間,這樣一個用來存放大量fd的數據結構,這樣會使得用戶空間和內核空間在傳遞該結構時複製開銷大.

poll
本質上和select沒有區別,它將用戶傳入的數組拷貝到內核空間,然後查詢每個fd對應的設備狀態,其沒有最大連接數的限制,原因是它是基於鏈表來存儲的,大量的fd的數組被整體複製於用戶態和內核地址空間之間,而不管這樣的複製是不是有意義

poll特點是“水平觸發”,如果報告了fd後,沒有被處理,那麼下次poll時會再次報告該fd
邊緣觸發:只通知一次

epoll
在Linux 2.6內核中提出的select和poll的增強版本
支持水平觸發LT和邊緣觸發ET,最大的特點在於邊緣觸發,它只告訴進程哪些fd剛剛變爲就需態,並且只會通知一次。使用“事件”的就緒通知方式,通過epoll_ctl註冊fd,一旦該fd就緒,內核就會採
用類似callback的回調機制來激活該fd,epoll_wait便可以收到通知
優點:
1.沒有最大併發連接的限制:能打開的FD的上限遠大於1024(1G的內存能監聽約10萬個端口)
2.效率提升:非輪詢的方式,不會隨着FD數目的增加而效率下降;只有活躍可用的FD纔會調用callback函數,即epoll最大的優點就在於它只管理“活躍”的連接,而跟連接總數無關
3.內存拷貝,利用mmap(Memory Mapping)加速與內核空間的消息傳遞;即epoll使用mmap減少複製開銷。

簡介

  Nginx (engine x) 是一個高性能的HTTP和反向代理服務器,也是一個IMAP/POP3/SMTP服務器。Nginx是由伊戈爾·賽索耶夫爲俄羅斯訪問量第二的Rambler.ru站點(俄文:Рамблер)開發的,第一個公開版本0.1.0發佈於2004年10月4日。

  他將源代碼以類BSD許可證的形式發佈,因它的穩定性、豐富的功能集、示例配置文件和低系統資源的消耗而聞名。2011年6月1日,nginx 1.0.4發佈。

  Nginx是一款輕量級的Web 服務器/反向代理服務器及電子郵件(IMAP/POP3)代理服務器,並在一個BSD-like 協議下發行。其特點是佔有內存少,併發能力強,事實上nginx的併發能力確實在同類型的網頁服務器中表現較好,中國大陸使用nginx網站用戶有:百度、京東、新浪、網易、騰訊、淘寶等。
  

nginx特性及基本功能

特性
1.模塊化的設計,有不錯的拓展性;
2.高可靠性;
3.支持熱部署:不停機更新配置文件,升級版本,更換日誌文件;
4.較低的內存消耗:10000個keep-alive(長連接)連接模式下的非活動連接,僅僅佔用2.5M的內存空間;
5.event-driven(事件驅動),aio(異步非阻塞I/O),mmap(一種內存映射文件的方法),sendfile(內核直接封裝報文)

基本的功能
1.靜態資源的web服務器;
2.http協議的反向代理器;
3.pop3/imap4協議反向代理服務器(郵件)
4.FastCGI(LNMP),uWSGI(python)等協議;
5.模塊化(非DSO);

nginx架構

NGINX從入門到放棄(原理與編譯安裝)

master/worker結構

一個master進程:負責加載和分析配置文件,管理worker進程,平滑升級。
一個或者多個worker進程:負責處理並響應用戶的請求。
緩存相關的進程:
cache loader:載入緩存的對象;
cache manager:管理緩存對象。

nginx模塊

nginx是高度模塊化的,但是其模塊在早期是不支持DSO(動態裝卸載)機制的;1.9.11版本之後才支持動態的裝卸載;
分類:
  核心模塊:core module
  標準模塊:
    http模塊:ngxhttp
      http core modules 默認功能
      http optional modules 需要編譯時候指定
    mail模塊 : ngxmail

    stream模塊: ngxstream*
第三方模塊

nginx的安裝

官方rpm包安裝

這裏可以獲得官方rpm包,之後本地安裝即可
http://nginx.org/packages/centos/7/x86_64/RPMS/

epel安裝

Fedora-EPEL源內有nginx的安裝,nginx未被直接收錄到base源中。
https://mirrors.aliyun.com/epel/7/x86_64/

編譯安裝nginx

1.安裝編譯環境

yum groupinstall "development tools" -y

2.安裝編譯時可能會需要的包

yum install pcre-devel openssl-devel zlib-devel -y

3.添加nginx系統賬號

useradd -r nginx

4.獲取nginx源碼包,解壓並編譯

#獲取nginx源碼包
wget http://nginx.org/download/nginx-1.14.0.tar.gz
#解壓
 tar -xvf nginx-1.14.0.tar.gz 
 cd nginx-1.14.0/
#編譯
./configure --prefix=/usr/local/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_status_module --with-threads --with-file-aio

make &&make install

NGINX從入門到放棄(原理與編譯安裝)
NGINX從入門到放棄(原理與編譯安裝)
編譯安裝選項
--prefix=/etc/nginx 安裝路徑
--sbin-path=/usr/sbin/nginx 指明nginx程序文件安裝路徑
--conf-path=/etc/nginx/nginx.conf 主配置文件安裝位置
--error-log-path=/var/log/nginx/error.log 錯誤日誌文件安裝位置
--http-log-path=/var/log/nginx/access.log 訪問日誌文件安裝位置
--pid-path=/var/run/nginx.pid 指明pid文件安裝位置
--lock-path=/var/run/nginx.lock 鎖文件安裝位置
--http-client-body-temp-path=/var/cache/nginx/client_temp 客戶端
body部分的臨時文件存放路徑,服務器允許客戶端使用put方法提交大數據時,臨時存放的磁盤路徑
--http-proxy-temp-path=/var/cache/nginx/proxy_temp 作爲代理服務器,服務器響應報文的臨時文件存放路徑
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp 作爲fastcgi代理服務器,服務器響應報文的臨時文件存放路徑
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 作爲uwsgi代理服務器,服務器響應報文的臨時文件存放路徑
--http-scgi-temp-path=/var/cache/nginx/scgi_temp 作爲scgi反代服務器,服務器響應報文的臨時文件存放路徑
--user=nginx 指明以那個身份運行worker進程,主控master進程一般由root運行
--group=nginx
--with-http_ssl_module 表示把指定模塊編譯進來
5.修改配置文件,添加環境變量

vim /etc/nginx/nginx.conf
#修改運行用戶爲nginx
user nginx;

#添加環境變量
vim /etc/profile.d/nginx.sh
PATH=/usr/local/nginx/sbin:$PATH
source /etc/profile.d/nginx.sh 

基本配置完成下面的配置是爲了省事
6.編寫centos7的systemd管理nginx的腳本

vim /usr/lib/systemd/system/nginx.service

#以下是文件內容
[Unit]
Description=the nginx web server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

#保存退出後添加systemd管理
systemctl daemon-reload 
#啓動nginx
systemctl strat nginx

nginx安裝成功
NGINX從入門到放棄(原理與編譯安裝)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章