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访问正常