nginx特性及I/O模型&nginx安裝

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操作。

image

                非阻塞I/O模型:忙等待狀態,當一個I/O操作未完成時,不將進程睡眠,而是返回一個錯誤狀態,於是I/O操作函數不斷地測試數據是否準備好,如果未準備好,繼續測試,直到數據準備完成爲止,這個不斷的測試過程會消耗大量CPU時間。這個操作過程只是在第一步過程不斷去測試,第二步從內核空間拷貝到進程空間也還是阻塞的。

image

                    I/O複用模型: 不再用進程本身去等待數據準備過程,而由複用器select和poll函數來測試數據有沒有準備好。複用器可以監控多個I/O的等待過程,當有一個I/O操作的數據已經準備好,則返回給進程信息,那麼依賴這個I/O操作的進程可以繼續操作。

image

                 事件(信號)驅動模型(event-driver): 事件驅動屬於文件I/O,首先允許套接口進行信號驅動I/O,並安裝一個信號處理函數,進程繼續運行並不阻塞。當數據準備好時,進程會收到一個SIGIO信號,但第二步仍然是阻塞的,也是一種複用機制,基於事件驅動的複用器。在linux上實現事件驅動的複用機器叫epoll。事件驅動觸發機制分爲兩種:①水平觸發:如果數據準備好後通知一次以後,進程沒有迴應,那麼信號器反覆通知進得去執行下一步操作的機器②邊緣觸發:數據準備好以後只通知一次,進程通過讀取通知信息後去執行下一步操作。

image

                     異步I/O模型(AIO):當內核把數據從內核空間拷貝到應用空間以後,再發通知給應用程序(進程)。異步I/O和基於事件驅動的區別是:異步模型是等所有的I/O操作都已經完畢後再通知用戶程序(進程),而事件驅動模型是I/O的第一步從磁盤讀入到內核空間以後就通知進程,而從內核空間拷貝到用戶空間過程還是阻塞的。

image

幾種I/O模型的比較:
前面四種I/O模型的區別在第一階段,第二階段都是相同的,數據從內核空間複製到應用空間都是阻塞的。而異步I/O則兩個階段都不同於前面四個模型。

image

同步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  顯示的是默認不安裝的模塊,如果有哪些需要安裝的模塊,那在編譯的時候要加上這些模塊進行編譯

image

#./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                 #啓動服務
image
nginx訪問正常
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章