nginx【engine x】是 Igor Sysoes編寫的一個http和反向代理服務器,另外它也可以做爲郵件代理服務器。
nginx的基本的http服務特性:
處理靜態文件,索引文件及自動索引,打開文件描述符緩存;
使用緩存加速反向代理,支持簡單的負載均衡以及容錯;
支持遠程FastCGI,uwsgi,SCGI,和memcached服務的緩存加速;
模塊化的架構,過濾器包括gzipping,byte ranges,chunked responses,能及SSI-filter.在SSI過濾器中,到同一個proxy或者fastcgi的多個子請求併發處理;
SSL 和 TLS SNI 支持;
IMAP/POP3代理服務功能:
使用外部 HTTP 認證服務器重定向用戶到 IMAP/POP3 後端;
使用外部 HTTP 認證服務器認證用戶後連接重定向到內部的 SMTP 後端;
其他的HTTP服務器特性
支持基於名稱和IP的虛擬主機;
支持Keep-alive和pipeliined連接;
可以靈活地進行配置;
支持平滑升級,也就是重新加載配置或在線升級時,不需要中斷正在處理的請求;
支持自定義的訪問日誌格式,對日誌寫操作時支持緩存功能,也就是可以降低日誌寫操作時的IO操作以及快速日誌輪轉;
對3xx-5xx的錯誤代碼可以重定向到自己指定的頁面。
支持重寫功能(rewrite):
可以使用正則表達式改變URI;
可以根據客戶端地址執行不同的功能;
支持基於客戶端地址和http基本認證機制的訪問控制;
支持HTTP referer 驗證
支持PUT、DELETE、MKCOL、COPY以及MOVE方法;
支持視頻流FLV和MP4;
支持速度限制;
支持對來自同一地址的併發連接數或請求數限制
嵌入Perl語言
I/O模型:當一個進程發起I/O請求,發起系統調用,轉爲內核模式,I/O調用分爲兩步,第一步,由內核把文件從磁盤載入到內核空間內存,因爲進程不能訪問內核空間內存,所以,第二步,要把文件內容從內核空間複製到進程空間。這樣才完成一次I/O操作
在uxix和linux下總共有五種I/O模型
阻塞I/O:指當進程I/O調用需要一段時間才能完成,於是進程就被阻塞在這,只有當所有的操作都已經完成,進程所需要的數據都已經複製到進程能夠操作的內存空間裏面以後,進程才能繼續後面的操作,在I/O操作完成之前,進程只能等待,而且由於等待I/O時被CPU進程切換交換出去,進程轉換爲不可中斷狀態,這種情況叫做阻塞I/O操作。
非阻塞I/O模型:忙等待狀態,當一個I/O操作未完成時,不將進程睡眠,而是返回一個錯誤狀態,於是I/O操作函數不斷地測試數據是否準備好,如果未準備好,繼續測試,直到數據準備完成爲止,這個不斷的測試過程會消耗大量CPU時間。這個操作過程只是在第一步過程不斷去測試,第二步從內核空間拷貝到進程空間也還是阻塞的。
I/O複用模型: 不再用進程本身去等待數據準備過程,而由複用器select和poll函數來測試數據有沒有準備好。複用器可以監控多個I/O的等待過程,當有一個I/O操作的數據已經準備好,則返回給進程信息,那麼依賴這個I/O操作的進程可以繼續操作。
事件(信號)驅動模型(event-driver): 事件驅動屬於文件I/O,首先允許套接口進行信號驅動I/O,並安裝一個信號處理函數,進程繼續運行並不阻塞。當數據準備好時,進程會收到一個SIGIO信號,但第二步仍然是阻塞的,也是一種複用機制,基於事件驅動的複用器。在linux上實現事件驅動的複用機器叫epoll。事件驅動觸發機制分爲兩種:①水平觸發:如果數據準備好後通知一次以後,進程沒有迴應,那麼信號器反覆通知進得去執行下一步操作的機器②邊緣觸發:數據準備好以後只通知一次,進程通過讀取通知信息後去執行下一步操作。
異步I/O模型(AIO):當內核把數據從內核空間拷貝到應用空間以後,再發通知給應用程序(進程)。異步I/O和基於事件驅動的區別是:異步模型是等所有的I/O操作都已經完畢後再通知用戶程序(進程),而事件驅動模型是I/O的第一步從磁盤讀入到內核空間以後就通知進程,而從內核空間拷貝到用戶空間過程還是阻塞的。
幾種I/O模型的比較:
前面四種I/O模型的區別在第一階段,第二階段都是相同的,數據從內核空間複製到應用空間都是阻塞的。而異步I/O則兩個階段都不同於前面四個模型。
同步I/O和異步I/O
a.同步I/O操作引起請求進程阻塞,直到I/O操作完成。異步I/O操作不引起請求進程阻塞。
b.我們的前四個模型都是同步I/O,只有最後一個異步I/O模型是異步I/O。
有兩種類型的文件IO同步:同步文件IO和異步文件IO。異步文件IO也就是重疊IO。在同步文件IO中,線程啓動一個IO操作然後就立即進入等待狀態,直到IO操作完成後才醒來繼續執行。而異步文件IO方式中,線程發送一個IO請求到內核,然後繼續處理其他的事情,內核完成IO請求後,將會通知線程IO操作完成了。
如果IO請求需要大量時間執行的話,異步文件IO方式可以顯著提高效率,因爲在線程等待的這段時間內,CPU將會調度其他線程進行執行,如果沒有其他線程需要執行的話,這段時間將會浪費掉(可能會調度操作系統的零頁線程)。如果IO請求操作很快,用異步IO方式反而還低效,還不如用同步IO方式。
同步IO在同一時刻只允許一個IO操作,也就是說對於同一個文件句柄的IO操作是序列化的,即使使用兩個線程也不能同時對同一個文件句柄同時發出讀寫操作。重疊IO允許一個或多個線程同時發出IO請求。
異步IO在請求完成時,通過將文件句柄設爲有信號狀態來通知應用程序,或者應用程序通過GetOverlappedResult察看IO請求是否完成,也可以通過一個事件對象來通知應用程序。
簡單的說“同步在編程裏,一般是指某個IO操作執行完後,纔可以執行後面的操作。異步則是,將某個操作給系統,主線程去忙別的事情,等內核完成操作後通知主線程異步操作已經完成。”
mmap: 內存映射,在I/O執行第一步以後,把進程的進程地址空間映射到內核空間上去,直接讀取內核空間的數據,不需要再執行第二步,從內核空間複製到用戶空間的操作。
nginx在設計的時候主要着眼點就是高性能和對物理資源的高密度利用,因此採用了模塊化、事件驅動、異步I/O、單線程及非阻塞架構,並大量採用了多路複用及事件通知機制,也支持mmap。
nginx會按需要運行多個主進程:一個主進程(master)和幾個工作進程(worker),如果配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理進程(cache manager)等,主進程以root用戶身份運行,而worker、cache loader 和cache manager都不是以root用戶運行
nginx安裝
安裝環境 centos6.5 64bit,nginx使用的是1.62版本
在編譯安裝nginx之前,首先要解決依賴關係,在centos中有兩個開發包組“Development Tools””Server Platform Development”,用yum安裝,就可以解決大部份的依賴關係。再安裝openssl-devel和pcre-devel
#yum groupinstall “Development Tools””Server Platform Development” –y
#yum install openssl-devel pcre-devel
下載nginx-1.6.2.tar.gz到/usr/local/src目錄下,解壓
#tar –xf nginx-1.6.2.tar.gz
#useradd –r nginx 添加nginx帳號爲系統用戶
cd到nginx-1.6.2目錄下,用./configure –help可以看到很多參數的幫助信息 ,--with表示默認安裝nginx的一些模塊,--without 顯示的是默認不安裝的模塊,如果有哪些需要安裝的模塊,那在編譯的時候要加上這些模塊進行編譯
#./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/nginx.pid \ --lock-path=/var/lock/nginx.lock \ --user=nginx \ --group=nginx \ --http-client-body-temp-path=/var/tmp/nginx/client/ \ --http-proxy-temp-path=/var/tmp/nginx/proxy/ \ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ \ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi \ --http-scgi-temp-path=/var/tmp/nginx/scgi \ --with-pcre #make && make install
#cd /etc/nginx/
#cp nginx.conf nginx.conf.bak #把配置文件備份一份
添加SysV init 服務啓動腳本
#vim /etc/init.d/nginx
#!/bin/sh # # nginx - this script starts and stops the nginx daemon # # chkconfig: - 85 15 # description: Nginx is an HTTP(S) server, HTTP(S) reverse \ # proxy and IMAP/POP3 proxy server # processname: nginx # config: /etc/nginx/nginx.conf # config: /etc/sysconfig/nginx # pidfile: /var/run/nginx.pid # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ "$NETWORKING" = "no" ] && exit 0 nginx="/usr/local/nginx/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/etc/nginx/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { # make required directories user=`nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then # echo "creating" $value mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
# chmod +x /etc/init.d/nginx #添加執行權限
# chkconfig --add nginx #添加到服務列表
# chkconfig nginx on #設置開機啓動
# service nginx start #啓動服務
nginx訪問正常