高性能web服务器nginx(一)之基本概念

说明本篇文章大部分参考此人的博文:http://freeloda.blog.51cto.com/2033581/1285722,建议若想继续深入学习nginx时最好先看下此人所写的文章,总结的很详细,然后在找相关的书籍和查阅官方文档学习。


一、NGINX介绍

1 简介

   传统上基于进程或线程模型架构的web服务通过每进程或每线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下。生成一个新的进程/线程需要事先备好其运行时环境,这包括为其分配堆内存和栈内存,以及为其创建新的执行上下文等。这些操作都需要占用CPU,而且过多的进程/线程还会带来线程抖动或频繁的上下文切换,系统性能也会由此进一步下降。另一种高性能web服务器/web服务器反向代理:Nginx(Engine X),nginx的主要着眼点就是其高性能以及对物理计算资源的高密度利用,因此其采用了不同的架构模型。受启发于多种操作系统设计中基于“事件”的高级处理机制,nginx采用了模块化、事件驱动、异步、单线程及非阻塞的架构,并大量采用了多路复用及事件通知机制。在nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环(run-loop)机制进行处理,而每个worker可以并行处理数千个的并发连接及请求。


2 Nginx 工作原理

   Nginx会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程(cache loader)和缓存管理器进程(cache manager)等。所有进程均是仅含有一个线程,并主要通过“共享内存”的机制实现进程间通信。主进程以root用户身份运行,而worker、cache loader和cache manager均应以非特权用户身份运行。

主进程主要完成如下工作:

  • 读取并验正配置信息;

  • 创建、绑定及关闭套接字;

  • 启动、终止及维护worker进程的个数;

  • 无须中止服务而重新配置工作特性;

  • 控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本;

  • 重新打开日志文件;

  • 编译嵌入式perl脚本;

  • worker进程主要完成的任务包括:

  • 接收、传入并处理来自客户端的连接;

  • 提供反向代理及过滤功能;

  • nginx任何能完成的其它任务;


3 Nginx 架构

   Nginx的代码是由一个核心和一系列的模块组成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能;还用于启用网络协议,创建必要的运行时环境以及确保不同的模块之间平滑地进行交互。不过,大多跟协议相关的功能和某应用特有的功能都是由nginx的模块实现的。这些功能模块大致可以分为事件模块、阶段性处理器、输出过滤器、变量处理器、协议、upstream和负载均衡几个类别,这些共同组成了nginx的http功能。事件模块主要用于提供OS独立的(不同操作系统的事件机制有所不同)事件通知机制如kqueue或epoll等。协议模块则负责实现nginx通过http、tls/ssl、smtp、pop3以及imap与对应的客户端建立会话。在Nginx内部,进程间的通信是通过模块的pipeline或chain实现的;换句话说,每一个功能或操作都由一个模块来实现。例如,压缩、通过FastCGI或uwsgi协议与upstream服务器通信,以及与memcached建立会话等。


4 Nginx 基础功能

  • 处理静态文件,索引文件以及自动索引;

  • 反向代理加速(无缓存),简单的负载均衡和容错;

  • FastCGI,简单的负载均衡和容错;

  • 模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI过滤器中,到同一个 proxy 或者 FastCGI 的多个子请求并发处理;

  • SSL 和 TLS SNI 支持;


5 Nginx IMAP/POP3 代理服务功能

  • 使用外部 HTTP 认证服务器重定向用户到 IMAP/POP3 后端;

  • 使用外部 HTTP 认证服务器认证用户后连接重定向到内部的 SMTP 后端;

  • 认证方法:

  • POP3: POP3 USER/PASS, APOP, AUTH LOGIN PLAIN CRAM-MD5;

  • IMAP: IMAP LOGIN;

  • SMTP: AUTH LOGIN PLAIN CRAM-MD5;

  • SSL 支持;

  • 在 IMAP 和 POP3 模式下的 STARTTLS 和 STLS 支持;


6 Nginx 支持的操作系统

  • FreeBSD 3.x, 4.x, 5.x, 6.x i386; FreeBSD 5.x, 6.x amd64;

  • Linux 2.2, 2.4, 2.6 i386; Linux 2.6 amd64;

  • Solaris 8 i386; Solaris 9 i386 and sun4u; Solaris 10 i386;

  • MacOS X (10.4) PPC;

  • Windows 编译版本支持 windows 系列操作系统;


7 Nginx 结构与扩展

  • 一个主进程和多个工作进程,工作进程运行于非特权用户;

  • kqueue (FreeBSD 4.1+), epoll (Linux 2.6+), rt signals (Linux 2.2.19+), /dev/poll (Solaris 7 11/99+), select, 以及 poll 支持;

  • kqueue支持的不同功能包括 EV_CLEAR, EV_DISABLE (临时禁止事件), NOTE_LOWAT, EV_EOF, 有效数据的数目,错误代码;

  • sendfile (FreeBSD 3.1+), sendfile (Linux 2.2+), sendfile64 (Linux 2.4.21+), 和 sendfilev (Solaris 8 7/01+) 支持;

  • 输入过滤 (FreeBSD 4.1+) 以及 TCP_DEFER_ACCEPT (Linux 2.4+) 支持;

  • 10,000 非活动的 HTTP keep-alive 连接仅需要 2.5M 内存。

  • 最小化的数据拷贝操作;


8 Nginx 其他HTTP功能

  • 基于IP 和名称的虚拟主机服务;

  • Memcached 的 GET 接口;

  • 支持 keep-alive 和管道连接;

  • 灵活简单的配置;

  • 重新配置和在线升级而无须中断客户的工作进程;

  • 可定制的访问日志,日志写入缓存,以及快捷的日志回卷;

  • 4xx-5xx 错误代码重定向;

  • 基于 PCRE 的 rewrite 重写模块;

  • 基于客户端 IP 地址和 HTTP 基本认证的访问控制;

  • PUT, DELETE, 和 MKCOL 方法;

  • 支持 FLV (Flash 视频);

  • 带宽限制;


9 为什么选择Nginx

  • 在高连接并发的情况下,Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢Nginx为我们选择了 epoll and kqueue 作为开发模型。

  • Nginx作为负载均衡服务器: Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务, 也可以支持作为 HTTP代理 服务器对外进行服务. Nginx采用C进行编写, 不论是系统资源开销还是CPU使用效率都比 Perlbal 要好很多。

  • 作为邮件代理服务器: Nginx 同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器), Last.fm 描述了成功并且美妙的使用经验.

  • Nginx 是一个 [#installation 安装] 非常的简单 , 配置文件 非常简洁(还能够支持perl语法),Bugs 非常少的服务器: Nginx 启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动. 你还能够 不间断服务的情况下进行软件版本的升级 。

  • Nginx 的诞生主要解决C10K问题


10 三种工作模型比较:

Web服务器要为用户提供服务,必须以某种方式,工作在某个套接字上。一般Web服务器在处理用户请求是,一般有如下三种方式可选择:多进程方式、多线程方式、异步方式。

  • 多进程方式:为每个请求启动一个进程来处理。由于在操作系统中,生成进程、销毁进程、进程间切换都很消耗CPU和内存,当负载高是,性能会明显降低。而httpd的prefork模型就是使用此种方式工作,故其性能较低。

优点: 稳定性!由于采用独立进程处理独立请求,而进程之间是独立的,单个进程问题不会影响其他进程,因此稳定性最好。

缺点: 资源占用!当请求过大时,需要大量的进程处理请求,进程生成、切换开销很大,而且进程间资源是独立的,造成内存重复利用。

  • 多线程方式:一个进程生成多个线程其中用多个线程处理用户请求。由于线程开销明显小于进程,而且部分资源还可以共享,因此效率较高。而httpd的worker模型就是使用此种方式工作。

优点:开销较小!线程间部分数据是共享的,且线程生成与线程间的切换所需资源开销比进程间切换小得多。

缺点:稳定性!线程切换过快可能造成线程抖动,且线程过多会造成服务器不稳定。

  • 异步方式(事件模型):使用非阻塞方式处理请求,是三种方式中开销最小的。但异步方式虽然效率高,但要求也高,因为多任务之间的调度如果出现问题,就可能出现整体故障,因此使用异步工作的,一般是一些功能相对简单,但却符合服务器任务调度、且代码中没有影响调度的错误代码存在的程序。而httpd的event模型就是使用此种方式工作。

优点:性能最好!一个进程或线程处理多个请求,不需要额外开销,性能最好,资源占用最低。

缺点:稳定性!某个进程或线程出错,可能导致大量请求无法处理,甚至导致整个服务宕机。


11 一个Web请求的处理过程:

wKioL1XxR_LxouA5AAFFm5Xgto4627.jpg

  1. 客户发起情况到服务器网卡;

  2. 服务器网卡接受到请求后转交给内核处理;

  3. 内核根据请求对应的套接字,将请求交给工作在用户空间的Web服务器进程

  4. Web服务器进程根据用户请求,向内核进行系统调用,申请获取相应资源(如index.html)

  5. 内核发现web服务器进程请求的是一个存放在硬盘上的资源,因此通过驱动程序连接磁盘

  6. 内核调度磁盘,获取需要的资源

  7. 内核将资源存放在自己的缓冲区中,并通知Web服务器进程

  8. Web服务器进程通过系统调用取得资源,并将其复制到进程自己的缓冲区中

  9. Web服务器进程形成响应,通过系统调用再次发给内核以响应用户请求

  10. 内核将响应发送至网卡

  11. 网卡发送响应给用户

通过这样的一个复杂过程,一次请求就完成了。

简单来说就是:用户请求-->送达到用户空间-->系统调用-->内核空间-->内核到磁盘上读取网页资源->返回到用户空间->响应给用户。上述简单的说明了一下,客户端向Web服务请求过程,在这个过程中,有两个I/O过程,一个就是客户端请求的网络I/O,另一个就是Web服务器请求页面的磁盘I/O。 


二、安装nginx

1、下载nginx并解压

1
2
[root@Director ~]# wget http://nginx.org/download/nginx-1.8.0.tar.gz
[root@Director ~]# tar -xf nginx-1.8.0.tar.gz

2、创建nginx运行用户

1
2
3
4
[root@Director ~]# groupadd -g 108 -r nginx 
[root@Director ~]# useradd -u 108 -r -g 108 nginx
[root@Director ~]# id nginx
uid=108(nginx) gid=108(nginx) 组=108(nginx)


3、编译安装nginx

1
2
3
[root@Director ~]# cd nginx-1.8.0
[root@Director nginx-1.8.0]# ./configure  --prefix=/usr   --sbin-path=/usr/sbin/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   --with-http_ssl_module   --with-http_flv_module   --with-http_stub_status_module   --with-http_gzip_static_module   --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
[root@Director nginx-1.8.0]# make && make install


4、查看nginx命令安装的路径

1
2
[root@Director nginx-1.8.0]# which nginx
/usr/sbin/nginx

查看nginx安装版本:

1
2
[root@Director nginx-1.8.0]# nginx -v
nginx version: nginx/1.8.0

查看nginx编译选项:

1
2
3
4
5
6
[root@Director nginx-1.8.0]# nginx -V
nginx version: nginx/1.8.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr --sbin-path=/usr/sbin/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 --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --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


5、为nginx提供SysV init脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
[root@Director nginx-1.8.0]# 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/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


6、将脚本赋予执行权限并添加到服务启动列表

1
2
3
[root@Director nginx-1.8.0]# chmod +x /etc/init.d/nginx
[root@Director nginx-1.8.0]# chkconfig --add nginx
[root@Director nginx-1.8.0]# chkconfig nginx on


7、启动nginx查看监听的端口

1
2
3
4
[root@Director nginx-1.8.0]# service nginx start
正在启动 nginx:                                           [确定]
[root@Director nginx-1.8.0]# ss -tunlp |grep nginx
tcp    LISTEN     0      128                    *:80                    *:*      users:(("nginx",4618,6),("nginx",4620,6))


8、浏览器输入linux主机的IP查看是否安装成功

wKiom1XxRe7h3GRbAAHMQXGnLD8536.jpg

9、将在vim打开nginx配置文件时实现语句高亮显示

http://www.vim.org/scripts/script.php?script_id=1886

1
2
3
4
[root@Director ~]# mkdir -pv .vim/syntax
[root@Director ~]# mv nginx.vim .vim/syntax
[root@Director ~]# vim .vim/filetype.vim
au BufRead,BufNewFile /etc/nginx/*,/usr/local/nginx/conf/* if &ft == '' | setfiletype nginx | endif


三、nginx配置文件

1、配置文件结构

   Nginx配置文件主要分为4部分:main(全局设置)、server(主机设置)、upstream(负载均衡服务器设置)和 location(URL匹配特定位置的设置)。main部分设置的指令将影响其他所有设置;server部分的指令主要用于指定主机和端口;upstream指令主要用于负载均衡,设置一系列的后端服务器;location部分用于匹配网页位置。这四者之间的关系如下:server继承main,location继承server,upstream既不会继承其他设置也不会被继承。如下图,

wKiom1XxRgnBfvyEAADHEM44eYk919.jpg

在这4个部分当中,每个部分都包含若干指令,这些指令主要包含Nginx的主模块指令、事件模块指令、HTTP核心模块指令。同时每个部分还可以使用其他HTTP模块指令,例如Http SSL模块、Http Gzip Static模块和Http Addition模块等。

   下面通过一个Nginx配置实例,详细介绍nginx.conf每个指令的含义。为了能更清楚地了解Nginx的结构和每个配置选项的含义,这里按照功能点将Nginx配置文件分为7个部分依次讲解。下面就围绕这7个部分进行介绍。


2、一般配置文件介绍

(1).Nginx 的全局配置文件

1
2
3
4
5
6
7
8
9
10
11
12
#user  nobody;  
worker_processes  1;
#error_log  logs/error.log;  
#error_log  logs/error.log  notice;  
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;
worker_rlimit_nofile 65535;
worker_rlimit_sigpending #;
events {
    use epoll;
    worker_connections  1024;  
}

上面这段代码中每个配置选项的含义解释如下:

  • user是个主模块指令,指定Nginx Worker进程运行用户以及用户组,默认由nobody账号运行。 

  • worker_processes  是个主模块指令,指定了Nginx要开启的进程数。每个Nginx进程平均耗费10MB~12MB内存。根据经验,一般指定一个进程足够了,如果是多核CPU,建议指定为CPU核心数减一个进程数即可。(注,如果负载以CPU密集型应用为主,如SSL或压缩应用,则worker数应与CPU数相同;如果负载以IO密集型为主,如响应大量内容给客户端,则worker数应该为CPU个数的1.5或2倍。) 

  • error_log是个主模块指令,用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少。 

  • pid 是个主模块指令,用来指定进程id的存储文件位置。 

  • worker_rlimit_nofile 指定一个worker进程所能够打开的最大文件句柄数。

  • worker_rlimit_sigpending  设定每个用户能够发往worker进程的信号的数量。

  • events指令用来设定Nginx的工作模式及连接数上限。 

  • use是个事件模块指令,用来指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中。此选择建议还是由nginx自行选择。

  • worker_connections也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024。最大客户端连接数由worker_processes和worker_connections决定,即max_client=worker_processes*worker_connections,在作为反向代理时变为:max_clients = worker_processes * worker_connections/4。(注,进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令“ulimit -n 65536”后worker_connections的设置才能生效。)

(2).HTTP服务器配置

http {  

    include       mime.types;  

    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  

    #                  '$status $body_bytes_sent "$http_referer" '  

    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;  

    #tcp_nopush     on;

    #keepalive_timeout  0;  

    keepalive_timeout  65;

    #gzip  on;

下面详细介绍这段代码中每个配置选项的含义。

  • include是个主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度。类似于Apache中的include方法。 

  • default_type 属于HTTP核心模块指令,这里设定默认类型为二进制流,也就是当文件类型未定义时使用这种方式,例如在没有配置PHP环境时,Nginx是不予解析的,此时,用浏览器访问PHP文件就会出现下载窗口。 

  • log_format是Nginx的HttpLog模块指令,用于指定Nginx日志的输出格式。main为此日志输出格式的名称,可以在下面的access_log指令中引用。 

  • client_max_body_size用来设置允许客户端请求的最大的单个文件字节数。 

  • client_header_buffer_size用于指定来自客户端请求头的headerbuffer大小。对于大多数请求,1KB的缓冲区大小已经足够,如果自定义了消息头或有更大的cookie,可以增加缓冲区大小。这里设置为32KB。 

  • large_client_header_buffers用来指定客户端请求中较大的消息头的缓存最大数量和大小, “4”为个数,“128K”为大小,最大缓存为4个128KB。 

  • sendfile参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodely两个指令设置为on,用于防止网络阻塞。 

  • keepalive_timeout 用于设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接。 

  • client_header_timeout用于设置客户端请求头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误。 

  • client_body_timeout用于设置客户端请求主体读取超时时间,默认值为60。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Request time out(408)”错误。 

  • send_timeout用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。 

  • gzip用于设置开启或者关闭gzip模块,“gzip on”表示开启gzip压缩,实时压缩输出数据流。

(3).HttpGzip模块配置

        下面配置Nginx的HttpGzip模块。这个模块支持在线实时压缩输出数据流。要查看是否安装了此模块,需要使用下面的命令:nginx -V  ,通过nginx -V 命令可以查看安装Nginx时的编译选项。下面是HttpGzip模块在Nginx配置中的相关属性设置:

#gzip  on;

#gzip_min_length  1k;

#gzip_buffers     4  16k;

#gzip_http_version  1.1;

#gzip_comp_level  2;

#gzip_types  text/plain application/x-javascript text/css application/xml;

#gzip_vary  on;

  • gzip用于设置开启或者关闭gzip模块,“gzip on”表示开启gzip压缩,实时压缩输出数据流。 

  • gzip_min_length用于设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大。 

  • gzip_buffers表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。 

  • gzip_buffers表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。 

  • gzip_comp_level用来指定gzip压缩比,1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源。 

  • gzip_types用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的。 

  • gzip_vary选项可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。

(4).负载均衡配置

下面设定负载均衡的服务器列表:

1
2
3
4
5
6
7
upstream test.net{
ip_hash;
server 192.168.10.13:80;
server 192.168.10.14:80  down;
server 192.168.10.15:8009  max_fails=3  fail_timeout=20s;
server 192.168.10.16:8080;
}
  • upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。在上面的设定中,通过upstream指令指定了一个负载均衡器的名称test.net。这个名称可以任意指定,在后面需要用到的地方直接调用即可。 

  • Nginx的负载均衡模块目前支持4种调度算法,下面进行分别介绍,其中后两项属于第三方调度算法。       

  • 轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。 

  • Weight。指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。 

  • ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。 

  • fair。这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。 

  • url_hash。此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx 的hash软件包。 

  • 在HTTP Upstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:       

    • down,表示当前的server暂时不参与负载均衡。 

    • backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。 

    • max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误。 

    • fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。

注意,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

(5).server虚拟主机配置

下面介绍对虚拟主机的配置。建议将对虚拟主机进行配置的内容写进另外一个文件,然后通过include指令包含进来,这样更便于维护和管理。

1
2
3
4
5
6
7
server{
listen         80;
server_name    192.168.12.188  www.test.net;
index index.html index.htm index.php;
root  /web/www/www.test.net
charset gb2312;
access_log  logs/www.test.net.access.log  main;
  • server标志定义虚拟主机开始; 

  • listen用于指定虚拟主机的服务器端口; 

  • server_name用来指定IP地址或者域名,多个域名之间用空格分开; 

  • index用于设定访问的默认首页地址; 

  • root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径; 

  • charset用于设置网页的默认编码格式。 

  • access_log用来指定此虚拟主机的访问日志存放路径。最后的main用于指定访问日志的输出格式。

(6).URL匹配配置

URL地址匹配是Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页的过滤处理。

格式:location [ = | ~ | ~* | ^~ ] uri { ... }

location URI {}:对当前路径及子路径下的所有对象都生效;

location = URI {}:精确匹配指定的路径,不包括子路径,因此,只对当前资源生效;

location ~ URI {},location ~* URI {}:模式匹配URI,此处的URI可使用正则表达式,~区分字符大小写,~*不区分字符大小写;

location ^~ URI {}:不使用正则表达式

案例1:

1
2
3
4
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$  {
                    root    /web/www/www.test.net;
                    expires 30d;
       }

说明:上面这段设置是通过location指令来对网页URL进行分析处理,所有扩展名为.gif、.jpg、.jpeg、.png、.bmp、.swf的静态文件都交给Nginx处理,而expires用来指定静态文件的过期时间,这里是30天。

案例2:

1
2
3
4
location ~ ^/(upload|html)/  {
                root    /web/www/www.test.net;
                expires 30d;
}

说明:上面这段设置是将upload和html下的所有文件都交给Nginx来处理,当然,upload和html目录包含/web/www/www.test.net目录中。

案例3:

1
2
3
4
location ~ .*.jsp$ {
            index index.jsp;
            proxy_pass http://localhost:8080;
          }

说明:在最后这段设置中,location是对此虚拟主机下动态网页的过滤处理,也就是将所有以.jsp为后缀的文件都交给本机的8080端口处理。

location [ = | ~ | ~* | ^~ ] 优先级

  • ocation = URI {}:精确匹配指定的路径,不包括子路径,因此,只对当前资源生效;(优先级最高) 

  • location ^~ URI {}:不使用正则表达式;(优先级次之) 

  • location ~ URI {},location ~* URI {}:模式匹配URI,此处的URI可使用正则表达式,~区分字符大小写,~*不区分字符大小写;(优先级次之) 

  • location URI {}:对当前路径及子路径下的所有对象都生效;(优先级最低)

(7).StubStatus模块配置

StubStatus模块能够获取Nginx自上次启动以来的工作状态,此模块非核心模块,需要在Nginx编译安装时手工指定才能使用。以下指令指定启用获取Nginx工作状态的功能。

1
2
3
4
5
6
location /NginxStatus {
    stub_status     on;
    access_log             logs/NginxStatus.log;
    auth_basic             "NginxStatus";
    auth_basic_user_file    ../htpasswd;
       }
  • stub_status为“on”表示启用StubStatus的工作状态统计功能; 

  • access_log 用来指定StubStatus模块的访问日志文件; 

  • auth_basic是Nginx的一种认证机制; 

  • auth_basic_user_file用来指定认证的密码文件。

   由于Nginx的auth_basic认证采用的是与Apache兼容的密码文件,因此需要用Apache的htpasswd命令来生成密码文件。例如要添加一个webadmin用户,可以使用下面的方式生成密码文件:

/usr/local/apache/bin/htpasswd -c  /opt/nginx/conf/htpasswd webadmin

要查看Nginx的运行状态,可以输入http://ip/ NginxStatus,然后输入刚刚创建的用户名和密码就可以看到如下信息:

1
2
3
4
Active connections: 1
server accepts handled requests
393411 393411 393799
Reading: 0 Writing: 1 Waiting: 0
  • Active connections表示当前活跃的连接数。 

  • 第三行的3个数字表示 Nginx当前总共处理了393411个连接, 成功创建了393 411次握手,总共处理了393 799个请求。 

  • 最后一行的Reading表示Nginx读取到客户端Header信息数; Writing表示Nginx返回给客户端的Header信息数;Waiting表示Nginx已经处理完、正在等候下一次请求指令时的驻留连接数。

补充说明:

1
2
3
4
5
error_page  404              /404.html;
error_page   500 502 503 504  /50x.html;
location = /50x.html {
           root   html;
       }

在最后这段设置中,设置了虚拟主机的错误信息返回页面,通过error_page指令可以定制各种错误信息的返回页面。在默认情况下,Nginx会在主目录的html目录中查找指定的返回页面。特别需要注意的是,这些错误信息的返回页面大小一定要超过512KB,否则会被IE浏览器替换为IE默认的错误页面。好了,到这里nginx的配置文件讲解全部完成。下面我们来说一说nginx命令参数。


3、配置文件深入介绍

(1).优化性能相关的配置

  • worker_rlimit_nofile #;  指定一个worker进程所能够打开的最大文件句柄数;

  • worker_rlimit_sigpending #;  设定每个用户能够发往worker进程的信号的数量;

  • worker_processes #;  worker进程的个数;通常其数值应该为CPU的物理核心数减1;

  • worker_cpu_affinity cpumask ...;  CPU亲源性及使各个woeker进程分别运行在指定的CPU上,注意CPU是使用掩码格式来填写。但是这种方法并不能禁止系统使用该CPU进行其他的操作,还需要结合系统调优及CPU隔离才能很好的使用此选项,从而有效的减少CPU的上下文切换。举例:worker_processes 6;  worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000; 

  • ssl_engine device;   在存在ssl硬件加速器的服务器上,指定所使用的ssl硬件加速设备;

  • timer_resolution t;  每次内核事件调用返回时,都会使用gettimeofday()来更新nginx缓存时钟;timer_resolution用于定义每隔多久才会由gettimeofday()更新一次缓存时钟;x86-64系统上,gettimeofday()代价已经很小,可以忽略此配置;

  • worker_priority nice;  worker进程的优先级,默认为0建议调小点,但不能过小。-20,19之间的值;

(2).事件相关的配置

  • accept_mutex [on|off] ;  是否打开Ningx的负载均衡锁;此锁能够让多个worker进轮流地、序列化地与新的客户端建立连接;而通常当一个worker进程的负载达到其上限的7/8,master就尽可能不再将请求调度此worker;

  • lock_file /path/to/lock_file;  lock文件

  • accept_mutex_delay #ms;  accept锁模式中,一个worker进程为取得accept锁的等待时长;如果某worker进程在某次试图取得锁时失败了,至少要等待#ms才能再一次请求锁;默认500ms。

  • multi_accept on|off;  是否允许一次性地响应多个用户请求;默认为Off; 

  • use [epoll|rtsig|select|poll];  定义使用的事件模型,建议让nginx自动选择;

  • worker_connections #;   每个worker能够并发响应最大请求数; 

(3).调试、定位nginx问题

  • daemon on|off;  是否让ningx运行后台;默认为on,调试时可以设置为off,使得所有信息去接输出控制台;

  • master_process on|off  是否以master/worker模式运行nginx;默认为on;调试时可设置off以方便追踪;

  • error_log /path/to/error_log level;  错误日志文件及其级别;默认为error级别;调试时可以使用debug级别,但要求在编译时必须使用--with-debug启用debug功能;

(4).虚拟主机相关的配置

  • server {}  定义一个虚拟主机;nginx支持使用基于主机名或IP的虚拟主机;

  • listen address[:port] [default_server] [ssl] [spdy] [proxy_protocol] [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];

说明:

    default_server:定义此server为http中默认的server;如果所有的server中没有任何一个listen使用此参数,那么第一个server即为默认server;

    backlog=number:指明tcp协议的backlog队列的大小,默认为-1,表示不设置 后援队列;

    rcvbuf=SIZE: 接收缓冲大小;

    sndbuf=SIZE: 发送缓冲大小;

    ssl: https server;

  • server_name [...]; server_name可以跟多个主机名,名称中可以使用通配符和正则表达式(通常以~开头);当nginx收到一个请求时,会取出其首部的server的值,而后跟众server_name进行比较;比较方式: 

    • 先做精确匹配;www.example.com  

    • 左侧通配符匹配;*.example.com 

    • 右侧通配符匹配;www.* 

    • 正则表达式匹配: ~^.*\.example\.com$

  • server_name_hash_bucket_size 32|64|128;  为了实现快速主机查找,nginx使用hash表来保存主机名;

  • location [ = | ~ | ~* | ^~ ] uri { ... } | location @name { ... } 功能:允许根据用户请求的URI来匹配指定的各location以进行访问配置;匹配到时,将被location块中的配置所处理;比如:http://www.example.com/images/logo.gif 

      =:精确匹配;

      ~:正则表达式模式匹配,匹配时区分字符大小写

      ~*:正则表达式模式匹配,匹配时忽略字符大小写

      ^~: URI前半部分匹配,不检查正则表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
location = / {  
    [ configuration A ]
}
location / {  
    [ configuration B ]
}
location /documents/ {
    [ configuration C ]
}
location ^~ /images/
{  
    [ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {  
    [ configuration E ]
}


       http://www.example.com/index.html  匹配到B。

       http://www.example.com/  匹配到A。

       http://www.example.com/documents/index.html   匹配到C。

       http://www.example.com/images/index.html  匹配到D。

       http://www.example.com/images/a.jpg  匹配到E。

     匹配优先级: 字符字面量最精确匹配-->正则表达式检索(由第一个匹配到所处理)-->按字符字面量。

(5).文件路径定义

  • root path 设置web资源路径,用于指定请求的根文档目录; 

1
2
3
4
5
6
    location / {
     root /www/htdocs;
    }
    location ^~ /images/ {
     root /web;
    }


匹配的文件路径为root: root/URI/ 

  • alias path  只能用于location中,用于路径别名; 

1
2
3
4
5
6
    location / {
     root /www/htdocs;
    }
    location ^~ /images/ {
     alias /web;
    }


匹配的文件路径为alias: alias/

  • index file ...;  定义默认页面,可参跟多个值;

  • error_page code ... [=[response]] uri;  当对于某个请求返回错误时,如果匹配上了error_page指令中设定的code,则重定向到新的URI中。即错误页面重定向; 

  • try_files path1 [path2 ...] uri;  自左至右尝试读取由path所指定路径,在第一次找到即停止并返回;如果所有path均不存在,则返回最后一个uri;  

(6).网络连接相关的设置

  • keepalive_timeout time;  保持连接的超时时长;默认为75秒;

  • keepalive_requests n;  在一次长连接上允许承载的最大请求数;

  • keepalive_disable [msie6 | safari | none ]  对指定的浏览器禁止使用长连接;

  • tcp_nodelay on|off;  对keepalive连接是否使用TCP_NODELAY选项;默认是启用的,一般是启动的。

  • client_header_timeout time;  读取http请求首部的超时时长;

  • client_body_timeout time;  读取http请求包体的超时时长;

  • send_timeout time;  发送响应的超时时长; 

(7).对客户端请求的限制

  • limit_except method ... { ... } ;指定对范围之外的其它方法的访问控制;

  • client_max_body_size SIZE;  http请求包体的最大值;常用于限定客户所能够请求的最大包体;根据请求首部中的Content-Length来检测,以避免无用的传输; 

  • limit_rate speed;  限制客户端每秒钟传输的字节数;默认为0,表示没有限制; 

  • limit_rate_after time;  nginx向客户发送响应报文时,如果时长超出了此处指定的时长,则后续的发送过程开始限速;

(8).文件操作的优化

  • sendfile on|off  是否启用sendfile功能; 

  • aio on|off   是否启用aio功能; 

  • open_file_cache max=N [inactive=time]|off  是否打开文件缓存功能; 

     max: 缓存条目的最大值;当满了以后将根据LRU算法进行置换;

     inactive: 某缓存条目在指定时长时没有被访问过时,将自动被删除;默认为60s;

               缓存的信息包括: 文件句柄、文件大小和上次修改时间。 已经打开的目录结构。 没有找到或没有访问权限的信息; 

  • open_file_cache_errors on|off  是否缓存文件找不到或没有权限访问等相关信息; 

  • open_file_cache_valid time;  多长时间检查一次缓存中的条目是否超出非活动时长,默认为60s;  

  • open_file_cache_min_use #;  在inactive指定的时长内被访问超此处指定的次数地,才不会被删除;

(9).对客户端请求的特殊处理

  • ignore_invalid_headers on|off  是否忽略不合法的http首部,默认为on。off意味着请求首部中出现不合规的首部将拒绝响应,只能用于server和http;  

  • log_not_found on|off  是否将文件找不到的信息也记录进错误日志中; 

  • esolver address;  指定nginx使用的dns服务器地址; 

  • resover_timeout time;  指定DNS解析超时时长,默认为30s;  

  • server_tokens on|off;  是否在错误页面中显示nginx的版本号;

(10).内存及磁盘资源分配

  • client_body_in_file_only on|clean|off  HTTP的包体是否存储在磁盘文件中;非off表示存储,即使包体大小为0也会创建一个磁盘文件;on表示请求结束后包体文件不会被删除,clean表示会被删除; 

  • client_body_in_single_buffer on|off;  HTTP的包体是否存储在内存buffer当中;默认为off; 

  • cleint_body_buffer_size size;  nginx接收HTTP包体的内存缓冲区大小; 

  • client_body_temp_path dir-path [level1 [level2 [level3]]];  HTTP包体存放的临时目录;

  • client_header_buffer_size size;  正常情况下接收用户请求的http报文header部分时分配的buffer大小;默认为1k; 

  • large_client_header_buffers number size;  存储超大Http请求首部的内存buffer大小及个数; 

  • connection_pool_size size;  nginx对于每个建立成功的tcp连接都会预先分配一个内存池,此处即用于设定此内存池的初始大小;默认为256; 

  • request_pool_size size;  nginx在处理每个http请求时会预先分配一个内存池,此处即用于设定此内存池的初始大小;默认为4k;  

(11).http核心模块的内置变量

  • $uri: 当前请求的uri,不带参数; 

  • $request_uri: 请求的uri,带完整参数; 

  • $host: http请求报文中host首部;如果请求中没有host首部,则以处理此请求的虚拟主机的主机名代替; 

  • $hostname: nginx服务运行在的主机的主机名; 

  • $remote_addr: 客户端IP 

  • $remote_port: 客户端Port 

  • $remote_user: 使用用户认证时客户端用户输入的用户名; 

  • $request_filename: 用户请求中的URI经过本地root或alias转换后映射的本地的文件路径; 

  • $request_method: 请求方法 

  • $server_addr: 服务器地址 

  • $server_name: 服务器名称 

  • $server_port: 服务器端口 

  • $server_protocol: 服务器向客户端发送响应时的协议,如http/1.1, http/1.0 

  • $scheme: 在请求中使用scheme, 如https://www.magedu.com/中的https; 

  • $http_HEADER: 匹配请求报文中指定的HEADER,$http_host匹配请求报文中的host首部 

  • $sent_http_HEADER: 匹配响应报文中指定的HEADER,例如$http_content_type匹配响应报文中的content-type首部; 

  • $document_root:当前请求映射到的root配置; 



你可能感兴趣的:(高性能web服务器nginx(一)之基本概念)