nginx功能测试二

https

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
* 创建CA服务器
cd /etc/pki/CA
(umask 077;openssl genrsa -out private/cakey.pem 2048)
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
touch index.txt serial
echo 01 > serial
* 到web服务器
mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
(umask 077;openssl genrsa -out nginx.key 2048)
openssl req -new -key http.key -out nginx.csr
scp nginx.csr 192.168.1.2:/tmp
* 到CA服务器
openssl ca -in /tmp/nginx.csr -out /etc/pki/CA/certs/nginx.crt -days 365
#newcerts中的也是证书,是pem格式的
scp certs/nginx.crt 192.168.1.3:/etc/nginx/ssl
* 到web服务器
cp conf.d/vhost1.conf conf.d/vhost1_ssl.conf
vim conf.d/vhost1_ssl.conf
server {
listen 443 ssl;
server_name www.ruopu.com;
root /data/nginx/vhost1;
access_log /var/log/nginx/vhost1_ssl_access.log main;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
#当前虚拟主机使用PEM格式的证书文件
ssl_certificate_key /etc/nginx/ssl/nginx.key;
#当前虚拟主机上与其证书匹配的私钥文件
ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;
#支持ssl协议版本,默认为后三个
ssl_session_cache shared:SSL:10m;
#在各worker之间使用一个共享的缓存。SSL是自定义的名字,1m内存空间可以缓存4000个会话,这里定义10M。
}
nginx -t
nginx -s reload
ss -tln
访问https://www.ruopu.com,将cacert.pem传到主机,这里定义的CA服务器与客户端的主机名是一样的,访问时通过了。

重写

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
vim /etc/nginx/conf.d/vhost1.conf
server{
rewrite /(.*)\.png$ /$1.jpg;
#rewrite放在server中,另外放在location或if中也可以。上面配置表示,所有以.png结尾的文件都转成.jpg格式的。括号是为了后面的$1引用,/是根,png前面的点需要转义,后面的.jpg的点不需要转义
}
nginx -t
nginx -s reload
访问www.ruopu.com/images/fish.png,这里实际访问的是一个叫fish.jpg的文件,名字一样但格式不同。
vim /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name www.ruopu.com;
root /data/nginx/vhost1;
error_page 404 /notfound.html;
# rewrite /(.*)$ https://www.ruopu.com/$1;
rewrite /(.*)\.png$ https://www.ruopu.com/$1.jpg;
#用户请求任何内容,都转到https的页面上。但两条不要一起写,如果一起写,在访问www.ruopu.com/images/night.png时会先匹配上面的规则,下面的规则就不会生效了。
location = /notfound.html {
root /data/nginx/error_pages;
}
location ^~ /images/ {
alias /data/pictures/;
}
location ~* ^/(admin|login) {
auth_basic "admin area or login url";
auth_basic_user_file /etc/nginx/.ngxpasswd;
}
location /ngxstatus {
stub_status;
}
}

vim /etc/nginx/conf.d/vhost1_ssl.conf
server {
listen 443 ssl;
server_name www.ruopu.com;
root /data/nginx/vhost1;
location ^~ /images/ {
alias /data/pictures/;
}
access_log /var/log/nginx/vhost1_ssl_access.log main;
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols sslv3 tlsv1 tlsv1.1 tlsv1.2;
ssl_session_cache shared:SSL:10m;
}
#vhost1_ssl.conf配置文件中也要有与vhost1.conf中相同的配置,这样才能正常访问,这里是定义的别名与vhost1.conf中是一样的,也就是要有相同的访问路径,不然不能正常访问,会有404的错误提示。
#上面的重写要写在监听80端口的server中,不能写在监听在443端口的server中,如果写在监听在443端口的server中,那么请求会无限重定向,最后是无法访问的。监听80端口与监听443端口的两个server中定义的内容应该是一样的。不然访问80端口时能访问的路径被重定向到443端口时就访问不到了。如果想让访问80端口的任何以png结尾的文件,都被重定向到443端口的.jpg文件,那么就要在监听443端口的配置文件中加入 rewrite /(.*)\.png$ /$1.jpg;,如果在监听80端口的server中定义是不起作用的。这是在要将所有访问的内容都重定向到443端口,并且还要让访问png文件的请求重定向到443端口的jpg文件,这两个条件都存在的情况下需要的配置。但如果只是将访问80端口的以png结尾的文件重定向到443端口的jpg文件的话,只要在监听80端口的server中写入 rewrite /(.*)\.png$ https://www.ruopu.com/$1.jpg; 就行了。
nginx -s reload
访问https://www.ruopu.com/images/night.png,rewrite规则可以写多条,rewrite匹配并重写url后会以新的url地址重新匹配配置文件或重新检查location的规则,如果可以匹配到,就会再重写一遍,直到匹配不到。默认的行为是last,就是重写的url会被重新再匹配一遍规则。还有break、redirect、permanent
vim /etc/nginx/conf.d/vhost1.conf
server{
rewrite /(.*)\.png$ /$1.jpg redirect;
}
#redirect是重定向,客户端要重新发起请求。如果是permanent就是永久重定向,也需要客户端重新发请求。last和break是不需要客户端重新发请求的,只是服务器内部做了转换
=======================================================================================
#[flag]:
last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环;
break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环;
redirect:重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头;302
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;301

反代

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
* 准备三台主机,一台反代,两台web服务,反代服务器的地址有两个,一个外网192.168.1.90,一个内网172.16.0.1。web服务器有两个内网地址,一个172.16.0.2,一个172.16.0.3。设置内网地址,就是将虚拟机网卡改为仅主机,然后设置仅主机的IP地址
yum install httpd mod_ssl
//到web服务器上安装httpd,mod_ssl,并提供主页,最后改为内网网卡并配置地址。改为内网地址172.16.0.2
vim /var/www/html/index.html
<h1>Real Server 1</h1>
vim /etc/sysconfig/network-scripts/ifcfg-eno16777736
IPADDR=172.16.0.2
NETMASK=255.255.0.0
systemctl start httpd
setenforce 0
systemctl stop firewalld
* 到反代服务器
vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repository
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
yum install nginx
vim /etc/nginx/conf.d/ruopu.conf
server {
listen 80;
server_name www.ruopu.com
location / {
proxy_pass http://172.16.0.2:80;
//这里要看web服务器是基于什么做的虚拟主机,是IP,port还是FQDN,是哪个就在http后输入哪个
}
}
nginx -t
systemctl start nginx
* 修改客户端hosts文件,让主机可以解析nginx的域名
* 访问测试
* 到web服务器上
tcpdump -i eno16777736 tcp port 80
//监听80端口,看一下请求是否为反代服务器发来的
* 到第二台web服务器上
yum install httpd
改为内网地址172.16.0.3
systemctl stop firewalld
setenforce 0
vim /var/www/html/index.html
<h1>Real Server 2</h1>
find /usr/share -iname "*.jpg" -exec cp {} /var/www/html \;
//这一次准备将图片文件都反代到这台服务器
systemctl start httpd
* 到反代服务器,加入
vim /etc/nginx/conf.d/ruopu.conf
location ~* \.(jpg|jpeg|png)$ {
proxy_pass http://172.16.0.3:80;
//将访问图片的请求代理到另一台服务器上
}
* 到客户端访问,如果是访问域名就返回第一台web服务器的内容,如果访问域名/*.jpg就返回第二台服务器的内容。在配置文件中,如果location中用了正则表达式,在proxy_pass指向的地址中的80端口后是不能加斜线/的,如果没用正则表达式,可以加斜线。像上边的第一个location设置,如果80后有斜线,表示将location中的斜线替换成80后的斜线,如果没有斜线,表示将location中的斜线补在80后
* 测试斜线的功能,到反代服务器上
vim /etc/nginx/conf.d/ruopu.com
server {
listen 80;
server_name www.ruopu.com;
location / {
root /data/nginx/html;
}
location /admin/ {
proxy_pass http://172.16.0.2:80;
//这个反代的意思是在172.16.0.2的根目录下找admin目录,下面的反代是在访问以jpg等为后缀名的文件时到172.16.0.3:80的根目录下找
}
location ~* \.(jpg|jpeg|png)$ {
proxy_pass http://172.16.0.3:80;
}
}
//修改配置文件,将admin代理过去
mkdir -pv /data/nginx/html
nginx -s reload
* 到客户端访问www.ruopu.com/admin,提示Not Found,因为web服务器上没有admin目录。但是,如果location /admin/中的80后有斜线,那么访问的就是172.16.0.2的根目录,也就是/var/www/html/index.html文件。也就是,没有斜线,就将/admin补在80后,因为172.16.0.2中没有admin目录,所以提示Not Found。如果有斜线,就表示访问http://172.16.0.2/admin就是在访问172.16.0.2的根目录,/admin/就等于/。
* 到web服务器上
mkdir /var/www/html/admin
vim /var/www/html/admin/index.html
admin
* 到客户端测试,这时显示admin
* 到反代服务器上加一个斜线
vim /etc/nginx/conf.d/ruopu.com
server {
listen 80;
server_name www.ruopu.com;
location / {
root /data/nginx/html;
}
location /admin/ {
proxy_pass http://10.5.5.204:80/;
}
location ~* \.(jpg|jpeg|png)$ {
proxy_pass http://10.5.5.205:80;
}
}
nginx -t
nginx -s reload
* 到客户端访问www.ruopu.com/admin,这时显示的是Real Server 1,也就是web服务器上html中定义的内容,配置的意思就是,当访问admin时,就替换成web服务器根下的内容。当location中定义的是根时,这个斜线就没有意义了,因为访问的都是根

设置上传大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
vim /etc/nginx/nginx.conf
http {
client_max_body_size 8M;
# 设置上传最大8M
}

# 下面设置php上传大小
vim /etc/php5/fpm/php.ini
;This sets the maximum amount of memory in bytes that a script is allowed to allocate
memory_limit = 32M

;The maximum size of an uploaded file.
upload_max_filesize = 8M

;Sets max size of post data allowed. This setting also affects file upload. To upload large files, this value must be larger than upload_max_filesize
post_max_size = 16M

nginx功能测试一

CPU绑定

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
ps axo user,comm,pid,psr,pcpu | grep nginx
#查看进程运行在哪个CPU上,显示的最后一个数字就是指第几颗CPU上。这个命令是查看进程的名称、PID以及CPU的占用率。psr表示绑定内核线程的处理器(如果有)的逻辑处理器号。 对一个进程来说,如果它的线程全都绑定到同一处理器上,那么显示该字段。pcpu表示CPU的占用率。comm表示进程名称。pid表示进程的ID号
watch -n.5 'ps axo comm,pid,psr | grep nginx'
yum install httpd-tools
ab -n 100000 -c 100 http://IP/index.html
#这时可以看到上面监测的绑定CPU数字在变化,因为CPU与进程没有绑定
vim /etc/nginx/nginx.conf
#这时在配置文件中加入绑定设置,定义在全局段
worker_cpu_affinity auto;
#自动绑定CPU
worker_rlimit_nofile 65536;
#如果不加入worker打开文件数量的上限,检查语法时会有报错,提示最多打开1024。定义在全局段
worker_priority -5;
#调整优先级
watch -n.5 'ps axo comm,pid,psr,ni | grep nginx'
#可以看到优先级改为了-5
nginx -t
nginx -s reload
vim /etc/hosts
192.168.1.15 www.ruopu.com
systemctl stop firewalld
setenforce 0
ab -n 100000 -c 100 http://IP/index.html
#这时监测页面的CPU数字是不会变化的,因为已经绑定了,显示的内容中第一个是主控进程,只看后四个即可
vim /etc/nginx/nginx.conf
worker_cpu_affinity 1000 0100 0010 0001;
#绑定第0到3颗CPU,因为CPU是四核的。这时监测页面显示绑定在0-3的CPU上
vim /etc/nginx/nginx.conf
worker_processes 2;
worker_cpu_affinity 1000 0100;
nginx -s reload
#再查看监测页面,这里只绑定在2颗CPU上

设置访问权限

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
vim /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name www.ruopu.com;
root /data/nginx/vhost1;
location / {
deny 192.168.1.22;
allow all;
#location定义对根及以下的路径的访问拒绝22地址访问,allow也一样,可以用一个地址或一个网段/24或all
}
}
nginx -s reload
访问IP
vim /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name www.ruopu.com;
root /data/nginx/vhost1;
location ~* \.(jpg|png) {
deny 192.168.1.22;
allow all;
}
}
//对目录中的jpg或png文件,拒绝22地址访问。location中定义的地址是在root定义的地址的下面的路径
nginx -s reload
find /usr/share -iname "*.jpg" -exec cp {} /data/nginx/vhost1 \;
访问测试,www.ruopu.com/morning.jpg
如果location中定义了root,那么以location中的root为准
=====================================================================================
#在一个server中location配置段可存在多个,用于实现从uri到文件系统的路径映射;ngnix会根据用户请求的URI来检查定义的所有location,并找出一个最佳匹配,而后应用其配置;

location [ = | ~ | ~* | ^~ ] uri { ... }
Sets configuration depending on a request URI.
=:对URI做精确匹配;例如, http://www.magedu.com/, http://www.magedu.com/index.html,如果等于根,那么就只有根被匹配,如果没有等号,那么从根以下的所有路径都匹配。
location = / {
...
}
~:对URI做正则表达式模式匹配,区分字符大小写;
~*:对URI做正则表达式模式匹配,不区分字符大小写;
^~:对URI的左半部分做匹配检查,不区分字符大小写;也就是以什么开头
不带符号:匹配起始于此uri的所有的url;
匹配优先级:=, ^~, ~/~*,不带符号;

定义别名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mkdir /data/pictures
cp fish.jpg /data/pictures
vim conf.d/vhost1.conf
location ^~ /images/ {
#^~是指以其后设定的内容开头的,但这里没有什么用
root /data/pictures;
}
#这时访问www.ruopu.com/images/fish.jpg提示404,上面定义的应该是在pictures中找images目录,然后再找文件。/data/pictures就相当于根,在根下再打开images目录
mkdir /data/pictures/images
mv /data/pictures/*.jpg /data/pictures/images
访问www.ruopu.com/images/flower.jpg
vim conf.d/vhost1.conf
location ^~ /images/ {
alias /data/pictures/;
}
#将root改为alias。别名中的pictures右边的斜线是相对于images右侧的斜线来说的。所以,上面别名/data/pictures/最右边的斜线一定不能少,不然就不能访问到。
nginx -s reload
访问www.ruopu.com/images/fish.jpg才有,flower.jpg是访问不到的。因为在pictures中只有fish.jpg文件,没有flower.jpg文件。root是对于左侧的斜线,alias是对于最右侧的斜线来说的。

自定义错误页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
vim /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name www.ruopu.com;
root /data/nginx/vhost1;
location ~* \.(jpg|png) {
error_page 404 =200 /notfound.html;
#notfound.html是URL的地址,它的位置是root定义的,因为加了等于200,所以这改变了状态码,在浏览器中按F12时可以看到是200了。测试使用等于200的设置会提示错误的值,原因是在200与其前面的等号中间加了空格,去掉空格就正常了。notfound.html应该是自定义的名字,但定义的名字与location指定的名字,与root定义的目录中的*.html文件的名字,这三个名字要一致,不然访问不了。error_page定义一次即可,这里只是展现了两种方法。
error_page 404 /notfound.html;
location = /notfound.html {
root /data/nginx/error_pages;
}
location ^~ /images/ {
alias /data/pictures/;
}
}
mkdir /data/nginx/error_pages
vim /data/nginx/error_pages/notfound.html
404
nginx -s reload
访问www.ruopu.com/test.html,这是一个不存在的页面

认证

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
yum install httpd-tools
htpasswd -c -m /etc/nginx/.ngxpasswd tom
htpasswd -m /etc/nginx/.ngxpasswd jerry
vim /etc/nginx/conf.d/vhost1.conf
server {
listen 80;
server_name www.ruopu.com;
root /data/nginx/vhost1;
error_page 404 /notfound.html;
location = /notfound.html {
root /data/nginx/error_pages;
}
location ^~ /images/ {
alias /data/pictures/;
}
location ~* ^/(admin|login) {
#~*做正则表达式模式匹配,如果以admin或login开头,就进行认证。当然,这也要求在vhost1中有这个目录才行。
auth_basic "admin area or login url";
#使用ngx_http_auth_basic_module模块实现基于用户的访问控制,使用basic机制进行用户认证;"admin area or login url"是一段自定义提示信息。
auth_basic_user_file /etc/nginx/.ngxpasswd;
}
}
mkdir /data/nginx/vhost1/admin
vim /data/nginx/vhost1/admin/index.html
admin aera
nginx -s reload
访问www.ruopu.com/admin,如果访问的是www.ruopu.com/login就会失败,因为在vhost1中没有login目录。

状态页

1
2
3
4
5
6
7
8
9
10
11
vim /etc/nginx/conf.d/vhost1.conf
location /ngxstatus {
#这里的ngxstatus也是自定义的名称,定义什么名字,访问时就用什么名字
stub_status;
#stub_status是一个系统变量
}
#ngxstatus是自定义名称,还可以在其中加认证或allow、deny。location后面定义的是URL名,也是路径名
nginx -s reload
访问www.ruopu.com/ngxstatus。
curl --silent http://www.ruopu.com/ngxstatus | awk '^Active/{print $3}'
#测试此条命令后的awk用法有问题,在^Active上。

压缩功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vim /etc/nginx/nginx.conf    
http {
gzip on;
gzip_min_length 1k;
#不压缩临界值,大于1K的才压缩,一般不用改
gzip_buffers 4 16k;
#支持实现压缩功能时为其配置的缓冲区数量及每个缓存区的大小;
gzip_comp_level 6;
#压缩级别,1-10,数字越大压缩的越好,时间也越长
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#进行压缩的文件类型,缺啥补啥就行了,JavaScript有两种写法,最好都写上吧,总有人抱怨js文件没有压缩,其实多写一种格式就行了
gzip_disable "MSIE [1-6]\.";
#IE6对Gzip不怎么友好,不给它Gzip了
}
nginx -s reload
cp nginx.conf /data/nginx/vhost1/nginx.html
chmod +r /data/nginx/vhost1/nginx.html
curl -I -H "Accept-Encoding: gzip, deflate" "http://www.ruopu.com/images/morning.jpg"
#如果对访问的内容进行了压缩,在结果中会有Content-Encoding: gzip的字样。

nginx安装

rpm包安装

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
vim /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repository
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
###自建repo文件或用以下命令;如果是CentOS6上安装nginx,就将上面源地址中的7改为6就可以了。也可以下载安装http://http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm。另外,在CentOS6上如果要安装nginx,还要将openssl升级到1.0.2版本以上。到https://www.openssl.org/source/openssl-1.0.2h.tar.gz下载,之后编译安装
###如果提示需要公钥验证,需要执行此命令rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
rpm -ivh https://mirrors.ustc.edu.cn/epel/epel-release-latest-7.noarch.rpm
------------------------------------------------------------------------------------
rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
//此命令安装后也会自建一个叫nginx.repo的源
yum repolist
yum info nginx
yum install nginx
------------------------------------------------------------------------------------
yum install epel-release -y
###也可以用yum安装epel-release包得到epel仓库。也可以安装epel库来安装nginx,这样安装nginx后会自动配置配色方案

注:nginx配置文件默认没有配色,使用下面方法解决
mkdir -pv ~/.vim/syntax
cd ~/.vim/syntax
wget http://www.vim.org/scripts/download_script.php?src_id=14376 -O nginx.vim
vim ~/.vim/filetype.vim
au BufRead,BufNewFile /etc/nginx/* set ft=nginx
###其中路径为你的nginx.conf文件路径

源码安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
yum install zlib-devel pcre-devel
yum groupinstall "开发工具"
tar nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --with-pcre --with-zlib
/usr/local/nginx/sbin/nginx
###启动
/usr/local/nginx/sbin/nginx -s reload
###重启
/usr/local/nginx/sbin/nginx -s stop
###关闭
vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=Nginx Service
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
###实现systemd管理nginx
###这里一定要注意PIDFile的路径,在/usr/local/nginx/conf/nginx.conf配置文件中,默认pid文件放在/usr/local/nginx/logs中,如果写错路径,nginx是无法启动的,报错为:PID file /run/nginx.pid not readable (yet?) after start.

nginx程序架构

&emsp;&emsp;nginx是一个模块化的、事件驱动的、异步,单线程的、非阻断的服务。nginx启动后会有master与worker进程,master进程只有一个,负责加载和分析配置文件、管理worker进程、平滑升级。worker进程有一个或多个,负责处理并响应用户请求。

worker模型

&emsp;&emsp;nginx并不为每个连接产生一个进程或线程。工作进程从一个共享的“listen”socket接受新的请求,每个worker内运行循环高效执行。每个worker处理数以千计的连接。在启动时,一组初始的监听套接字被创建。当处理HTTP请求和响应时,worker不断接受,读取和写入到socket。

&emsp;&emsp;nginx的worker代码的运行循环是最复杂的部分。它包括全部的内部调用,并在很大程度上依赖于异步处理任务的想法。异步操作通过模块化,事件通知,广泛使用回调函数和微调定时器实现。总体而言,关键的原则是尽可能的非阻塞。 唯一可以让nginx阻塞的情形是,没有足够的磁盘存储供worker操作。

&emsp;&emsp;由于nginx并不会为每个连接产生新的进程或线程,内存使用在绝大多数情况下是非常保守的,效率非常高。 nginx节省CPU周期,因为没有持续的进程或线程的创建销毁模式。nginx要做的是检查网络和存储的状态,初始化新的连接,将它们添加到运行循环,处理直到完成,此时连接被释放,从运行循环中移除。谨慎使用系统调用和准确实现支持接口,如poll和slab内存分配器相结合,nginx通常达到中度至低CPU占用率,即使在极端恶劣的工作负载环境下。

&emsp;&emsp;由于nginx可以产生数个worker进程处理连接,在多核上扩展性很好。一般情况下,每核一个单独的worker可以充分利用多核架构,并防止线程的波动和锁定。隔离的单线程worker进程没有资源匮乏和资源控制机制。该模型还允许在物理存储设备上的可扩展性,有利于更好的磁盘利用率,避免了磁盘I / O阻塞。所以,一些资源在几个worker之间共享可以更有效的被利用

&emsp;&emsp;在磁盘和CPU的负载模式中,nginx的worker数目应该进行相应的调整。这里有一些基本规则,系统管理员应该根据负载量尝试几种配置。以下的是一般建议内容:如果负载模式是CPU密集的情况下,处理大量的TCP / IP,做SSL,压缩,nginx的worker的数量和CPU核的数量应该相匹配;如果负载主要是磁盘I / O范畴的情况下,从储存提供不同的内容,或繁忙的代理。worker的数量可以是一个半到两个核。与之相反的是,一些工程师选择worker的数量是基于独立存储单元的数量,但这种方法的效率取决于磁盘存储的类型和配置。

Nginx进程的作用

&emsp;&emsp;nginx在内存中运行多个进程。有一个主进程和多个worker进程。此外,还有一些特殊用途的进程,特别是高速缓存加载器和高速缓存管理器。在nginx的1.x版本中所有的进程都是单线程。所有进程主要使用共享内存的进程间通信机制。主进程以root用户运行。缓存加载器,缓存管理器和worker作为一个非特权用户运行。

&emsp;主进程负责执行以下任务:

  • 读取并验证配置
  • 创建,绑定和关闭套接字
  • 启动,终止和维护配置的工作进程数
  • 不中断服务的情况下重新配置
  • 控制不停止服务的二进制升级(如有必要,启动新的二进制程序和回滚)
  • 重新打开日志文件
  • 编译嵌入式的Perl脚本

&emsp;&emsp;worker进程接受,处置和处理来自客户端的连接,提供反向代理和过滤功能,做nginx能力范围之内的所有事情。关于监测nginx的实例的动态,系统管理员应该留意worker,因为他们是反映了Web服务器的实际日常操作的进程。

&emsp;&emsp;缓存加载器进程负责检查磁盘上的缓存项和使用高速缓存元数据填充Nginx在内存中的数据库。从本质上讲,缓存加载器可以帮助nginx和文件协同工作,一个已经专门分配存储在磁盘上的目录结构。它遍历目录,检查缓存内容,元数据,更新共享内存中的相关条目,当一切都干净并准备投入使用时,它会退出。

&emsp;&emsp;高速缓存管理器主要是负责缓存过期和失效。在正常nginx的操作过程中它驻留在内存中,在失败的情况下,它被主进程重新启动。

Nginx的缓存的简要概述

&emsp;&emsp;Nginx的缓存是以分层数据存储的形式在一个文件系统中实现的。缓存键是可配置的,不同请求的目的参数可以用来控制哪些参数可以进入高速缓存中。高速缓存键和缓存元数据存储在共享内存段,从而缓存加载器、缓存管理器和worker都可以访问。没有任何文件缓存在内存中,只有操作系统的虚拟文件系统机制方面的优化。每个高速缓存的响应被放置在文件系统上的不同文件。通过nginx的配置指令控制的层次结构(层次和命名的详细信息)。当一个响应被写入到高速缓存的目录结构,路径和文件的文件名是来自代理URL的MD5哈希。

&emsp;&emsp;放置在高速缓存中的内容的过程如下所示:当nginx从上游服务器读取响应,内容首先被写入到高速缓存的目录结构以外的一个临时文件。当nginx完成处理请求时,临时文件重命名,并被移动到缓存目录中。如果临时文件目录代理是在另一个文件系统上,该文件将被复制,因此建议临时文件和缓存目录保持在同一个文件系统。需要显式地清除,从缓存目录结构删除文件是比较安全的。

HTTP请求处理过程

  1. 客户端发送HTTP请求。
  2. nginx的核心段根据所配置的location选择合适匹配请求的处理程序。
  3. 如果配置要求这样做,负载平衡器为代理挑选一个上游服务器(或“后端”)。
  4. 阶段处理程序执行它的工作,并传递每个输出缓冲器到所述第一滤波器。
  5. 第一滤波器的输出传递到所述第二过滤器。
  6. 第二滤波器的输出到第三个(等等)。
  7. 最终的响应被发送到客户端。

参考:https://my.oschina.net/daleshen128/blog/95130