说明本篇文章大部分参考此人的博文:http://freeloda.blog.51cto.com/2033581/1285722,建议若想继续深入学习nginx时最好先看下此人所写的文章,总结的很详细,然后在找相关的书籍和查阅官方文档学习。
一、NGINX介绍
传统上基于进程或线程模型架构的web服务通过每进程或每线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下。生成一个新的进程/线程需要事先备好其运行时环境,这包括为其分配堆内存和栈内存,以及为其创建新的执行上下文等。这些操作都需要占用CPU,而且过多的进程/线程还会带来线程抖动或频繁的上下文切换,系统性能也会由此进一步下降。另一种高性能web服务器/web服务器反向代理:Nginx(Engine X),nginx的主要着眼点就是其高性能以及对物理计算资源的高密度利用,因此其采用了不同的架构模型。受启发于多种操作系统设计中基于“事件”的高级处理机制,nginx采用了模块化、事件驱动、异步、单线程及非阻塞的架构,并大量采用了多路复用及事件通知机制。在nginx中,连接请求由为数不多的几个仅包含一个线程的进程worker以高效的回环(run-loop)机制进行处理,而每个worker可以并行处理数千个的并发连接及请求。
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建立会话等。
处理静态文件,索引文件以及自动索引;
反向代理加速(无缓存),简单的负载均衡和容错;
FastCGI,简单的负载均衡和容错;
模块化的结构。过滤器包括gzipping, byte ranges, chunked responses, 以及 SSI-filter 。在SSI过滤器中,到同一个 proxy 或者 FastCGI 的多个子请求并发处理;
SSL 和 TLS SNI 支持;
使用外部 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 支持;
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 系列操作系统;
一个主进程和多个工作进程,工作进程运行于非特权用户;
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 内存。
最小化的数据拷贝操作;
基于IP 和名称的虚拟主机服务;
Memcached 的 GET 接口;
支持 keep-alive 和管道连接;
灵活简单的配置;
重新配置和在线升级而无须中断客户的工作进程;
可定制的访问日志,日志写入缓存,以及快捷的日志回卷;
4xx-5xx 错误代码重定向;
基于 PCRE 的 rewrite 重写模块;
基于客户端 IP 地址和 HTTP 基本认证的访问控制;
PUT, DELETE, 和 MKCOL 方法;
支持 FLV (Flash 视频);
带宽限制;
在高连接并发的情况下,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问题
Web服务器要为用户提供服务,必须以某种方式,工作在某个套接字上。一般Web服务器在处理用户请求是,一般有如下三种方式可选择:多进程方式、多线程方式、异步方式。
多进程方式:为每个请求启动一个进程来处理。由于在操作系统中,生成进程、销毁进程、进程间切换都很消耗CPU和内存,当负载高是,性能会明显降低。而httpd的prefork模型就是使用此种方式工作,故其性能较低。
优点: 稳定性!由于采用独立进程处理独立请求,而进程之间是独立的,单个进程问题不会影响其他进程,因此稳定性最好。
缺点: 资源占用!当请求过大时,需要大量的进程处理请求,进程生成、切换开销很大,而且进程间资源是独立的,造成内存重复利用。
多线程方式:一个进程生成多个线程其中用多个线程处理用户请求。由于线程开销明显小于进程,而且部分资源还可以共享,因此效率较高。而httpd的worker模型就是使用此种方式工作。
优点:开销较小!线程间部分数据是共享的,且线程生成与线程间的切换所需资源开销比进程间切换小得多。
缺点:稳定性!线程切换过快可能造成线程抖动,且线程过多会造成服务器不稳定。
异步方式(事件模型):使用非阻塞方式处理请求,是三种方式中开销最小的。但异步方式虽然效率高,但要求也高,因为多任务之间的调度如果出现问题,就可能出现整体故障,因此使用异步工作的,一般是一些功能相对简单,但却符合服务器任务调度、且代码中没有影响调度的错误代码存在的程序。而httpd的event模型就是使用此种方式工作。
优点:性能最好!一个进程或线程处理多个请求,不需要额外开销,性能最好,资源占用最低。
缺点:稳定性!某个进程或线程出错,可能导致大量请求无法处理,甚至导致整个服务宕机。
客户发起情况到服务器网卡;
服务器网卡接受到请求后转交给内核处理;
内核根据请求对应的套接字,将请求交给工作在用户空间的Web服务器进程
Web服务器进程根据用户请求,向内核进行系统调用,申请获取相应资源(如index.html)
内核发现web服务器进程请求的是一个存放在硬盘上的资源,因此通过驱动程序连接磁盘
内核调度磁盘,获取需要的资源
内核将资源存放在自己的缓冲区中,并通知Web服务器进程
Web服务器进程通过系统调用取得资源,并将其复制到进程自己的缓冲区中
Web服务器进程形成响应,通过系统调用再次发给内核以响应用户请求
内核将响应发送至网卡
网卡发送响应给用户
通过这样的一个复杂过程,一次请求就完成了。
简单来说就是:用户请求-->送达到用户空间-->系统调用-->内核空间-->内核到磁盘上读取网页资源->返回到用户空间->响应给用户。上述简单的说明了一下,客户端向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查看是否安装成功
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既不会继承其他设置也不会被继承。如下图,
在这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前半部分匹配,不检查正则表达式
12345678910111213141516 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资源路径,用于指定请求的根文档目录;
123456 location / {root /www/htdocs;}location ^~ /images/ {root /web;}
匹配的文件路径为root: root/URI/
alias path 只能用于location中,用于路径别名;
123456 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配置;