nginx基础
Nginx的基本架构
一个master主进程,生成一个或多个worker子进程
事件驱动
epoll(边缘触发),用于Linux
kqueue:用于BSD
/dev/poll:
IO复用器:select、poll、rt signal
支持sendfile及sendfile64
支持AIO
支持mmap
名词解释:
sendfile机制:正常响应报文路径“内核空间-->用户空间-->内核空间-->客户端”,如果报文在用户空间不做任何改变时,路径不再经由用户空间,直接由内核空间响应给客户端,省去两步无意义的IO消耗,此种机制即sendfile
工作模式
非阻塞、事件驱动机制,由一个master进程生成多个worker线程,每个worker响应n个请求
配置文件
main配置段:全局配置段
event配置段:定义event模型工作特性
http{}:定义http协议相关的配置
配置指令不区分大小写,要以“;”结尾;
语法格式
directive value [value2…]
支持使用变量
内置变量
模块会提供内置变量定义
自定义变量
set var_name value
主配置段指令
正常运行的必备配置
优化性能的配置
事件相关的配置
用于调试、定位问题
Nginx主配置段指令
正常运行的必备配置
1、user USERNAME[GROUPNAME]
指定运行worker进程的用户和组;
user nginx nginx
2、pid/path/to/pid_file
指定nginx守护进程的pid文件;
pid /var/run/nginx/nginx.pid
3、worker_rlimit_nofile#
指定所有worker进程所能打开的最大文件句柄数
4、worker_rlimit_core
指定所有worker进程所能使用的核心文件的最大值,一般无需手动调整
性能优化相关配置
1、worker_processes #
worker进程的个数,通常应该略少于CPU物理核心数
2、worker_cpu_affinity cpumask …
将worker进程绑定在指定的cpu上,当该cpu产生进程切换后,worker进程需再度运行时只会被调度回原来绑定的cpu上,从而使之前运行产生的缓存依然有效,提升cpu缓存的命中率;但无法降低contextswitch
要想降低context switch,需要在系统启动时隔离出要绑定的cpu,并将中断处理从绑定cpu上剥离,从而达到专cpu专用;
worker_cpu_affinity 00000001 0000010表示绑定第1、2号cpu
3、timer_resolution
计时器解析度:降低此值可减少gettimeofday()系统调用的次数,从而减少软中断,提升系统性能;
4、worker_priority number
指明worker进程的nice值(-20~19);
名词解释
context switch:
进程切换,会使cpu产生无意义消耗;
cpumask:
cpu掩码;假设系统有4颗cpu,可用8位二进制数字表示,用对应位数字1,其他位数字0表示相应的cpu,如:0000 0001(1号)0000 0010(2号)0000 0100(3号)0000 1000(4号);0000 0011(表示1号和2号两颗cpu);
gettimeofday():
一种系统调用,日志系统记录日志时需要使用当前系统的时间,此时即可通过调用此程序获得时间;
计时器解析度:
解析度越高,调用gettimeofday()的次数就越频繁,相应的,记录日志时的时间也就越精确;
优先级:
nice值(-20~19)对应的优先级(100~139),默认nice值为0,即优先级为120;nice值越小,优先级越高;
事件相关配置
1、accept_mutex {on|off}
master调度用户请求至各worker进程时使用的负载均衡锁,on表示能让所有worker轮流的、序列化的响应新请求;
2、lock_file
accept_mutex用到的锁文件路径;
3、use[epoll|rtsig|select|poll]
指明使用的事件模型,建议让nginx自行选择;
4、worker_connections
设定单个worker进程所能处理的最大并发连接数;
worker_connections * worker_processes = nginx所能接受的最大并发连接数
用户调试、定位问题
1、daemon {on|off}
是否以守护进程方式运行nginx;调试时应设置为off,从而能将各种日志及错误信息输出到屏幕上,以便在前台查看;
2、master_process {on|off}
是否以master/worker模型来运行nginx;调试时可以设置为off;
3、error_log file | stderr |syslog:server=address[,parameter=value] | memory:size [debug | info | notice |warn | error | crit | alert | emerg]
指明错误日志的记录位置和记录级别,以便查看排错
记录格式:error_log 记录位置 记录级别;
若要使此配置段配置生效,需要在编译时使用--with-debug选项;
注意:调优常用修改参数:worker_processes,worker_cpu_affinity,worker_priority,worker_connections
新改动配置生效的方法
nginx -t:检查语法错误
nginx -s reload:重载配置文件
nginx -s stop|quit:停止nginx服务
nginx:开启nginx服务
nginx -s reopen:重启nginx服务
Nginx作为web服务器时使用的配置
http{}:由ngx_http_core_module模块引入
配置框架
http {
upstream{
...
}
server {
location URL {
root"/path/to/somedir";
...
} # 类似于httpd中的<Location>,用于定义URL与本地文件系统的映射关系;
locationURL {
if... {
...
}
}
}# 每个server类似于httpd中的一个<VirtualHost>,用来定义虚拟主机;
server{
...
}
}
注意:与http相关的指令仅能放置于http、server、location、upstream、if上下文中,但有些指令的应用位置是固定的,仅能应用于这5种上下文的某些种
配置指令
1、定义虚拟机
server{}
server{
listen 8080;
server_name www.magedu.com;
root "/vhosts/web1";
}
2、指定监听的地址和端口
listen
listen address [:port]
listen port
listen unix:path
采用第三种监听,表示监听在本地的一个socket类型的文件上,意味着客户端只能是本机
3、设置主机名
server_name NAME […]
仅能用于server上下文中
server_name后可跟多个主机,主机名还可使用正则表达式(~)或通配符
匹配法则
(1)优先做精确匹配检测;
(2)左侧通配符匹配检查:如*.magedu1.com;
(3)右侧通配符匹配检查:如mail.*;
(4)正则表达式匹配检查:如~^.*\.magedu2\.com$;
(5)default_server;
server{
server_name www.magedu1.com;
}
server{
server_name *.magedu1.com;
}
server{
server_namemail.*
}
以上述server定义的虚拟机为例加以说明:
(1)当用户访问www.magedu1.com时,1、2都匹配,优先匹配服务器1;
(2)当用户访问mail.magedu1.com时,2、3都匹配,优先匹配服务器2;
(3)当用户访问mail.magedu2.com时,3、4都匹配,优先匹配服务器3;
(4)当用户访问ftp.magedu2.com时,匹配服务器4;
(5)当用户访问ftp.magedu.com时,所有服务器都不匹配,则只能匹配默认服务器;若默认服务器未定义,则自上而下按顺序匹配;
4、设置资源映射路径
root path
用于指明请求的URL所对应的资源所在的文件系统上的起始路径
root放置的位置越大,生效范围越大,但是相应的,生效的优先级也就越低。比如:放在http中对,所有server都生效;放在某server中,对该server中所有的location都生效;放在某location中,对该location中所有if都生效;但是假如root1放在server中,而该server的某location中定义了root2,则对该location而言,生效的一定是root2;
5、定义location
location[ = | ~ | ~* | ^~ ] uri { ... }
允许根据用户请求的URL来匹配定义的各location;匹配到时,此请求将被相应的location配置块中的配置所处理,例如做访问控制等功能;
匹配法则:
=:精确匹配检查;
~:正则表达式模式匹配检查,区分字符大小写;
~*:正则表达式模块匹配检查,不区分字符大小写;
^~:URI的前半部分匹配,不支持正则表达式;
匹配的优先级:精确匹配(=)-->^~-->~-->~*-->不带任何符号的location;
server{
listen80;
server_namewww.magedu.com;
①location =/ {
root"/vhosts/web1";
}
②location/ {
root"/vhosts/web1";
}
③location ^~/images/ {
root"/vhosts/images";
}
④location~* \.php$ {
fcgipass
}
}
以上述location为例加以说明:
若访问http://www.magedu.com,则匹配①;
若访问http://www.magedu.com/bbs/,则匹配②;
若访问http://www.magedu.com/images/index.php,则匹配③;
6、设置别名
alias path;
用于location配置段,定义路径别名
location /images/ {
root"/vhosts/web1";
}
http://www.magedu.com/images/a.jpg<-- /vhosts/web1/images/a.jpg
location/images/ {
alias "/www/pictures/";
}
http://www.magedu.com/images/a.jpg <-- /www/picuters/a.jpg
可以这样理解:若location中定义为root,则root指明的路径是相对于/images/的左侧的“/”而言的;若location中定义为alias,则alias指明的路径是相对于/images/的右侧的“/”而言的。
注意:root表示指明路径为对应的location "/" URL;alias表示路径映射,即location指令后定义的URL是相对于alias所指明的路径而言;
7、设置默认主页面
index file
index index.php index.html
8、设置错误页面
error_page code […] [=code] URI | @name
根据http的响应状态码来指明特用的错误页面
error_page 404 /404_customed.html
[=code]:以指定的响应码进行响应而非默认的原来的响应码;省略时默认以新资源的响应码做为其响应码
通过上图设置,既定制了404错误页面信息,也自定义了返回的状态码(本来应返回404,此处却返回200 OK)
9、基于IP的访问控制
allow IP/Network
deny IP/Network
在配置文件中添加一行信息“deny172.16.14.1;”前后测试对比
10、基于用户的认证
basic,digest
auth_basic后跟提示信息以提醒用户为何需要认证
auth_basic_user_file
帐号密码文件建议使用htpasswd来创建
1、修改配置文件
2、创建用户和密码
#mkdir users
#htpasswd -c -m /etc/nginx/users/.htpasswd zrcj
11、配置https服务
1、生成CA自签证书
#(umask 077;openssl genrsa -out private/cakey.pem 2048)
#openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 2650
# touchindex.txt
# echo01 > serial
2、生成申请证书
# mkdir/etc/nginx/ssl
# cd/etc/nginx/ssl
#(umask 077;openssl genrsa -out nginx.key 1024)
#openssl req -new -key nginx.key -out nginx.csr
3、签署证书
#openssl ca -in nginx.csr -out nginx.crt -days 365
4、修改配置文件
5、浏览器测试
12、配置nginx状态页
stub_status {on|off}
仅能用于location上下文
location/status {
stub_status on;
allow 172.16.0.0/16;
deny all;
}
结果示例:
Active connections: 6 # 当前所有处于打开状态的连接数;
server accepts handled requests
241 241 431
Reading: 0 Writing: 1 Waiting: 5
第一行信息:当前所有处于打开状态的连接数;
第二行的3个数字:
(1) 已经接受过的连接数
(2) 已经处理过的连接数
(3)已经处理过的请求数;在“保持连接”模式下,请求数可能会多于连接数;
最后一行信息
Reading:正处于接收请求状态的连接数;
Writing:请求已经接收完成,正处于处理请求或发送响应的过程中的连接数;
Waiting:保持连接模式,且处于活动状态的连接数;
13、URL重写
rewrite regex replacement flag;
例如:
...
rewrite^/images/(.*\.jpg)$ /imgs/$1 break;
rewrite^/imgs/(.*\.jpg)$ /images/$1 break;
....
注意:nginx的URL重写中参数引用不使用“\1,\2”,而是改为“$1,$2”
http://www.magedu.com/images/a/b/c/1.jpg--> http://www.magedu.com/imgs/a/b/c/1.jpg
flag:
last:
一旦此rewrite规则重写完成后,就不再被后面其它的rewrite规则进行处理;而是由UserAgent重新对重写后的URL再一次发起请求,并从头开始执行类似的过程
break:
一旦此rewrite规则重写完成后,由UserAgent对新的URL重新发起请求,且不再会被当前locatrion内的任何rewrite规则所检查(当所写rewrite规则构成死循环时需使用break);
redirect:
以302响应码(临时重定向)返回新的URL;(当替换的目标位置是以“http”协议开头的新的绝对路径时,可使用此flag)
permanent:
以301响应码(永久重定向)返回新的URL;
名词解释
SEO:
搜索引擎优化(SearchEngine Optimization,简称SEO)是一种利用搜索引擎的搜索规则来提高目的网站在有关搜索引擎内的排名的方式
14、if
语法:if (condition) {...}
应用环境:server, location
condition:
(1)变量引用;
变量值为空串,或者以“0”开始,则为false;其它的均为true;
(2)以变量为操作数构成的比较表达式
可使用=, !=类似的比较操作符进行测试;
(3)正则表达式的模式匹配操作
~: 区分大小写的模式匹配检查
~*: 不区分大小写的模式匹配检查
!~和!~*:对上面两种测试取反
(4) 测试指定路径为文件可能性:-f, !-f
(5) 测试指定路径为目录的可能性:-d, !-d
(6) 测试文件的存在性:-e, !-e
(7) 检查文件是否有执行权限:-x, !-x
例如:
if($http_user_agent ~* MSIE) {
rewrite^(.*)$ /msie/$1 break;
}
名词解释
$http_user_agent:
内置变量,获取用户的浏览器类型
MSIE:
MicrosoftInternet Explorer,微软浏览器
15、防盗链
location~* \.(jpg|gif|jpeg|png)$ {
valid_referernone blocked www.magedu.com;
if($invalid_referer) {
rewrite^/ http://www.magedu.com/403.html;
}
}
名词解释
valid_referer:
nginx的内置指令,用于定义哪种引用是合法的
16、定制访问日志
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;
注意:此处可用变量为nginx各模块内建变量;
网络连接相关的配置
1、keepalive_timeout #;
长连接的超时时长,默认为75s;
2、keepalive_requests #;
在一个长连接上所能够允许请求的最大资源数;
3、keepalive_disable [msie6|safari|none];
为指定类型的User Agent禁用长连接;
4、tcp_nodelay on|off;
是否对长连接使用TCP_NODELAY选项;
5、client_header_timeout #;
读取http请求报文首部的超时时长;
6、client_body_timeout #;
读取http请求报文body部分的超时时长;
7、send_timeout #;
发送响应报文的超时时长;
名词解释
tcp_nodelay:
tcp连接需要3次握手和4次断开,此为额外开销;若某次申请的内容全是多个数据量很小的请求,会造成很大的额外开销,为避免此种浪费,tcp在拥塞避免算法中有一种解决方案:将多次请求的小资源打包封装成一个请求报文发送,这种解决方案叫做tcp_delay;tcp_nodelay与之相反
fastcgi相关的配置
LNMP:php启用fpm模型;
location~ \.php$ {
①root html;
②fastcgi_pass 127.0.0.1:9000;
③fastcgi_index index.php;
④fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
⑤include fastcgi_params;
}
①:指明php的根目录位置;
②:反向代理至本机9000端口上,若php是单独的另一台主机,要监听在该主机的外部网卡上;
③:指明fastcgi_index的主页;
④:指明SCRIPT_FILENAME及其位置;
⑤:包含进/etc/nginx/目录下的fastcgi_params,该文件定义了如何把用户请求的变量值映射给后端的fastcgi;
原文地址:http://10066605.blog.51cto.com/10056605/1654526