Nginx的架构
1.master/networker
- 一个master进程:
负责加载和分析配置文件、管理worker进程、平滑升级; - 一个或多个worker进程:
处理并相应用户请求; - 缓存相关的进程:
- cache loader:载入缓存对象
- cache manager:管理缓存对象
2.特性
- 异步、事件驱动和非阻塞
- 并发请求处理:通过kevent/epoll/select,/dev/poll
- 文件I/O:高级IO sendfile,异步,mmap
3.Nginx高度模块化,其早期不支持DSO机制;近期版本持动态装载和卸载
模块分类:
- 核心模块:core module
- 标准模块:
- HTTP modules:
standard HTTP modules
optional HHTP modules - Mail modules
- HTTP modules:
- 其他模块
4.Nginx的功用:
静态的web资源服务器;(图片服务器,或者js/css/html/txt等静态资源服务器)
- 结合FastCGI/uwSGI/SCGI等协议反代动态资源请求;
- http/https协议的反向代理;
- imap4/pop3协议的方向代理;
- tcp/udp协议的请求转发;
nginx的安装配置
1.官方的预制包:
#使用epel仓库
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
2.编译安装:
~]# yum groupinstall "Development Tools" "Server Platform Development"
~]# yum install pcre-devel openssl-devel zlib-devel #正则表达式引擎 压缩算法
~]# useradd -r nginx #创建系统用户
~]# ./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.pid --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_dav_module --with-http_stub_statu_module --with-threads --with-file-aio
~]# make && make install
#安装目录 配置文件路径 错误日志 访问日志 进程文件 锁文件 进程的用户和组 装载的模块
3.配置文件结构:
1. 配置文件的组成部分:
主配置文件:nginx.conf
include conf.d/*.conf包含子目录下的配置文件;
fastcgi:uwsgi,scgi等协议相关的配置文件;
mime.type:支持的mime类型;
2.主配置文件的配置指令
语法:directive value [value2 …];
- 指令必须以分号结尾;
- 支持使用配置变量;
- 内建变量:由Nginx模块引入,可直接引用;
- 自定义变量:由用户使用set命令定义:
set variable_name value;
引用变量:$variable_name
3.主配置文件结构:
main #主配置段,也即全局配置段;
event{...} #事务日志配置段
http{...} #http协议相关配置段;
mail{...}
stream{...}
4.http协议相关的配置结构
http{ #各个server的公共配置
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
' "$http_user_agent" "$http_x_forwarded_for" ';
用于定义事务日志文件格式,mian是格式名称;
$remote_addr :客户端地址;
$remote_user :远程用户;
$time_local :本地时间;
$request :请求报文的头部;
$status :响应码;
$body_bytes_sent :响应报文字节数;
$http_referer :跳转地址;
$http_user_agent :客户端代理;
$http_x_forwarded_for :Nginx作为代理时,记录真正的客户端地址;
server{ #每一个server用于定义一个虚拟主机;
if CONDITION{...}
}
}
4. 配置指令:
1. main配置段常见的配置指令:
- 正常运行必备的配置;
- 优化性能先关的配置;
- 用于调试及定位问题相关的配置;
- 事件驱动先关的配置;
1. 正常运行必备的配置:
1. user [group] 启动worker进程的属主属组
2. pid */PATH/TO/PID_FILE* Nginx主进程进程号码的的文件路径
3. include *file|mask* 包含其他配置文件片段
4. load_module *file*
2. 性能优化先关的配置:
worker_processes auto|number; #worker进程的个数;通常应该是等于或小于CPU核心数
worker_cpu_affinity auto [cpumask]; #将worker进程绑定进程在CPU上,避免被CPU调度;
worker_priority number; #指定worker进程的nice值,设定worker进程的优先级[-20-19]
worker_rlimit_nofile number; #worker进程能够打开文件数量上限:
CPUMASK位图表示有几个CPU就用几位表示;
ps axo comm,pid,psr|grep nginx #查看Nginx进程占用的CPU
当前主机只运行Nginx时绑定CPU很有效果;
3. 调试、定位问题:
deamon on|off ; #是否以守护进程方式运行Nginx;
master_process on|off #是否以master/worker模型运行Nginx;默认为on;
error_log file [level]
4. 事件驱动相关配置:
worker_connections number; #每个worker进程所能打开最大并发连接数量;
use method; #指明并发连接请求的处理方法; use epoll;
accept_mutex on|off #处理新的连接请求的方法;on意味着由各worker轮流处理新请求,off意味着每个新请求的到达都会通知所有的worker请求,哪个空闲则哪个处理;
2. http协议的相关配置:
1.与套接字相关配置
- listen
- listen address[:port] [default_server] [ssl] [backlog=number] [rcvbuf=size] [sndbuf=size];
- listen port;
default_server; #设定为默认虚拟主机;
ssl; #限制仅能够通过ssl连接访问;
backlog=*number*; #后援队列长度;
rcvbuf=size; #接受缓冲区大小;
sndbuf=size; #发送缓冲区大小;
backlog #后援队列,定义超过并发连接时排队个数
rcvbuf #接受缓冲大小
sndbuf #发送缓冲大小
- server_name SERVER_NAME; nginx是通过主机名来区分不同虚拟主机;
支持*通配任意长度的任意字符; *.abc.com www.abc.*
支持~起始的正则表达式匹配; ~www/d\.abc\.com$
配置机制:
字符串精确匹配;
左侧*匹配;
右侧*匹配;
正则匹配;
proxy_pass URL;
反向代理;
tcp_nodelay on|off;
在keepalive模式下是否启用tcp_nodelay; 客户端请求很小文件时,服务端会等待几个文件共用一个tcp头部;
tcp_nopush on|off;
启用sendfile时,一个报文发送一个文件,sendfile会直接在内核内存中发送报文,而内核无法生成应用层头部,所以从用户内存空间发送应用层首部到内核空间,完成报文发送;
sendfile on|off;
不需要将内核空间文件拷贝到用户空间;
2.与路径相关配置
root /PATH;
网页文件根目录; 可用的位置:http,server,location;
location [ = | ~ | ~* | ^~ | uri ] {…}
在一个server中location配置段可存在多个,用于实现从URI到文件系统的路径映射,nginx会根据用户请求的URI来检查定义的所有location,并找到最佳匹配,而后应用其配置;
‘=’:对URI做精确匹配; location = / 那么能匹配到的只能是/;
‘^~’:对URI做左半部分匹配检查,不区分大小写;
‘~’:对URI做正则表达式匹配,区分代大小写;
‘~*’:对URI做正则表达式模式匹配,不区分大小写;
不带符号:匹配起始于URI的所有;
root /PATH/; #如果在server中定义了root,则将其覆盖。uri是以当前定义的root为根;
alias /PATH/; #uri为path的别名;
总结:
alias中定义的path是location上URI的路径映射,也就是本机的真实路径;
root中定义的是根,location上的URI要以当前root为根查找;
index FILE_NAME;
默认资源;
error_page code …[=response]uri;
#指定错误码的错误页;
code=number; #状态码
response=number; #响应码,可以自定义响应码;
- types_hash_max_size size;
内存中保存的hash表的最大值;比对hash表比直接找文件快得多;
3.定义客户端请求
keepalive_timeout time;
保持连接的超时时间,默认75s;
keepalive_requests number;
一次长连接所允许的最大请求资源数量,默认100;
keepalive_disable none| browser ;
对那种浏览器禁用长连接;
send_timeout time;
向客户端发送响应报文的超时时长;
client_body_buffer_size size
接受客户端请求报文的body部分的缓冲区大小,默认为16K超出被缓存到Client_body_temp_path定义的位置;
- client_body_temp_path PATH [level1[level2[level3]]];
设定用于存储客户端请求报文的body部分临时存储路径子目录结构和数量;
将URL进行单行加密,获得其hash值,用hash值每一位的值来指定存放的目录
16进制的数字:
client_body_temp_path /var/nginx/file 1 2 2
1:用一位0-f:定义一级子目录
2:用二位00-ff:定义二级子目录
2:用二位00-ff:定义三级子目录
4.限制客户端配置
limit_rate rate;
限制传输速度,单位bytes/second;
limit_except method…;
限制客户端使用对指定方法之外的其他方法的;
example:
#只允许192.168.10.0/24网段,使用GET之外的方法;
#其余主机只能使用GET方法;
limit except GET{
allow 192.168.10.0/24;
deny all;
}
5.文件操作优化配置
aio on|off|threads[=pid];
是否启用aio功能
directio size|off;
在linux主机启用O_DIRECT标记,当文件大于给定大小时使用;
- open_file_cache off|on;
- open_file_cache max=N [inactive=time];
打开的文件缓存
syntax:
max=N;#可缓存项的上限,达到上限后会使用LRU算法实现缓存管理
LRU算法:最近一次最少使用
inactive=time; #缓存项的非活动时长,在此指定的时长之内未被命中的或命中次数少于open_file_cache_min_uses指定所指定的次数的缓存想即为非活动项;
nginx可以缓存:
1.文件描述符(元数据),文件大小和最近修改时间;
2.打开的目录结构
3.没有找到的数据没有权限访问的数据的相关信息;
open_file_cache_valid time;
缓存项有效性的检查频率,default 60s
openfile cache_min_uses number;
在open_file_cache指明的inactive参数指定的时长内,至少命中多少次方可被归类为活动项;
open_file_cache_errors on|off;
是否缓存查找时发生错误的文件一类信息;有可能文件第一次不存在,后面又有了,那么这个缓存就会导致错误;
6.ngx_http_access_module
#实现基于ip的访问控制功能
syntax:
allow|deny address|CIDR|unix|all;
example:
location /index.html {
deny 192.168.10.11;
allow all;
}
context:http,server,location,limit_except;
7.ngx_http_auth_basic_module
#实现基于用户的访问控制,使用basic机制进行用户认证
syntax:
auth_basic string|off; #认证提示
auth_basic_user_file file; #认证文件
example:
location /admin {
alias /nginx/date;
auth_basic "input username and password";
auth_basic_user_file /nginx/date/ngxpasswd;
}
注意:认证文件由htpasswd创建;
8.ngx_http_stub_status_module
#用于输出Nginx的基本信息状态;
Active connections: 1
server accepts handled requests
30 30 92
Reading: 0 Writing: 1 Waiting: 0
Active connections:活动状态的连接数;
accepts:已经接受的客户端请求的总数;
handled:已经处理完成的客户端请求的总数;
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接的连接数;
Writing:处于想客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;
example:
location /ngxstatus {
stub_status;
}
9.ngx_http_log_module
#用于指定请求日志格式
syntax:
log_format NAME STRING...;
#string可以使用Nginx核心模块及其它模块内嵌的变量;
access_log PATH [FROMAT [buffer=size] [gzip=level] [flush=time] [if=condition] ];
access_log off;
#访问日志文件路径配置,格式相关的缓冲配置;
buffer:定义缓冲区大小
open_log_file_cache max=N [inactive=TIME] [min_uses=N] [valid=TIME];
#缓存各日志文件相关的元数据信息;
max:缓存最大文件描述符数量;
inactive:定义非活动时间;
min_uses:定义在inactive时长内,最小访问次数;
valid:检查时间;
Context:
http, server, location, if in location, limit_except
10.ngx_http_gzip_module
#该模块使用gzip压缩响应报文。这通常有助于将传输数据的大小减少一半甚至更多;
gzip on|off; #开启或关闭对响应报文的压缩;
gzip_comp_level lever; #对响应报文的压缩比;
gzip_disable regex...; #禁止压缩响应被正则表达式匹配的用户代理;
gzip_min_length length; #响应报文大于等于这个值时才压缩:
gzip_buffer number size; #支持实现压缩功能时为其配置的缓冲区数量以及每个缓存区的大小;
gzip_proxied off | expired | no-cache | no_store | no_last_modified | no_etag | auth | any...;
#nginx作为反代服务器收到从被代理服务器发送的响应报文后,在何种情况下启动压缩功能;
off:对代理的请求不启用压缩;
no-cache,on-store,private:表示从被代理服务器收到的响应报文首部的cache-control的值为三者中一个,启用压缩;
gzip_types mime-type...;
#压缩过滤,仅对此处设定的MIME类型的内容启用压缩功能;
example:
gzip on;
gzip_comp_level 5;
gzip_types text/plain application/xml;
gzip_min_length 1000;
context:http, server, location
11.ngx_http_ssl_module
ssl on | off;
#启用https协议虚拟主机
#该指令在版本1.15.0中已作废。应该改用listen指令的ssl参数
ssl_certificate file;
#当前虚拟主机使用PEM格式的证书文件;
ssl_certificate_key file;
#与当前主机证书匹配的私钥文件;
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,默认为后三个;
ssl_session_cache off | none | [builitin[:size]] [shared:name:size];
#builitin[:size]使用OpenSSL内建的缓存,此缓存为每worker进程私有;
#[shared:name:size]在各个worker之间共享一个缓存;
#注意:各个worker进程不共用一个缓存,那么在新的worker进程处理时会重新检测证书;
ssl_session_timeout time;
#客户端一侧的连接可以复用ssl_session_cache中缓存的ssl参数的有效时长;
example:
ssl_certificate "/date/ca/nginx.crt";
ssl_certificate_key "/date/ca/nginx.key";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:NginxCache:100;
ssl_session_timeout 30;
12.ngx_http_rewrite_module
#将用户请求的URI基于regex所描述的模式进行检查,而后完成替换;
rewrite regex replacement [flag];
#将用户请求的URI基于Regex所描述的模式进行检查,匹配则改写为replacement指定的新的URI;
[flage]:
last:重写完成后停止在当前URI在当前location中的后续操作的其他重写操作,对重写后的URI进行新的检查,进行新的循环;
break:重写完成后停止所有当前重写,结束循环;
redirect:重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端;
permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端;
注意:
如果在同一级配置模块中存在多个rewrite规则,那么会自上而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,因此隐含有循环机制;[flag]标志位表示用于控制此循环机制;
如果replacement是以http://或者https://开头,则替换结果会直接以重定向返回给客户端;
302:零时重定向;
301:(状态码)永久重定向;
return
return code[text];
return code URL;
return URL;
#停止处理并将指定的响应码返回给客户端
rewrite_log on|off;
#是否开启重写日志;
set $variable value;
#用户自定义变量;
if(condition){...}
#引入一个上下文;条件满足时,执行配置快中的配置指令;
condition:
比较操作符:
==,!=;
~:匹配时,区分字符大小写;
~*:匹配时,不区分大小写;
!~:不匹配时,区分大小写;
!~*:不匹配时,不区分大小写;
文件及目录存在性判断:
-e,!-e:文件或目录存在为真否则为假:
-f,!-f:文件是否存在;
-d,!-d;目录是否存在;
-x,!-x;文件或目录是否存在且可执行;
13.ngx_http_referer_module
#该模块用于阻止对Referer报头字段中具有无效值的请求的站点访问;
valid_referers none|blocked|server_names|string...;
#定义referer首部的合法可用值;
none:请求报文首部没有referer首部;
blocked:请求报文的referer首部没有值;
server_name:参数,其可以有值作为主机名或主机名模式;
arbitrary_string:直接字符串,可以使用*作为通配符;
regular expression:正则表达式模式匹配的字符串,要使用~开头;
example:
valid_referers none blocked server_names
*.example.com example.* www.example.org/galleries/ ~\.google\.;
if ($invalid_referer) {
return 403;
}
14.ngx_http_proxy_module
#该模块允许nginx将请求传递给另一台服务器
1.proxy_pass URL; #proxy_pass后面是一个uri时,其会将location匹配到的uri替换,Context:location, if in location, limit_except
2.proxy_set_header X-Forwarded-For $proxy_add_X_forwarded_for;
#设定发往后端主机的请求报文的请求首部的值;Context:http,server,location
反代缓存:
1.proxy_cache_path PATH [levels=levels] keys_zone=name:size [inactive=time] [max_size=size]
#定义可用的proxy缓存,keys_zone:定义该缓存项名称,在内存空间大小 ;Context:http
2.proxy_cache NAME #调用缓存
3.proxy_cache_key string #以什么作为hash的键,来命中缓存 ;
Default:proxy_cache_key $scheme$proxy_host$request_uri;
4.proxy_cache_valid [code]:time #响应码缓存时长
200 302 10m 404 1m
5.proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off
#确定在什么情况下可以与代理服务器进行通信时使用陈旧的缓存响应
example:
http{
proxy_cache_path /nginx/cache levels=1:1:1 keys_zone=pass:10m max_size=1G;
server{
listen 80;
server_name www.aa.com;
proxy_cache pass;
proxy_cache_key $request_uri; #以请求的URI为查询缓存的键
proxy_cache_valid 200 302 10m; #响应码为302 202缓存有效时长为10m
proxy_cache_valid 404 1m; #响应码为404的缓存有效时长为1m
location / {
proxy_pass http://192.168.10.12:80;
proxy_set_header X-Forwarded-For $proxy_add_X_forwarded_for;
}
location ~* \.(jpg|png)$ {
proxy_pass http://192.168.10.13:80;
}
}
}
15.ngx_http_upstream_module
#该模块用于定义可以由proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, memcached_pass和 grpc_pass指令引用的服务器组。
1.upstream NAME{...} #定义一个服务器组Context:http
2.server address [parameters]; #定义服务器地址和其他参数。地址可以使IP或域名,可写端口,默认为80
weight=number #权重
max_conns=number #最大并发连接数
max_fails=number #健康状态检测,超时次数,default:1
fail_timeout=time #健康状态检测,多长时间检测一次,default:10s
backup #将服务器标记为备份服务器。当主服务器不可用时,将传递请求。不能和hash,ip_hash,random使用
down #将服务器标记为永久不可用
3.ip_hash #sh算法,源地址hash。Context:upstream
4.hash KEY #KEY hash,自定义用什么来进行hash调度
$remote_addr,基于IP地址hash $request_uri基于uri hash
5.Keepalive connections #每个worker进程与后端服务器的保持连接的最大数量。如果超过此数量,则关闭最近最少使用的连接
6.least_conn #最少连接算法,权重不同时即为wlc;
example:
upstream lb{
hash $request_uri;
server 192.168.10.12 weight=2 max_fails=3 fail_timeout=1s;
server 192.168.10.13 weight=3 max_fails=3 fail_timeout=1s;
# server 127.0.0.1 backup; #hash绑定不能和backup同时使用
keepalive 32;
}