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

nginx特性及I/O模型&nginx安装_第1张图片

                非阻塞I/O模型:忙等待状态,当一个I/O操作未完成时,不将进程睡眠,而是返回一个错误状态,于是I/O操作函数不断地测试数据是否准备好,如果未准备好,继续测试,直到数据准备完成为止,这个不断的测试过程会消耗大量CPU时间。这个操作过程只是在第一步过程不断去测试,第二步从内核空间拷贝到进程空间也还是阻塞的。

nginx特性及I/O模型&nginx安装_第2张图片

                    I/O复用模型: 不再用进程本身去等待数据准备过程,而由复用器select和poll函数来测试数据有没有准备好。复用器可以监控多个I/O的等待过程,当有一个I/O操作的数据已经准备好,则返回给进程信息,那么依赖这个I/O操作的进程可以继续操作。

nginx特性及I/O模型&nginx安装_第3张图片

                 事件(信号)驱动模型(event-driver): 事件驱动属于文件I/O,首先允许套接口进行信号驱动I/O,并安装一个信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个SIGIO信号,但第二步仍然是阻塞的,也是一种复用机制,基于事件驱动的复用器。在linux上实现事件驱动的复用机器叫epoll。事件驱动触发机制分为两种:①水平触发:如果数据准备好后通知一次以后,进程没有回应,那么信号器反复通知进得去执行下一步操作的机器②边缘触发:数据准备好以后只通知一次,进程通过读取通知信息后去执行下一步操作。

nginx特性及I/O模型&nginx安装_第4张图片

                     异步I/O模型(AIO):当内核把数据从内核空间拷贝到应用空间以后,再发通知给应用程序(进程)。异步I/O和基于事件驱动的区别是:异步模型是等所有的I/O操作都已经完毕后再通知用户程序(进程),而事件驱动模型是I/O的第一步从磁盘读入到内核空间以后就通知进程,而从内核空间拷贝到用户空间过程还是阻塞的。

nginx特性及I/O模型&nginx安装_第5张图片

几种I/O模型的比较:
前面四种I/O模型的区别在第一阶段,第二阶段都是相同的,数据从内核空间复制到应用空间都是阻塞的。而异步I/O则两个阶段都不同于前面四个模型。

nginx特性及I/O模型&nginx安装_第6张图片

同步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  显示的是默认不安装的模块,如果有哪些需要安装的模块,那在编译的时候要加上这些模块进行编译

nginx特性及I/O模型&nginx安装_第7张图片

#./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特性及I/O模型&nginx安装_第8张图片
nginx访问正常