- 默认启动Nginx时,使用的配置文件是: 安装路径/conf/nginx.conf 文件可以在启动nginx的时候,通过-c来指定要读取的配置文件
- 常见的配置文件有如下几个:
- nginx.conf:应用程序的基本配置文件
- mime.types:MIME类型关联的扩展文件
- fastcgi.conf:与fastcgi相关的配置
- proxy.conf:与proxy相关的配置
- sites.conf:配置Nginx提供的网站,包括虚拟主机
- Nginx的进程结构
- 启动Nginx的时候,会启动一个Master进程,这个进程不处理任何客户端的请求,主要用来产生worker进程,一个worker进程用来处理一个request。
- Nginx模块分为:核心模块、事件模块、标准Http模块、可选Http模块、邮件模块、第三方模块和补丁等
- Nginx基本模块:所谓基本模块,指的是Nginx默认的功能模块,它们提供的指令,允许你使用定义Nginx基本功能的变量,在编译的时候不能被禁用,包括:
- 核心模块:基本功能和指令,如进程管理和安全
- 事件模块:在Nginx内配置网络使用的能力
- 配置模块:提供包含机制常见的核心模块指令,大部分都是放置在配置文件的顶部具体的指令,请参看nginx的官方文档,非常详细,参见:http://nginx.org/en/docs/ngx_core_module.html还有下面这个网站,也是非常不错的:http://www.howtocn.org/nginx:directiveindex
- 常见的events模块指令,大部分都是放置在配置文件的顶部具体的指令,在上面那个文档里面,命令的context为events的就是events模块指令,只能在events里面使用,核心模块指令,重点看看:error_log、include、pid、user、worker_cpu_affinity、worker_processes
error_log日志有6个级别:debug|info|notice|warn|error|crit |
Nginx支持将不同的虚拟主机的日志记录在不同的地方,如下示例:
http{
error_log logs/http_error.log error;
server{
server_name one;
access_log logs/one_access.log;
error_log logs/one_error.log error;
}
server{
server_name two;
access_log logs/two_access.log;
error_log logs/two_error.log error;
}
}
注意:error_log off不是禁用日志,而是创建一个名为off的日志,要禁用日志,可以这么写:error_log/dev/null crit;
- Nginx的HTTP配置主要包括三个区块,结构如下:
http { //这个是协议级别 include mime.types; application/octet-stream; default_type keepalive_timeout 65; gzip on; server { //这个是服务器级别 listen 80; localhost; server_name location / { //这个是请求级别 root index } html{ index.html index.htm; } }
- Nginx的HTTP核心模块,包括大量的指令和变量,大都很重要,具体参见:
- http://nginx.org/en/docs/http/ngx_http_core_module.html
Location区段
- Location区段,通过指定模式来与客户端请求的URI相匹配,基本语法如下:
location [=|~|~*|^~|@] pattern{……}
1:没有修饰符 表示:必须以指定模式开始,如:
server {
server_name henry.com;
location /abc {
……
}
}
那么,如下是对的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
http://henry.com/abc/
http://henry.com/abcde
2:= 表示:必须与指定的模式精确匹配,如:
server {
server_name henry.com;
location = /abc {
……
}
}
那么,如下是对的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
如下是错的:
http://henry.com/abc/
http://henry.com/abcde
3:~ 表示:指定的正则表达式要区分大小写,如:
server {
server_name henry.com;
location ~ ^/abc$ {
……
}
}
那么,如下是对的:
http://henry.com/abc
http://henry.com/abc?p1=11&p2=22
如下是错的:
http://henry.com/ABC
http://henry.com/abc/
http://henry.com/abcde
4:~* 表示:指定的正则表达式不区分大小写,如:
server {
server_name henry.com;
location ~* ^/abc$ {
……
}
}
那么,如下是对的:
http://henry.com/abc
http://henry.com/ABC
http://henry.com/abc?p1=11&p2=22
如下是错的:
http://henry.com/abc/
http://henry.com/abcde
5:^~ 类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他模式了。
6:@ :定义命名location区段,这些区段客户段不能访问,只可以由内部产生的请求来访问,如try_files或error_page等
- 查找顺序和优先级
- 带有“=“的精确匹配优先
- 没有修饰符的精确匹配
- 正则表达式按照他们在配置文件中定义的顺序
- 带有“^~”修饰符的,开头匹配
- 带有“~” 或“~*” 修饰符的,如果正则表达式与URI匹配
- 没有修饰符的,如果指定字符串与URI开头匹配
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
location / {
# 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
[ configuration B ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
[ configuration C ]
}
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中 处理。
[ configuration D ]
}
各请求的处理如下例:
- / → configuration A
- /documents/document.html → configuration B
- /images/1.gif → configuration C
- /documents/1.jpg → configuration D
- Nginx通常被用作后端服务器的反向代理,这样就可以很方便的实现动静分离,以及负载均衡,从而大大提高服务器的处理能力。Http Proxy模块,功能很多,最常用的是proxy_pass,最好还是都看看。
- 如果要使用proxy_cache的话,需要集成第三方的ngx_cache_purge模块,用来清除指定的URL缓存。这个集成需要在安装nginx的时候去做,形如:./configure --add-module=../ngx_cache_purge-1.0 ……
动静分离
- Nginx实现动静分离,其实就是在反向代理的时候,如果是静态资源,那么就直
接从Nginx发布的路径去读取,而不需要从后台服务器获取了。
- 但是要注意:这种情况下需要保证后端跟前端的程序保持一致,可以使用Rsync
做服务端自动同步或者使用NFS、MFS分布式共享存储
负载均衡
- Nginx通过upstream模块来实现简单的负载均衡
- 在upstream块内,定义一个服务器列表,默认的方式是轮询,如果要确定同一个访问者发出的请求总是由同一个后端服务器来处理,可以设置ip_hash,如:
upstream cctest1.com {
ip_hash
server 127.0.0.1:9080 weight=5;
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:1111;
}
请注意:这个方法本质还是轮询,而且由于客户端的ip可能是不断变化的,比如动态ip,代理,翻墙等等,因此ip_hash并不能完全保证同一个客户端总是由同一个服务器来处理。
- 更多指令和配置,请参考Nginx的http负载均衡模块
Geo和GeoIP模块
- 这两个模块主要用于做全局的负载均衡,可以根据不同的客户端ip来访问不同的服务器,示例如下:
http{
geo $geo{
default default;
202.103.10.1/24 A;
179.9.0.3/24 B;
upstream default.server{
server 192.168.0.100;
}
upstream A.server{
server 192.168.0.101;
}
upstream B.server{
server 192.168.0.102;
}
server{
listen 80;
location / {
proxy_pass http://$geo.server$request_uri;
}
}
}
Rewrite模块配置
- Rewrite模块:用来执行URL重定向。这个机制有利于去掉恶意访问的url,也有利于搜索引擎优化(SEO)。
- Nginx使用的语法源于Perl兼容正则表达式(PCRE)库,基本语法如下:
- ^ :必须以^后的实体开头
- $ :必须以$前的实体结尾
- . :匹配任意字符
- [ ] :匹配指定字符集内的任意字符
- [^ ] :匹配任何不包括在指定字符集内的任意字符串
- | :匹配 | 之前或之后的实体
- () :分组,组成一组用于匹配的实体,通常会有|来协助
- 捕获子表达式,可以捕获放在()之间的任何文本,比如:
- ^(.*)(hello|sir)$ 字符串为“hi sir” 捕获的结果: $1=hi $2=sir这些被捕获的数据,在后面就可以当变量一样使用了
- 内部请求
- 外部请求是客户端的url,内部请求是Nginx通过特殊的指令触发。比如:error_page、index、rewrite、try_files、include等等
- 内部请求分成两种类型
- 内部重定向:URI被改变,可能会匹配到其他的Location
- 子请求:比如使用Addition模块,指令add_after_body允许你在原始的URI之后指定一个URI,会把该URI被处理后的结果,插入到原始的URI的body中。
- 内部重定向示例:
server {
server_name herny.com;
location /abc/ {
rewrite ^/abc/(.*)$ /bcd/$1
}
location /bcd/{
internal;
root pages;
}
}
n 条件结构的基本语法:
1:没有操作符:指定的字符串或者变量不为空,也不为0开始的字符串,取true
2:= , != ,例:if($request_method = POST){…}
3:~,~*,!~,!~* ,例:if($uri ~* “\.jsp$”){…}
4:-f,!-f :用来测试指定文件是否存在,例:if(-f $request_filename){…}
5:-d,!-d :用来测试指定目录是否存在
6:-e,!-e:用来测试指定文件、目录或者符号链接是否存在
7:-x,!-x:用来测试指定文件是否存在和是否可以执行
8:break:跳出if块
9:return:终止处理,并返回一个指定的http状态码
10:set:初始化或者重定义一个变量
- Http Index模块,都看看
- Http Referer模块,都看看,可用于防盗链
- Http Limit Zone模块,都看看,可用于会话的连接数控制,如限制每个IP的并发连接数等
- Http Access模块,用于简单的访问控制,都看看
- Http Charset模块,重点看看:charset
- Gzip模块,可以都看看
- Http Browser模块,用于按照请求头中的“User-agent”来创建一些变量,好为不同的浏览器创建不同的内容,暂时了解即可
- Memcached模块,这是把Nginx当作Memcached的客户端,用来连接Memcached的模块。暂时不用看
- Http Addition模块,可以在当前location内容之前或后添加内容,暂时不用看
- Http Empty Gif模块,这个模块在内存中保存一个能够很快传递的1×1透明GIF,暂时不用看
- Http Auth Basic模块,基于Http Basic认证的方式来保护虚拟主机或目录,暂时不用看
- Http AutoIndex模块,用于提供自动目录列表,该模块只有在找不到默认的index文件的时候才启用,暂时不用看
- Http Fcgi模块,用于与FastCGI进程交互,暂时不用看
- FLV Stream模块,支持当Http下载方式播放Flv时,可以支持进度条拖放,暂时不用看。
- SSL模块,暂时不用看
- 邮件模块,暂时不用看
- 还有很多的模块,这里就不再一一介绍了
- server配置为监听ip和端口
server{
listen 127.0.0.1:9080;
server_name 127.0.0.1;
}
server配置为监听域名和端口
server{
listen 80;
server_name www.henry.com henry.com *.henry.com;
}
向后台服务器传递客户端的真实ip
location ~ \.(jsp|action|mvc)$ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://henry.com;
}
- 在负载均衡里面,实现后端服务器故障转移的配置
location ~ \.(jsp|action|mvc)$ {
proxy_next_upstream http_502 http_504 timeout;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://server_pool;
}
- 简单的防盗链
location / {
……
valid_referers blocked henry.com *.henry.com;
if($invalid_referer){
rewrite ^/ http://henry.com;
}
}
- 简单的限制下载速度
location / {
limit_rate 256K;
使用proxy_cache的配置
http{#下面这两个path指定的路径必须在同一个分区
proxy_temp_path /cachetemp/proxy_temp_path;
#设置名称为mycache,内存缓存100m,自动清除1天未使用的内容,硬盘缓存空间1g
proxy_cache_path /cachetemp/proxy_cache_path levels=1:2 keys_zone=mycache:100m
inactive=1d max_size=1g;
server{
location ~ .*\.(gif|jpg|html|js|css)$ {
proxy_cache mycache; #使用名称为mycache的缓存
#对不同的Http状态码设置不同的缓存时间
proxy_cache_valid 200 304 24h;
proxy_cache_valid 301 302 10m;
proxy_cache_valid any 1m;
#设置缓存的key值
proxy_cache_key $host$uri$is_args$args;
}
}
}
Nginx的配置优化
如果没有足够的实力和必要去自己改写Nginx,那么Nginx的优化主要就是:优化Nginx的配置,做到合理高效的使用
- 优化的方向和目标,无外乎:
- 尽量提高单台机器处理效率
- 尽量降低单台机器的负载
- 尽量降低磁盘I/O
- 尽量降低网络I/O
- 尽量减少内存使用
- 尽量高效利用CPU
- 生产环境下,应该使Nginx模块最小化,就是用到哪几个就开哪几个,这个需要在编译安装Nginx的时候做。用户和组,生产环境下,最好是专为Nginx创建用户和组,并单独设置权限,这样会更安全。例如: user nginx nginx
- worker_processes :通常配置成cpu的总核数,或者其2倍,性能会更好。这可以减少进程间切换带来的消耗。
- 还可以同时使用worker_cpu_affinity来绑定cpu,使得每个worker进程独享一个cpu,实现完全的并发,性能更好,不过这个只对linux系统有效。
- events里面的事件模型,Linux推荐使用epoll模型,FreeBSD推荐采用kqueue
- worker_rlimit_nofile:描述一个nginx进程打开的最多的文件数目。配置成跟linux内核下文件打开数一致就可以了。可以通过ulimit -n 来查看,新装的系统默认是1024,CentOS中可以如下方式进行修改:在/etc/security/limits.conf最后增加:
- * soft nofile 65535
- * hard nofile 65535
- * soft nproc 65535
- * hard nproc 65535
- worker_connections:每个进程允许的最多连接数,默认是1024,可以设置大一些。理论上并发总数是worker_processes和worker_connections的乘积,
- worker_connections值的设置跟物理内存大小有关,因为系统可以打开的最大文件数和内存大小成正比,一般1GB内存的机器上可以打开的文件数大约是10万左右,所以,
- worker_connections 的值需根据 worker_processes 进程数目和系统可以打开的最大文件总数进行适当地进行设置。
- keepalive_timeout:设置到65左右就可以
- client_header_buffer_size:设置请求的缓存,设置为4k,通常为系统分页大小的整数倍,可以通过getconf PAGESIZE 来查看系统分页大小。
- 对打开文件设置缓存
- open_file_cache max=建议设置成和每个进程打开的最大文件数一致 inactive=60s;
- open_file_cache_valid 90s;
- open_file_cache_min_uses 2;
- open_file_cache_errors on;
- 尽量开启Gzip压缩,gzip_comp_level通常设置成3-5,高了浪费CPU
- Error日志优化:运行期间设置为crit,可以减少I/O
- access日志优化:如果使用了其他统计软件,可以关闭日志,来减少磁盘写,或者写入内存文件,提高I/O效率。
- sendfile指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,通常应设置成on,如果是下载等应用磁盘IO重负载应用,可设置为 off
- Buffers size优化:如果buffer size太小就会到导致nginx使用临时文件存储response,这会引起磁盘读写IO,流量越大问题越明显。
- client_body_buffer_size 处理客户端请求体buffer大小。用来处理POST提交数据,上传文件等。client_body_buffer_size 需要足够大以容纳需要上传的POST数据。同理还有后端的buffer数据。
- worker_priority进程优先级设置:Linux系统中,优先级高的进程会占用更多的系统资源,这里配置的是进程的静态优先级,取值范围-20到+19,-20级别最高。因此可以把这个值设置小一点,但不建议比内核进程的值低(通常为-5)
- 合理设置静态资源的浏览器缓存时间,尽量用浏览器缓存
- 负载均衡锁accept_mutex,建议开启,默认就是开启的
- 如果使用SSL的话,而且服务器上有SSL硬件加速设备的话,请开启硬件加速。