IT序号网

Nginx学习之Nginx配置知识解答

qq123 2021年07月06日 程序员 196 0

  Nginx可以用来提供静态资源服务(静态资源文件访问)、反向代理服务(请求转发、负载等)、API服务,可以通过配置文件进行配置来实现Nginx的能力,因此本篇就进行配置文件的详述来进行Nginx使用实践。

1、Nginx配置概述

  1.1、配置文件结构

  Nginx配置文件结构目录如下图所示:

  

  具体模块功能分工如下:

  • 全局块

  该部分配置主要影响Nginx全局,通常包括下面几个部分:配置运行Nginx服务器用户(组)、worker process数、Nginx进程PID存放路径、错误日志的存放路径配置文件的引入。

  • events块

  该部分配置主要影响Nginx服务器与用户的网络连接,主要包括:设置网络连接的序列化、是否允许同时接收多个网络连接、事件驱动模型的选择、最大连接数的配置。

  • http块

  定义MIMI-Type自定义服务日志、允许sendfile方式、传输文件连接超时时间、单连接请求数上限。

  • server块

  配置网络监听基于名称的虚拟主机配置、基于IP的虚拟主机配置。

  • location块

  location配置请求根目录配置、更改location的URI、网站默认首页配置。

  1.2、配置文件语法

  Nginx的配置语法如下:

  • 配置文件由指令与指令块构成,每条指令以;结尾,
  • 指令与参数间以空格符号分割
  • 指令块以{}大括号将多条指令组织在一起
  • include语句允许组合多个配置文件以提升可维护性
  • 使用#符号添加注释,提供可读性
  • 使用$符号使用变量
  • 部分指令的参数支持正则表达式

  如示例:

   

2、Nginx详细配置

  2.1、Nginx全局块配置

  配置示例:

user  nobody nobody; 
worker_processes  3; 
 
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;

  2.1.1、配置运行Nginx服务器用户(组)

  指令格式:user user [group];

  user:指定可以运行Nginx服务器的用户

  group:可选项,可以运行Nginx服务器的用户组。

  如果user指令不配置或者配置为user nobody nobody,则默认所有用户都可以启动Nginx进程(window下不指定)。

  2.1.2、worker process数配置

  Nginx服务器实现并发处理服务的关键,指令格式:worker_processes number | auto;

  number:Nginx进程最多可以产生的worker process数。

  auto:Nginx进程将自动检测并设定worker process数。

  worker_processes设置为多少,Nginx的主进程就会创建多少个worker_processes子进程,根据硬件调整,通常worker_process数等于CPU数量或者2倍于CPU。

  2.1.3、Nginx进程PID存放路径

  Nginx进程是作为系统守护进程在运行,需要在某文件中保存当前运行程序的主进程号,Nginx支持该保存文件路径的自定义。

  指令格式:pid file;

  file:指定存放路径和文件名称如果不指定默认置于路径 logs/nginx.pid。

  2.1.4、错误日志的存放路径

  指定格式:error_log file | stderr;

  file:日志输出到某个文件。

  filestderr:日志输出到标准错误输出。

  这个设置可以放入全局块,http块,server块,级别以此为:debug|info|notice|warn|error|crit|alert|emerg。

error_log  logs/error.log;   
error_log  logs/error.log  notice;   
error_log  logs/error.log  info;  

  2.1.5、指定指定进程可以打开的最大描述符

worker_rlimit_nofile 65535;

  这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit -n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。

  现在在linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。

  2.2、events模块配置

  配置示例:

use epoll; 
accept_mutex on; 
multi_accept on; 
worker_connections  1024; 
keepalive_timeout 60; 
client_header_buffer_size 4k;   
open_file_cache max=65535 inactive=60s;    
open_file_cache_valid 80s; 
open_file_cache_min_uses 1;

  2.2.1、指定事件模型

use epoll;

  使用epoll的I/O 模型。linux建议epoll,FreeBSD建议采用kqueue,window下不指定。

补充说明:与apache相类,nginx针对不同的操作系统,有不同的事件模型。

A)标准事件模型

  Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或poll。

B)高效事件模型

  Kqueue:适用于FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X。使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。

  Epoll:适用于Linux内核2.6版本及以后的系统。

  /dev/poll:适用于Solaris 7 11/99+,HP/UX 11.22+ (eventport),IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+。

  Eventport:适用于Solaris 10。 为了防止出现内核崩溃的问题, 有必要安装安全补丁。

  2.2.2、设置网络连接的序列化

  指令格式:accept_mutex on | off;

  该指令默认为on状态,但在1.11.3的后续版本中默认为off。表示会对多个Nginx进程接收连接进行序列化,防止多个进程对连接的争抢。也就是防止“惊群现象”发生,就Nginx的场景来解释的话大致的意思就是:当一个新网络连接来到时,多个worker进程会被同时唤醒,但仅仅只有一个进程可以真正获得连接并处理之。如果每次唤醒的进程数目过多的话,其实是会影响一部分性能的。

  所以在这里,如果accept_mutex on,那么多个worker将是以串行方式来处理,其中有一个worker会被唤醒;反之若accept_mutex off,那么所有的worker都会被唤醒,不过只有一个worker能获取新连接,其它的worker会重新进入休眠状态。

Changes with nginx 1.11.3                                        26 Jul 2016 
    *) Change: now the "accept_mutex" directive is turned off by default.

  这个值的开关与否其实是要和具体场景挂钩的。 

  2.2.3、是否允许同时接收多个网络连接

  指令格式:multi_accept on | off;

  该指令默认为off状态,意指每个worker process 一次只能接收一个新到达的网络连接。若想让每个Nginx的worker process都有能力同时接收多个网络连接,则需要开启此配置。

  2.2.4、工作进程的最大连接数量

worker_connections 512;

  每个工作进程的最大连接数量。根据硬件调整,和前面工作进程配合起来用,尽量大,但是别把cpu跑到100%就行。每个进程允许的最多连接数,默认512,理论上每台nginx服务器的最大连接数为:worker_processes*worker_connections。

  2.2.5、其余配置

keepalive_timeout 60;  #keepalive超时时间。
#客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
#分页大小可以用命令getconf PAGESIZE 取得。但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。 client_header_buffer_size 4k;   #这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 open_file_cache max=65535 inactive=60s; #这个是指多长时间检查一次缓存的有效信息。 open_file_cache_valid 80s; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如下例,如果有一个文件在inactive时间内一次没被使用,它将被移除。 open_file_cache_min_uses 1;

  2.3、HTTP全局配置模块

  2.3.1、定义MIME-Type

#设定mime类型,类型由mime.type文件定义 
include       mime.types; 
#指定默认文件类型,默认为text/plain。MIME-Type指的是网络资源的媒体类型,也即前端请求的资源类型include指令将mime.types文件包含进来 
default_type  application/octet-stream;

  我们通过cat mime.types来查看mime.types文件内容,我们发现其就是一个types结构,里面包含了各种浏览器能够识别的MIME类型以及对应类型的文件后缀名字,如下所示:

  

  2.3.2、自定义服务日志

  指令格式:access_log path [format],适用于HTTP全局模块、Server全局模块。

  path:自定义服务日志的路径 + 名称

  format:可选项,自定义服务日志的字符串格式。

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' 
                  '$status $body_bytes_sent "$http_referer" ' 
                  '"$http_user_agent" "$http_x_forwarded_for"'; 
log_format  log404 '$status [$time_local] $remote_addr $host$request_uri $sent_http_location'; 

#用了log_format指令设置了日志格式之后,需要用access_log指令指定日志文件的存放路径; access_log logs/access.log main; access_log logs/host.access.404.log log404;

  日志格式如下所示:

$remote_addr与$http_x_forwarded_for用以记录客户端的ip地址; 
$remote_user:用来记录客户端用户名称; 
$time_local: 用来记录访问时间与时区; 
$request: 用来记录请求的url与http协议; 
$status: 用来记录请求状态;成功是200, 
$body_bytes_sent :记录发送给客户端文件主体内容大小; 
$http_referer:用来记录从那个页面链接访问过来的; 
$http_user_agent:记录客户浏览器的相关信息;

  注意:通常web服务器放在反向代理的后面,这样就不能获取到客户的IP地址了,通过$remote_add拿到的IP地址是反向代理服务器的iP地址。反向代理服务器在转发请求的http头信息中,可以增加x_forwarded_for信息,用以记录原有客户端的IP地址和原来客户端的请求的服务器地址。

  2.3.3、缓存配置

  open_file_cache max指令指定缓存是否启用,可以适用于在HTTP全局模块、server全局模块以及location模块进行使用,如下所示:

# 这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。 
open_file_cache max=65535 inactive=60s; 
 
# 语法:open_file_cache_errors on | off ,默认值:off 
# 配置适用模块:http, server, location,这个指令指定是否在搜索一个文件是记录cache错误。 
open_file_cache_errors on 
 
#语法:open_file_cache_min_uses number 默认值:1  
# 配置适用模块:http, server, location,这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如果使用更大的值,文件描述符在cache中总是打开状态. 
open_file_cache_min_uses 2 
 
# 语法:open_file_cache_valid time 默认值:60  
# 配置适用模块:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息. 
open_file_cache_valid 30s

  2.3.4、允许sendfile方式传输文件

  sendfile参数用于开启高效文件传输模式,也就是基于IO的零拷贝技术,其配置说明如下:

# sendfile指令指定nginx是否调用sendfile函数(zero copy方式)来输出文件,对于普通应用,必须设为on。 
# 如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络IO处理速度,降低系统uptime。 
# 默认为off,可以在http块,server块,location块。 
sendfile on | off;   
# size>0,则Nginx进程的每个worker process每次调用sendfile()传输的数据了最大不能超出此值;若size=0则表示不限制。默认值为0 
sendfile_max_chunk size;  #如100K 
# 在FreeBSD上使用TCP_NOPUSH套接字选项, 在Linux上使用TCP_CORK套接字选项。 在Linux和FreeBSD 4.*上将响应头和正文的开始部分一起发送;此选项仅在使用sendfile的时候使用。 
tcp_nopush on; 
#  这个选项仅在将连接转变为长连接的时候才被启用。将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞; 
tcp_nodelay on;

  2.3.5、HttpGzip模块配置

  gzip模块支持在线实时压缩输出数据流,浏览器请求会告诉服务端当前浏览器支持的压缩类型,服务端会将数据根据浏览器支持的压缩类型进行压缩返回。浏览器请求时会附带支持的压缩类型,如下图所示:

  

  配置示例及含义如下:

# 用于设置开启或者关闭gzip模块,“gzip on”表示开启GZIP压缩,实时压缩输出数据流; 
gzip on; 
# 设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大; 
gzip_min_length 1K 
# 表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果; 
gzip_buffers 4 16k; 
# 用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可; 
gzip_http_version 1.1; 
# 用来指定GZIP压缩比(1~9),1 压缩比最小,处理速度最快;9 压缩比最大,传输速度快,但处理最慢,也比较消耗cpu资源; 
gzip_comp_level 2; 
# 用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的; 
gzip_types text/plain application/json application/x-javascript application/css application/xml application/xml+rss 
    text/javascript application/x-httpd-php image/jpeg image/gif image/png image/x-ms-bmp;
# 选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据。 
gzip_vary on;

  效果如下所示(原始文件+效果):

  

  

  2.3.6、负载均衡配置

  upstream是Nginx的HTTP Upstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。upstream常见参数如下:

service:反向服务地址 加端口。 
weight:权重。 
max_fails:允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream 模块定义的错误;并认为主机已挂掉则,踢出。 
fail_timeout:踢出后重新探测时间,也就是在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。 
down:表示当前的server暂时不参与负载均衡; 
backup:预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻; 
max_conns:允许最大连接数。 
slow_start:当节点恢复,不立即加入,而是等待 slow_start 后加入服务对列。

  注意:当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。

  upstream支持以下几种负载均衡算法,配置如下所示:

  • 轮询(默认)

  每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

upstream backserver { 
  server 192.168.0.14; 
  server 192.168.0.15; 
}
  • 指定权重

  指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

upstream backserver { 
  server 192.168.0.14 weight=8; 
  server 192.168.0.15 weight=10; 
}
  • ip_hash(IP绑定)

  每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决分布式session的问题。

upstream backserver { 
  ip_hash; 
  server 192.168.0.14:8888; 
  server 192.168.0.15:8080; 
}
  • least_conn最少连接优先

  把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相同;但是有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就可以达到更好的负载均衡效果。

upstream backserver { 
    least_conn; #把请求转发给连接数较少的后端服务器 
    server localhost:8080 weight=2; 
    server localhost:8081; 
    server localhost:8082 backup; 
    server localhost:8083 max_fails=3 fail_timeout=20s; 
}
  • fair(第三方)

  按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backserver { 
    server server1; 
    server server2; 
    fair; 
}
  • url_hash(第三方)

  按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

upstream backserver { 
  server squid1:3128; 
  server squid2:3128; 
  hash $request_uri; 
  hash_method crc32; 
}

  2.3.7、其他配置文件

server_names_hash_bucket_size 128; 
# 保存服务器名字的hash表是由指令server_names_hash_max_size 和server_names_hash_bucket_size所控制的。
# 参数hash bucket size总是等于hash表的大小,并且是一路处理器缓存大小的倍数。在减少了在内存中的存取次数后,使在处理器中加速查找hash表键值成为可能。
# 如果hash bucket size等于一路处理器缓存的大小,那么在查找键的时候,最坏的情况下在内存中查找的次数为2。
# 第一次是确定存储单元的地址,第二次是在存储单元中查找键 值。因此,如果Nginx给出需要增大hash max size 或 hash bucket size的提示,那么首要的是增大前一个参数的大小。 client_header_buffer_size 4k; # 客户端请求头部的缓冲区大小。这个可以根据你的系统分页大小来设置,一般一个请求的头部大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。
# 分页大小可以用命令getconf PAGESIZE取得。 large_client_header_buffers 
8 128k; # 客户请求头缓冲大小。nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取。 client_max_body_size 300m; # 设定通过nginx上传文件的大小。 proxy_connect_timeout 90#后端服务器连接的超时时间_发起握手等候响应超时时间。 proxy_read_timeout 180; # 连接成功后_等候后端服务器响应时间_其实已经进入后端的排队之中等候处理(也可以说是后端服务器处理请求的时间)。 proxy_send_timeout 180; # 后端服务器数据回传时间_就是在规定时间之内后端服务器必须传完所有的数据。 proxy_buffer_size 256k; # 设置从被代理服务器读取的第一部分应答的缓冲区大小,通常情况下这部分应答中包含一个小的应答头。
# 默认情况下这个值的大小为指令proxy_buffers中指定的一个缓冲区的大小,不过可以将其设置为更小。 proxy_buffers 
4 256k; # 设置用于读取应答(来自被代理服务器)的缓冲区数目和大小,默认情况也为分页大小,根据操作系统的不同可能是4k或者8k proxy_busy_buffers_size 256k; proxy_temp_file_write_size 256k; # 设置在写入proxy_temp_path时数据的大小,预防一个工作进程在传递文件时阻塞太长 proxy_temp_path /data0/proxy_temp_dir; # proxy_temp_path和proxy_cache_path指定的路径必须在同一分区 proxy_cache_path /data0/proxy_cache_dir levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g; # 设置内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。 keepalive_timeout 120; # keepalive超时时间。 client_body_buffer_size 512k; # 如果把它设置为比较大的数值,例如256k,那么,无论使用firefox还是IE浏览器,来提交任意小于256k的图片,都很正常。
# 如果注释该指令,使用默认的client_body_buffer_size设置,也就是操作系统页面大小的两倍,8k或者16k,问题就出现了。
# 无论使用firefox4.0还是IE8.
0,提交一个比较大,200k左右的图片,都返回500 Internal Server Error错误 proxy_intercept_errors on; # 表示使nginx阻止HTTP应答代码为400或者更高的应答。

  2.4、Server全局模块

listen 80; 
# listen用于指定虚拟主机的服务端口。 
server_name 192.168.8.18 cszhi.com; 
# server_name用来指定IP地址或者域名,多个域名之间用空格分开。 
index index.html index.htm index.php; 
# index用于设定访问的默认首页地址。 
root /wwwroot/www.cszhi.com 
# root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径。 
charset gb2312; 
# Charset用于设置网页的默认编码格式。 
access_log logs/www.ixdba.net.access.log main; 
# access_log用来指定此虚拟主机的访问日志存放路径,最后的main用于指定访问日志的输出格式。 
error_page 404 /404.html; 
error_page 500 502 503 504 /50x.html; 
# 错误页,如果返回对应错误码则跳到对应错误页面

  2.5、location模块

  2.5.1、location模块语法

  location URL配置块位于Server模块之内,URL地址匹配是进行Nginx配置中最灵活的部分。 location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页进行过滤处理。使用location URL匹配配置还可以实现反向代理,用于实现PHP动态解析或者负载负载均衡。location语法为是 location[=|~|~*|^~|@]/uri/{……} ,uri前面的方括号中的内容是可选项,解释如下:

  • / 基于uri目录匹配。
  • = 表示把URI作为字符串,以便与参数中的uri做完全匹配。
  • ~ 表示正则匹配URI时是字母大小写敏感的。
  • ~* 表示正则匹配URI时忽略字母大小写问题。
  • ^~ 表示正则匹配URI时只需要其前半部分与uri参数匹配即可。

  2.5.2、正则优先级

  如果根据匹配规则,多条location命中,则按照优先级进行匹配,其流程如下流程图所示:

优先级:(location =) > (location 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (/)

  

  如下所示示例:

location = / {   
   return 250;  
} 
location / {   
   return 251; 
}  
location /documents/ {   
   return 252; 
}   
location ~ /documents/Abc { 
    return 253; 
} 
location ^~ /images/ { 
    return 254; 
} 
location ~* \.(gif|jpg|jpeg)$ { 
    return 255;  
} 
location /images/abc { 
    return 256; 
} 
location ~ /images/abc/ { 
    return 257; 
}

  测试结果如下:

http://localhost/ -> return 250 
http://localhost/downloads/download.html -> return 251 
http://localhost/images/1.gif -> return 254 
http://localhost/images/abc -> return 256  此处实验和理论结果冲突,理论上该是返回254,欢迎大家实验指正 
http://localhost/images/abc/def -> return 257 此处试验和理论结果冲突,理论上该是返回254,欢迎大家实验指正 
http://localhost/documents/document.html -> return 252 
http://localhost/documents/1.jpg -> return 255 
http://localhost/documents/Abc.jpg -> return 253

  2.5.3、rewrite重定向

  指令语法:rewrite regex replacement[flag];

  应用位置:server、location、if

  rewrite是实现URL重定向的重要指令,他根据regex(正则表达式)来匹配内容跳转到replacement,结尾是flag标记。

  如:

location /rewrite_to_baidu { 
       rewrite ^/ http://www.baidu.com; 
}

  效果如下,访问http://localhost/rewrite_to_baidu,直接跳转到了http://www.baidu.com。

  

  rewrite会用到以下语法。

  • last – 基本上都用这个Flag。
  • break – 中止rewirte,不在继续匹配。
  • redirect – 返回临时重定向的HTTP状态302。
  • permanent – 返回永久重定向的HTTP状态301。

  注:last和break最大的不同在于,break是终止当前location的rewrite检测,而且不再进行location匹配 - last是终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则。

  • last
  1. 结束当前的请求处理,用替换后的URI重新匹配location;
  2. 可理解为重写(rewrite)后,发起了一个新请求,进入server模块,匹配location;
  3. 如果重新匹配循环的次数超过10次,nginx会返回500错误;
  4. 返回302 http状态码 ;
  5. 浏览器地址栏显示重地向后的url。
  • break
  1. 结束当前的请求处理,使用当前资源,不在执行location里余下的语句;
  2. 返回302 http状态码 ;
  3. 浏览器地址栏显示重地向后的url。

  另外,还可以通过if判断进行rewrite,语法如下:

Syntax:    if (condition) { ... } 
Default:    — 
Context:    server, location

  能作为条件的内容如下:

  • 变量名;如果变量的值为空字符串或“ 0”,则为false;否则为true (在1.0.1版之前,任何以“ 0”开头的字符串都被视为错误值。)
  • 使用“ =”和“ !=”运算符将变量与字符串进行比较
  • 将变量同使用“ ~”(区分大小写的匹配)和“ ~*”(不区分大小写的匹配)的正则表达式进行匹配正则表达式也可以使用占位符用于以后通过$1..$9变量进行填充。也可使用非运算符“ !~”和“ !~*”。如果正则表达式包含“ }”或“ ;”字符,则整个表达式应用单引号或双引号引起来。
  • 使用“ -f”和“ !-f”运算符检查文件是否存在
  • 使用“ -d”和“ !-d”运算符检查目录是否存在
  • 使用“ -e”和“ !-e”运算符检查文件,目录或符号链接是否存在
  • 使用“ -x”和“ !-x”运算符检查可执行文件

  常见参数如下:

$args #这个变量等于请求行中的参数。 
$content_length #请求头中的Content-length字段。 
$content_type #请求头中的Content-Type字段。 
$document_root #当前请求在root指令中指定的值。 
$host #请求主机头字段,否则为服务器名称。 
$http_user_agent #客户端agent信息 
$http_cookie #客户端cookie信息 
$limit_rate #这个变量可以限制连接速率。 
$request_body_file #客户端请求主体信息的临时文件名。 
$request_method #客户端请求的动作,通常为GET或POST。 
$remote_addr #客户端的IP地址。 
$remote_port #客户端的端口。 
$remote_user #已经经过Auth Basic Module验证的用户名。 
$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。 
$query_string #与$args相同。 
$scheme #HTTP方法(如http,https)。 
$server_protocol #请求使用的协议,通常是HTTP/1.0或HTTP/1.1 
$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。 
$server_name #服务器名称。 
$server_port #请求到达服务器的端口号。 
$request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。 
$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。 
$document_uri #与$uri相同。

  示例:

# 多目录转成参数 abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2 
if ($host ~* (.*)\.domain\.com) { 
    set $sub_name $1;    
    rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last; 
} 
 
# 目录对换 /123456/xxxx -> /xxxx?id=123456 
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last; 
 
# 例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下: 
if ($http_user_agent ~ MSIE) { 
    rewrite ^(.*)$ /nginx-ie/$1 break; 
} 
 
# 目录自动加“/” 
if (-d $request_filename){ 
    rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; 
} 
 
# 所有路径为 /images/*.png|jpg的请求都转发到/test下,try_files会依次顺序访问接下来的路径,前一个路径不存在则访问下一个。
# 如下例,要是$arg_file不存在则最后会返回"image not found exception" location / { rewrite '^/images/(.*)\.(png|jpg)$' /test?file=$1.$2; set $image_file $1; set $image_type $2; } location /test { root html; try_files /$arg_file /image404.html; } location /image404.html { return 404 "image not found exception"; }

  最后一个示例如下所示:

  

  2.5.4、proxy_pass

  proxy_pass主要用作代理转发,相较rewrite,proxy_pass不影响浏览器地址栏的url。在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。

假设下面四种情况分别用 http://192.168.1.1/proxy/test.html 进行访问。 
# 第一种:代理到URL:http://127.0.0.1/test.html 
location /proxy/ { 
    proxy_pass http://127.0.0.1/; 
} 
# 第二种(相对于第一种,最后少一个 / ),代理到URL:http://127.0.0.1/proxy/test.html 
    location /proxy/ { 
proxy_pass http://127.0.0.1; 
} 
# 第三种:代理到URL:http://127.0.0.1/aaa/test.html 
location /proxy/ { 
    proxy_pass http://127.0.0.1/aaa/; 
} 
# 第四种(相对于第三种,最后少一个 / ),代理到URL:http://127.0.0.1/aaatest.html 
location /proxy/ { 
    proxy_pass http://127.0.0.1/aaa; 
} 
 
# 另外可与负载均衡upstream进行配合使用,如下所示,会被负载到:http://30.4.4.4:9999/proxy/test.html或者http://30.4.4.5:8888/proxy/test.html 
upstream apptest { 
    server 30.4.4.4:9999; 
    server 30.4.4.5:8888; 
} 
location /proxy { 
    proxy_pass http://apptest; 
    proxy_set_header Host whhealth.org.cn:2005;         
}

  2.5.5、deny、allow

  Nginx的deny和allow指令是由ngx_http_access_module模块提供,Nginx安装默认内置了该模块。 除非在安装时有指定 --without-http_access_module。

  语法:allow/deny address | CIDR | unix: | all

  它表示,允许/拒绝某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问。注意:unix在1.5.1中新加入的功能。在nginx中,allow和deny的规则是按顺序执行的。

# 示例1:这段配置值允许192.168.0.0/24网段和127.0.0.1的请求,其他来源IP全部拒绝。 
location / { 
    allow 192.168.0.0/24; 
    allow 127.0.0.1; 
    deny all; 
} 
# 示例2:访问的uri中包含admin的请求,只允许110.21.33.121这个IP的请求。 
location ~ "admin" { 
    allow 110.21.33.121; 
    deny all 
} 
# 禁止多个目录 
location ~ ^/(cron|templates)/ { 
    deny all; 
    break; 
}

  效果如下所示:

  

3、常见场景配置

  3.1、日常常见操作

#第一个必选规则是直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。   
#这里是直接转发给后端应用服务器了,也可以是一个静态首页   
location = / {   
    proxy_pass http://tomcat:8080/index   
}   
 
# 第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项   
# 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用   
location ^~ /static/ {   
    root /webroot/static/;   
}   
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {   
    root /webroot/res/;   
}   
 
# 第三个规则就是通用规则,用来转发动态请求到后端应用服务器   
# 非静态文件请求就默认是动态请求  
location / {   
    proxy_pass http://tomcat:8080/   
}  

  3.2、日志切割

  我们可以通过crontab生成定时任务,定时对nginx日志进行归档。

# 列出当前用户的定时任务crontab 
crontab -l 
# 编辑crontab 
crontab -e 
# 分 时 日 月 星期 command 
MAILTO=“” 
0 0 * * * sh /usr/local/nginx/logs/rotate.sh 
# 重启crontab 
systemctl restart crond.service 
# 查看crontab状态 
systemctl status crond.service

  编写rotate.sh脚本进行日志归档操作。

#!/bin/bash 
log_path="/usr/local/nginx/logs/" 
datetime=$(date -d "-1 day" "+%Y%m%d") 
mkdir -p $log_path/history 
mv $log_path/access.log $log_path/history/access.log_$datetime.log 
mv $log_path/error.log $log_path/history/error.log_$datetime.log 
 
# 像Nginx主进程发送USR1信号重新生成日志文件 
kill -USE1 $(cat $log_path/nginx.pid)

  3.3、反向代理

  正向代理,是指客户端与目标服务器之间增加一个代理服务器,客户端直接访问代理服务器,在由代理服务器访问目标服务器并返回客户端并返回 。这个过程当中客户端需要知道代理服务器地址,并配置连接。

# 正向代理 
location = /baidu.html { 
    proxy_pass http://www.baidu.com; 
}

  反向代理,是指客户端访问目标服务器,在目标服务内部有一个统一接入网关将请求转发至后端真正处理 的服务器并返回结果。这个过程当中客户端不需要知道代理服务器地址,代理对客户端而言是透明的。

# 反向代理 
location = /fox { 
    proxy_pass http://127.0.0.1:8080/; 
}

  代理相关参数

proxy_pass # 代理服务 
proxy_redirect off; # 是否允许重定向 
proxy_set_header Host $host; # 传 header 参数至后端服务 
proxy_set_header X-Forwarded-For $remote_addr; # 设置request header 即客户端IP地址 proxy_connect_timeout 90; # 连接代理服务超时时间 
proxy_send_timeout 90; # 请求发送最大时间 
proxy_read_timeout 90; # 读取最大时间 
proxy_buffer_size 4k; 
proxy_buffers 4 32k; 
proxy_busy_buffers_size 64k; 
proxy_temp_file_write_size 64k;

  3.4、代理缓存

  代理缓存,获取服务器端内容进行缓存,详情可参考官网,http://nginx.org/en/docs/http/ngx_http_proxy_module.html

#proxy_cache_path 缓存路径 
#levels 缓存层级及目录位数 
#keys_zone 缓存区内存大小 
#inactive 有效期 
proxy_cache_path /tmp/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=60m use_temp_path=off; 
    server { 
        listen 80; 
        server_name  localhost *.yuanma.com; 
        location / { 
          proxy_set_header Host   $host; 
          proxy_set_header X-Real-IP  $remote_addr; 
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
          proxy_pass http://backend/; 
        proxy_cache my_cache; #以全路径md5值作为Key 
        proxy_cache_key $host$uri$is_args$args; 
    } 
}

  缓存参数详细说明:

  

  缓存清除 ,添加ngx_cache_purge模块,步骤如下:

#下载ngx_cache_purge 模块包 
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz 
#查看已安装模块 
./sbin/nginx -V 
#进入nginx安装包目录 重新构建 --add-module为模块解压的全路径 
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with- http_ssl_module --with-debug --add-module=/root/ngx_cache_purge-2.3 
#重新编译 
make 
#热升级
kill -SIGUSR2 nginx的pid号

  清除缓存配置如下:

location ~ /clear(/.*) {  
  #允许访问的IP 
  allow 192.168.3.1; 
  #禁止访问的IP 
  deny all; 
  #配置清除指定缓存区和路径(与proxy_cache_key一致)
  proxy_cache_purge my_cache $host$
1$is_args$args; }

  3.5、下载限速

  3.6、https转http

  生成自签名证书,https://www.cnblogs.com/hnxxcxg/p/7610582.html

# 使用openssl工具生成一个RSA私钥 
openssl genrsa -des3 -out server.key 1024 # 生成CSR(证书签名请求) 
openssl req -new -key server.key -out server.csr # 删除私钥中的密码 
openssl rsa -in server.key -out server.key 
# 生成自签名证书 
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

  配置https服务 : http://nginx.org/en/docs/http/configuring_https_servers.html

http { 
    #监听本机443端口为https协议 
    server { 
        listen  443 ssl; 
        server_name  localhost; 
 
        ssl_certificate      cert.pem;    #SSL证书路径 
        ssl_certificate_key  cert.key;    #SSL证书key路径 
 
        ssl_session_cache    shared:SSL:1m; 
        ssl_session_timeout  5m; 
 
        ssl_ciphers  HIGH:!aNULL:!MD5; 
        ssl_prefer_server_ciphers  on; 
 
        location / { 
            proxy_pass http://localhost:8080    #将监听443的https服务转发到本机的8080 http服务 
        } 
   } 
}

  3.7、websocket请求转发


发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Nginx学习之Nginx概念及部署知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。