做服务端开发的,工作中难免会遇到处理Nginx配置相关问题。在配置Nginx时,我一直本着“照葫芦画瓢”的原则,复制已有的配置代码,自己修修改改然后完成配置需求,当有人问起Nginx相关问题时,其实仍然一无所知。为此在工作之余,花了一周的时间阅读Nginx配置相关文章,整理成自己的学习笔记如下:
- nginx是什么?
- nginx如何配置?
- nginx中location部分url如何匹配?
- nginx中rewrite命令如何重写url?
- nginx中if判断如何使用?
- nginx变量如何使用?
- nginx中一些常用的命令
nginx是什么
Nginx是俄罗斯人Igor Sysoev基于C语言编写的十分轻量级的HTTP服务器,它主要有以下特点:
- 它是一个高性能的HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器;
- Nginx使用异步事件驱动的方法来处理请求,Nginx的模块化事件驱动架构可以在高负载下提供更可预测的性能;
- 作为Web服务器,Nginx处理静态文件、索引文件,自动索引的效率非常高
- 作为反向代理服务器,Nginx可以实现反向代理加速,提高网站运行速度
- 作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器对外进行服务,同时还支持简单的容错和利用算法进行负载均衡
- Nginx是专门为性能优化而开发的,非常注重效率,Nginx在官方测试的结果中,能够支持五万个并行连接,而在实际的运作中,可以支持二万至四万个并行链接
- 在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级
nginx如何配置?
Nginx的配置文件默认存放路径是etc/nginx/nginx.conf,可以在Nginx启动时添加参数–conf-path=PATH来更改nginx.conf文件的存放路径。nginx.conf中的配置信息主要包含以下五个部分:
- main(全局设置):主要是包括Nginx工作进程,日志的配置以及server,location中一些共用的配置
- events(连接设置):主要包括Nginx连接信息的配置
- server(主机设置):主要是包括主机名称,Ip,路径解析,http请求头设置,反向代理等配置
- upstream(上游服务器设置):主要为反向代理服务器信息、负载均衡等相关配置
- location(URL匹配):特定URL的匹配设置
以上每部分包含若干个条指令,他们之间的关系是:server继承main,location继承server,main部分设置的指令将影响其它所有部分的设置,server部分的设置将影响到location部分的设置。upstream既不会继承指令也不会被继承,它有自己的特殊指令,不需要在其他地方的应用。
以下是我整理的关于Nginx五个主要模块的所有基础参数设置,并用#注释的方式对每个参数的含义做了详细的阐述:
Nginx基础配置参数详解:
1 ################################################################################################################## 2 # main全局配置 # 3 ################################################################################################################## 4 5 user www www; #默认为nobody 6 # 设置nginx工作进程的用户 7 8 worker_processes 2; # 默认为1 9 # 设置worker角色的工作进程的个数,正常情况下可以设置成cpu的内核数,最多设置为8个; 10 # 也可以将worker_processes的值设为auto,这样nginx会自动检测CPU核数并打开相同数量的worker进程; 11 # 当nginx添加了SSL证书时,最好要打开多个worker进程。SSL握手会进行硬盘I/O操作。所以打开多个worker进程有利于性能的提升; 12 13 worker_cpu_affinity 01 10; 14 # 通过设置cpu粘性来降低由于多CPU核切换造成的寄存器等现场重建带来的性能损耗,上述设置表示第一个worker进程用第一个cpu,第二个worker进程进程使用第二个cpu 15 16 worker_rlimit_nofile; # 默认为操作系统的限制(65535) 17 # 设置每个worker进程的最大打开文件数(句柄)限制 18 19 error_log logs/error.log error; 20 # 配置错误日志路径以及打印级别(debug | info | notice | warn | error | crit | alert | emerg) 21 # 生产场景一般是warn | error | crit 这三个级别之一,级别太低会有太多IO消耗,影响效率 22 23 pid logs/nginx.pid; 24 # pid文件为文本文件,内容只有一行, 记录了该进程的ID,根据PID文件的内容,准确判断进程是否正在运行,防止意外启动多个进程实例。 25 # 只有获得pid文件(固定路径固定文件名)写入权限(F_WRLCK)的进程才能正常启动并把自身的PID写入该文件中,其它同一个程序的多余进程则自动退出。 26 27 ################################################################################################################## 28 # events模块中包含nginx中所有处理连接的设置 # 29 ################################################################################################################## 30 31 events { 32 use epoll; 33 # 用于设置处理客户端请求的轮询方法 34 # 在Linux操作系统下,nginx默认使用epoll事件模型 35 # 同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue 36 # 在操作系统不支持这些高效模型时才使用select 37 38 worker_connections 2048; #默认为512 39 # 设置可由一个worker进程同时打开的最大连接数。但不能超过worker_rlimit_nofile的设置 40 41 accept_mutex on; # 默认为on 42 # 当一个新连接到达时,如果激活了accept_mutex,那么多个Worker将以串行方式来处理,其中有一个Worker会被唤醒,其他的Worker继续保持休眠状态; 43 # 如果没有激活accept_mutex,那么所有的Worker都会被唤醒,不过只有一个Worker能获取新连接,其它的Worker会重新进入休眠状态,[thundering herd现象](https://en.wikipedia.org/wiki/Thundering_herd_problem) 44 45 accept_mutex_delay 500ms; # 默认为500ms 46 # 当accept_mutex功能启用后,只有一个持有mutex锁的worker进程会接受并处理请求,其他worker进程等待。accept_mutex_delay指定的时间就是这些worker进程的等待时间,过了等待时间下一个worker进程便取得mutex锁,处理请求。 47 48 multi_accept on # 默认为off 49 # multi_accept可以让nginx worker进程尽可能多地接受请求,提高性能 50 # 如果设置为on,可以让worker进程一次性地接受监听队列里的所有请求,然后处理 51 # 如果multi_accept的值设为off,那么worker进程必须一个一个地接受监听队列里的请求 52 # 如果web服务器面对的是一个持续的请求流,那么启用multi_accept可能会造成worker进程一次接受的请求大于worker_connections指定可以接受的请求数。这就是overflow,这个overflow会造成性能损失,overflow这部分的请求不会受到处理 53 } 54 55 ################################################################################################################## 56 # 提供http服务相关的一些配置参数 # 57 ################################################################################################################## 58 59 http { 60 61 #################################################################################### 62 # 基本配置 # 63 #################################################################################### 64 65 include mime.types; 66 # include可以包含若干子配置文件,实现不同需求配置独立,可以将不同的server配置在不同的conf文件里 67 # mime.types文件列出针对不同的请求文件返回的HTTP response的Content-Type的Accept值 68 # 除非服务端Web程序手动设置了Content-Type,如果Web程序没设置,则会从mime.types中匹配返回 69 # 如果mime.types中也没找到对应文件的扩展名的话,就使用默认的default_type 70 71 default_type application/octet-stream; 72 # 如果在mime.types的配置中没有找到响应请求文件的格式,则走default_type 73 74 types_hash_max_size 2048; 75 # 设置散列表的冲突率。 76 # types_hash_max_size越大,就会消耗更多的内存,但散列key的冲突率会降低,检索速度就更快。 77 # types_hash_max_size越小,消耗的内存就越小,但散列key的冲突率可能上升。 78 79 server_tokens off; 80 # 返回错误页面时是否在Server中注明Nginx版本 81 82 server_names_hash_bucket_size 64; 83 # 为了提高快速寻找到相应server_name的能力,Nginx 使用散列表来存储server_name,server_names_hash_bucket_size设置了每个散列桶占用的内存大小。 84 85 server_name_in_redirect off; 86 # 重定向主机名称的处理.该配置需要配合server_name使用. 87 # 设置为on时,表示在重定向请求时会使用stream里配置的第一个主机名代替原先请求中的Host头部,而当关闭时,表示在重定向请求时使用请求本身的Host头部。 88 89 90 91 #################################################################################### 92 # 日志配置 # 93 #################################################################################### 94 95 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 96 '$status $body_bytes_sent "$http_referer" ' 97 '"$http_user_agent" "$http_x_forwarded_for"'; 98 # 定义日志nginx日志文件的打印格式并命名为变量main 99 100 access_log logs/access.log main; 101 # access_log指定nginx的访问日志的存放路径文件以及使用的日志文件格式 102 103 #access_log off; 104 # 为了提高效率,可以将访问日志关掉 105 106 access_log /data/logs/nginx-access.log buffer=32k flush=5s; 107 # buffer和flush可以设置缓存日志的刷盘策略,日志超过32k才刷盘,如果没满32k,但是超过5s也自动刷盘 108 109 rewrite_log on; # 默认是off 110 # 开启或者关闭rewrite模块指令执行的日志,如果开启,则重写将记录下notice等级的日志到nginx 的error_log中 111 112 #################################################################################### 113 # 高效文件传输 # 114 #################################################################################### 115 116 sendfile on; 117 # 当一个程序需要传输文件时,Linux内核首先将文件数据缓冲,然后将文件数据传送给程序缓冲,最后程序将文件数据传输到目的地。 118 # Sendfile方法是一种数据传输的更高效的方法,数据在内核中的文件描述符之间传输 119 # 这种方法的结果是改善了对操作系统资源的利用,提高Nginx静态资源托管效率,直接在内核空间完成文件发送,不需要先read再write,没有上下文切换开销 120 121 tcp_nopush on; 122 # TCP_NOPUSH是FreeBSD的一个socket选项,对应Linux的TCP_CORK,Nginx里统一用tcp_nopush来控制它,并且只有在启用了sendfile之后才生效。 123 # 启用它之后,数据包会累计到一定大小之后才会发送,减小了额外开销,提高网络效率 124 125 tcp_nodelay on; 126 # TCP_NODELAY也是一个socket选项,启用后会禁用Nagle算法,尽快发送数据,某些情况下可以节约200ms 127 # Nagle算法原理是:在发出去的数据还未被确认之前,新生成的小数据先存起来,凑满一个 MSS 或者等到收到确认后再发送 128 # Nginx 只会针对处于keep-alive状态的TCP连接才会启用tcp_nodelay 129 130 keepalive_timeout 65; 131 # 长连接的时间限制,http是基于tcp实现的,这个参数用于设置tcp长连接的时间长度 132 # 客户端可以设置http服务要不要走长连接,通过设置请求头Connection=keep-alive实现的,http1.0默认是关闭的,http1.1默认是打开的 133 # 谷歌浏览器同时最多有6个tcp连接 134 # keepalive_timeout时间不能设置太长,因为太长会长时间占用tcp连接不释放,导致服务器的tcp连接不够用;也不能太短,如果太短会导致一些大文件上传接口因为上传一半而中断; 135 136 #################################################################################### 137 # http_proxy 设置,client相关配置 # 138 #################################################################################### 139 140 client_max_body_size 10m; 141 # 允许客户端请求的最大单文件字节数限制。如果有上传较大文件的需求,尽量设置大一些 142 143 client_body_buffer_size 128k; 144 # 缓冲区代理用户端请求的最大字节数 145 146 client_header_timeout 60; 147 # 指定等待client发送一个请求头的超时时间,仅当在一次read中,没有收到请求头,才会算成超时。如果在超时时间内,client没发送任何东西,nginx返回HTTP状态码408(“Request timed out”) 148 149 client_body_timeout 60; 150 # 该指令设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后,nginx返回HTTP状态码408(“Request timed out”) 151 152 #################################################################################### 153 # http_proxy 设置,server相关配置 # 154 #################################################################################### 155 156 proxy_connect_timeout 60; 157 # 该指令设置与upstream server的连接超时时间,有必要记住,这个超时不能超过75秒 158 159 proxy_send_timeout 75; 160 # 这个指定设置了发送请求给upstream服务器的超时时间。超时设置不是为了整个发送期间,而是在两次write操作期间。如果超时后,upstream没有收到新的数据,nginx会关闭连接 161 162 proxy_read_timeout 75; 163 # 该指令设置与代理服务器的读超时时间。它决定了nginx会等待多长时间来获得请求的响应。这个时间不是获得整个response的时间,而是两次reading操作的时间,默认值60s 164 165 proxy_upstream_fail_timeout 10; 166 # Upstream模块下server指令的参数,设置了某一个upstream后端失败了指定次数(max_fails)后,该后端不可操作的时间,默认为10秒 167 168 proxy_buffer_size 4k; 169 # 设置代理服务器(nginx)从后端realserver读取并保存用户头信息的缓冲区大小,默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点 170 171 proxy_buffers 4 32k; 172 # proxy_buffers缓冲区,4个缓存,每个大小限制为32k。 173 174 proxy_busy_buffers_size 64k; 175 # 高负荷下缓冲大小(proxy_buffers*2) 176 177 proxy_temp_file_write_size 64k; # 默认为1024M 178 # 当proxy_buffers放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M 179 # 它与proxy_cache没有关系,大于这个值,将从upstream服务器传回。设置为0禁用 180 181 proxy_temp_path /usr/local/nginx/proxy_temp 1 2; 182 # 指定缓存写到那个目录 183 184 #################################################################################### 185 # gzip压缩功能设置 # 186 #################################################################################### 187 188 gzip on; 189 # 开启gzip压缩输出,减少网络传输,客户端通过设置请求头Accept-Encoding=gzip, deflate, br来支持gzip压缩 190 191 gzip_static on; 192 # nginx对于静态文件的处理模块,该模块可以读取预先压缩的gz文件,这样可以减少每次请求进行gzip压缩的CPU资源消耗。 193 # 该模块启用后,nginx首先检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容 194 195 gzip_disable "msie[1-6]."; 196 # IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死,为了确保其它的IE6版本不出问题,所以建议加上gzip_disable的设置 197 198 gzip_min_length 1k; 199 # 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大 200 201 gzip_buffers 4 16k; 202 # 设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存 203 204 gzip_http_version 1.0; 205 # 用于识别http协议的版本,早期的浏览器不支持Gzip压缩,用户就会看到乱码,所以为了支持前期版本加上了这个选项。 206 # 如果你用了Nginx的反向代理并期望也启用Gzip压缩的话,由于末端通信是 http/1.0,故请设置为 1.0 207 208 gzip_comp_level 6; 209 # gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu) 210 211 gzip_types text/html text/plain text/css text/javascript application/json application/javascript application/x-javascript 212 application/xml; 213 # 匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的 214 215 gzip_vary on; 216 # 和http头有关系,会在响应头加个Vary:Accept-Encoding,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据 217 218 gzip_proxied any 219 # Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头 220 221 ################################################################################## 222 # FastCGI 设置,为了保证Nginx下PHP环境的高速稳定运行,需要添加一些FastCGI优化指令 # 223 ################################################################################## 224 225 fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; 226 # 为FastCGI缓存指定一个文件路径、目录结构等级、关键字区域存储时间和非活动删除时间 227 228 fastcgi_connect_timeout 300; 229 # 指定连接到后端FastCGI的超时时间 230 231 fastcgi_send_timeout 300; 232 # 指定向FastCGI传送请求的超时时间,这个值是已经完成两次握手后向FastCGI传送请求的超时时间 233 234 fastcgi_read_timeout 300; 235 # 指定接收FastCGI应答的超时时间,这个值是已经完成两次握手后接收FastCGI应答的超时时间 236 237 fastcgi_buffer_size 64k; 238 # 用于指定读取FastCGI应答第一部分需要多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers选项指定的缓冲区大小 239 240 fastcgi_buffers 4 64k; 241 # 指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求。 242 # 如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存;如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中。 243 # 一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“16 16k”、“4 64k”等 244 245 fastcgi_temp_file_write_size 128k; 246 # 表示在写入缓存文件时使用多大的数据块,默认值是fastcgi_buffers的两倍 247 248 fastcgi_cache TEST; 249 # 表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生 250 251 fastcgi_cache_valid 200 302 1h; 252 # 指定code为200,302的响应缓存为一小时 253 254 fastcgi_cache_valid 301 1d; 255 # 指定code为301的缓存有效时间为1天 256 257 fastcgi_cache_valid any 1m; 258 # 其它缓存有效时间都为1分钟 259 260 ################################################################################## 261 # 设定负载均衡后台服务器列表 # 262 ################################################################################## 263 264 upstream backend { 265 ip_hash; # 默认为round-robin 266 # 负载均衡处理方式,一共有三种方式: 267 # (1)round-robin(轮训请求方式) 268 # (2)ip_hash(回话持久化方式,这个方法保证从同一个客户端发起的请求总是定向到同一台服务器) 269 # (3)least_conn(最少连接方式,找连接最少的服务进行处理) 270 271 server 192.168.10.100:8080 max_fails=2 fail_timeout=30s weight=2; 272 server 192.168.10.101:8080 max_fails=2 fail_timeout=30s weight=3; 273 server 192.168.10.101:8080 backup 274 server 192.168.10.101:8080 down; 275 # weight设置每个服务的命中几率,默认是1; 276 # backup表示备份服务,只有所有的非备份不能使用时,会启动该服务,down表示当前服务永远不参与负载; 277 # max_fails表示容许请求失败的次数,当超过该次数时将暂停一定时间(fail_timeout) 278 } 279 280 ################################################################################## 281 # server虚拟主机配置 # 282 ################################################################################## 283 284 server { 285 ############################################ 286 # 基本配置 # 287 ############################################ 288 289 listen 80 default_server; # 默认为80 290 # 监听端口设置,小于1024的要以root启动, 291 # default_server表示如果找不到对应端口的server_name,则默认走这个匹配 292 293 server_name itoatest.example.com; 294 # 一个nginx可以配置多个server,nginx通过检查请求header中host来匹配每个server的server_name决定走哪个server, 295 # 如果没有任何一个server可以匹配,则会选择第一个server做匹配。默认匹配可以通过listen中添加defalut_server来改变。 296 # server_name有四种匹配方式: 297 # (1)精确匹配(itoatest.example.com) 298 # (2)星号开头的最长的通配符名称(*.example.org) 299 # (3)星号结束的最长的通配符名称(mail.*) 300 # (4)正则表达式匹配(~^wwwd+.example.net$,正则表达式必须以~开头) 301 302 root /apps/oaapp; 303 # 见下文location讲解 304 305 allow 223.252.218.196; 306 allow 59.111.28.48/32; 307 # allow表示允许某个ip或ip段访问 308 309 deny all 310 # deny表示禁止某个ip或者ip段访问 311 312 error_page 500 502 503 504 /50x.html; 313 error_page 403 http://example.com/forbidden.html; 314 # 这个参数可以为错误代码指定相应的错误页面 315 316 charset utf-8; 317 # 设置http头信息的charset编码 318 319 if ($request_method = POST) { 320 return 405; 321 } 322 # 关于if的使用请看下文[Nginx中如何使用变量?] 323 324 ############################################ 325 # location特定的URL对应的一系列配置项 # 326 ############################################ 327 location /i/ { # 关于location中的路径匹配规则以及匹配优先级请看下文[Nginx中location部分URL如何匹配?] 328 root /apps/oaapp; 329 #alias /apps/oaapp/; 330 # root和alias都可以用来指定请求资源的真实路径。 331 # 区别是root最后得到的资源地址是root的值加上location的值,而alias正如其名,alias指定的路径是location的别名,不管location的值怎么写,资源的真实路径都是 alias 指定的路径。 332 # 比如当访问http://itoatest.example.com/i/hello.gif这个地址时,如果是root,资源的真实路径是/apps/oaapp/i/hello.gif;如果是alias真实路径是/apps/oaapp/hello.gif; 333 # alias只能作用在location中,而root可以存在server、http和location中 334 # alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无 335 336 index index.jsp index.html index.htm; 337 # 当用户请求的是http://itoatest.example.com/i/这个地址时,就会自动在root配置指令指定的文件系统目录下依次寻找 index.jsp 和 index.html,index.htm这三个文件,直到找到一个并返回 338 339 autoindex on; # 默认为off 340 # 当index指定的文件都找不到时,如果开启autoindex,那么则会生成一个root所指目录下的“目录索引”的html并返回,如果没有开启,则会返回forbidden 341 342 autoindex_exact_size off # 默认为on 343 # 只有在autoindex开启时才起作用,默认为on,显示出文件的确切大小,单位是bytes。改为off后,显示出文件的大概大小,单位是kB或者MB或者GB 344 345 autoindex_localtime on # 默认为off 346 # 只有在autoindex开启时才起作用,默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间 347 348 proxy_pass http://backend; 349 # 请求转向某个upstream定义的负载均衡的服务器列表,如果只有一台服务器的话,也可以直接写成proxy_pass http://ip:port; 350 351 rewrite ^/i/(.*) /$1 break; 352 # rewrite 的作用是修改 $uri,具体细节请看下文[rewrite如何重写url?] 353 354 proxy_redirect off; # 默认是default 355 proxy_redirect http://192.168.10.101:8080/i/wuman/ http://itoatest.example.com/i/wuman/ 356 # 如果需要修改从被代理服务器传来的应答头中的"Location"和"Refresh"字段,可以用这个指令设置,分为三种情况: 357 #(1)proxy_redirect off表示不修改服务端的redirect地址 358 #(2)proxy_redirect default 将根据location和proxy_pass的设置来决定 359 #(3)可以自己设置不同的替换规则 360 361 proxy_set_header Host $host; #默认是$proxy_host 362 # 可以通过三个变量对Host进行设置: 363 #(1)$proxy_host,表示是反向代理后的host,就是proxy_pass后面跟的host 364 # (2) $host首先从请求头中获取Host值,如果没有则选择server_name 365 # (3) $http_host是直接从请求头中获取,所以可能为空,如果是非80/443端口的时候,$http_host = $host:$port 366 367 proxy_set_header X-Real-IP $remote_addr; 368 # 由于在客户端和web服务器之间增加了中间层,因此web服务器无法直接拿到客户端的ip,通过$remote_addr变量拿到的将是反向代理服务器的ip地址; 369 # 所以我们可以设置一个请求头X-Real-IP,通过获取这个请求头就可以拿到客户端的真实ip 370 371 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 372 # 上述的意思增加一个$proxy_add_x_forwarded_for到X-Forwarded-For里去,注意是增加,而不是覆盖 373 # 如果每次代理都使用上述配置,那么X-Forwarded-For可以获取到经过多次代理后的客户多IP以及多层代理nginx的IP:IP0, IP1, IP2... 374 # 所以proxy_set_header也是获取真实客户端ip的一种方法 375 376 proxy_set_header X-Forwarded-Proto https; 377 # 请求标头可帮助您识别客户端与您的负载均衡器连接时所用的协议,并随后将标题传递到您的服务器 378 379 proxy_set_header X-Forwarded-Host $host 380 # 可以帮助您识别客户端与您的负载均衡器连接时所用的host,并随后将标题传递到您的服务器 381 382 proxy_set_header X-Forwarded-Host $port 383 # 可以帮助您识别客户端与您的负载均衡器连接时所用的port,并随后将标题传递到您的服务器 384 385 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; # 默认是error timeout 386 # 指定在什么情况下将请求应传递到下一个服务器,如果设置为off表示在任何情况下都不需要传递 387 # error表示发生错误时,将请求传递到下一个服务器 388 # timeout表示发生请求或者响应超时时,将请求传递给下一个服务器 389 # invalid_header表示服务器返回空响应或无效响应时,将请求传递给下一个服务器 390 # http_code表示服务器返回对应的code时将请求传递到下一个服务器 391 392 proxy_next_upstream_timeout 30 # 默认是0 393 # 限制请求可以传递到下一个服务器的时间,0表示关闭限制 394 395 proxy_next_upstream_tries 2 # 默认为0 396 # 限制将请求传递到下一个服务器的可能尝试次数, 0值关闭此限制 397 398 } 399 400 location ~ .*.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ 401 { 402 root /apps/oaapp; 403 404 expires 7d; 405 # 对于站点中不经常修改的静态内容(如图片,JS,CSS),可以在服务器中设置expires过期时间,控制浏览器缓存,达到有效减小带宽流量,降低服务器压力的目的 406 } 407 408 location = /50x.html { 409 root html; 410 } 411 412 location = /video { 413 directio 4m; # 该路径下所有大于4M的文件不直接从磁盘读取,不走缓存 414 # Direct I/O是文件系统的一个功能,它允许程序绕过内核缓存,直接在硬盘上读写数据 415 # 这可以充分利用CPU频数,改善缓存的有效性,Directo I/O适用于访问率少的数据。这些数据不需要缓存在任何位置 416 # 在http, server和location当中都可以定义 417 # 如果某个请求是通过directo I/O,那么这个请求不能使用sendfile功能 418 } 419 } 420 }
nginx中location部分url如何匹配?
location主要是匹配url中除去server_name(主机名)后的部分,其中关于url的匹配规则有以下几种:
- 精确匹配:以“=”开头表示精确匹配
- 开头匹配:^~ 表示uri以某个常规字符串开头,不是正则匹配
- 区分大小写的正则匹配:~开头表示区分大小写的正则匹配
- 不区分大小写的正则匹配:~* 开头表示不区分大小写的正则匹配
- 通用匹配:匹配url的前面部分
对于上述五类匹配,它们之间的匹配顺序和优先级关系如下:
- 不同类型之间匹配和location的顺序无关,只和优先级有关,各种匹配规则的优先级关系是: [精确匹配] > [开头匹配] > [正则匹配] > [通用匹配];
- 除了通用匹配,开头匹配以外,相同类型的匹配优先级只和顺序有关,排在前面的优先匹配;
- 通用匹配和开头匹配的优先级与通用匹配的最长字符串有关,通用字符串越长,匹配优先级越高;
下面是我设置的几个location,并测试和验证以上匹配规则:
1 server { 2 listen 80 default_server; 3 server_name dev.zdp.com; 4 5 # 通用匹配 [匹配规则0] 6 location / 7 { 8 return 302 https://dashboard.youdata.com; 9 } 10 11 # 通用匹配 [匹配规则1] 12 location /hello 13 { 14 return 302 https://dashboard.youdata.com; 15 } 16 17 # 通用匹配 [匹配规则2] 18 location /hello/no 19 { 20 return 302 https://dev.youdata.com; 21 } 22 23 # 不区分大小写的正则匹配 [匹配规则3] 24 location ~* /hello/y[a-e][a-z][1-9] 25 { 26 return 302 https://test.youdata.com; 27 } 28 29 # 区分大小写的正则匹配 [匹配规则4] 30 location ~ /hello/y[A-E][E-Z][1-9] 31 { 32 return 302 https://pre.youdata.com; 33 } 34 35 # 区分大小写的正则匹配 [匹配规则5] 36 location ~ /hello/y[a-e][e-z] 37 { 38 return 302 https://pre163.youdata.com; 39 } 40 41 # 开头匹配 [匹配规则6] 42 location ^~ /hello/yes 43 { 44 return 302 https://youdata.netease.com; 45 } 46 47 # 开头匹配 [匹配规则7] 48 location ^~ /hello/yesno 49 { 50 return 302 https://youdata.163.com; 51 } 52 53 # 精确匹配 [匹配规则8] 54 location = /hello 55 { 56 return 302 https://www.baidu.com; 57 } 58 59 }
location用例测试:
- “http://dev.zdp.com/hello” ——- 精确匹配优先,命中[匹配规则8]
- “http://dev.zdp.com/hello/yesnoOk” ——- 开头匹配优先,开头匹配同时满足条件时,长优先,命中[匹配规则7]
- “http://dev.zdp.com/hello/yesOk” ——- 开头匹配优先,命中[匹配规则6]
- “http://dev.zdp.com/hello/yaz” ——- 正则匹配,命中[匹配规则5]
- “http://dev.zdp.com/hello/yAZ3” ——- 正则匹配,按照location顺序匹配,命中[匹配规则3]
- “http://dev.zdp.com/hello/no” ——- 通用匹配,按照匹配长度优先,命中[匹配规则2]
- “http://dev.zdp.com/hello/Ok” ——- 通用匹配,命中[匹配规则1]
- “http://dev.zdp.com/everyone” ——- 通用匹配,所有其它匹配不满足时,命中[匹配规则0]
nginx中rewrite命令如何重写url?
rewrite功能就是,使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。rewrite只能放在server{},location{}中,并且只能对域名后边的除去传递的参数外的字符串起作用,例如:
http://dev.zdp.com/a/we/index.php?id=1&u=str => rewrite只能对/a/we/index.php部分重写
重写用法:
server { rewrite 规则 定向路径 重写flag; } location { rewrite 规则 定向路径 重写flag; }
rewrite的执行顺序
- 执行server块的rewrite指令;
- 执行location匹配;
- 执行选定的location中的rewrite指令,如果location中rewrite指令没有break的flag,则会根据当前rewrite路径重新匹配location;
- 如果其中某步URI被重写,则重新循环执行1-3,直到找到真实存在的文件,循环最多不会超过10次;
rewrite的flag标志
- last: 停止处理当前location中的ngx_http_rewrite_module指令集(rewrite,return等),并开始重新搜索与更改后的URI相匹配的location
- break : 停止处理当前location中的ngx_http_rewrite_module指令集(rewrite,return等),不会重新搜索
- redirect : 返回302临时重定向,地址栏会显示跳转后的地址
- permanent : 返回301永久重定向,地址栏会显示跳转后的地址
- default: 默认标志,继续会处理当前location中的ngx_http_rewrite_module指令集(rewrite,return等),如果没有return,会开始重新搜索与更改后的URI相匹配的location
rewrite的测试用例
1 server { 2 listen 80 default_server; 3 server_name dev.zdp.com; 4 5 set $flag="default"; 6 7 # 当我们访问http://dev.zdp.com/test1/helloworld时,对于不同flag变量返回的结果如下: 8 # 当$flag="default"时,会执行后续的ngx_http_rewrite_module命令,所以会重定向到https://newke.com; 9 # 当$flag="last"时,不会执行后续的ngx_http_rewrite_module命令,但是会重新匹配location,所以重定向到https://www.baidu.com; 10 # 当$flag="break"时,不会执行后续的ngx_http_rewrite_module命令,所以没有找到匹配,失败 11 location /test1 12 { 13 rewrite ^/test1/([^/]+?) /test2/$1 $flag; 14 return 302 https://newke.com; 15 } 16 17 location /test2 18 { 19 return 302 https://www.baidu.com; 20 } 21 22 location / 23 { 24 25 # 访问 /permanent.html 的时候,页面直接302定向到https://www.baidu.com 26 rewrite /permanent.html https://www.baidu.com redirect; 27 28 # 把 /html/*.html => /post/*.html ,301定向 29 rewrite ^/html/(.+?).html$ /post/$1.html permanent; 30 31 # 把 /search/key => /search.html?keyword=key 32 rewrite ^/search/([^/]+?)(/|$) /search.html?keyword=$1 permanent; 33 } 34 }
nginx中if判断如何使用?
只是上面的简单重写很多时候满足不了需求,比如需要判断当文件不存在时、当路径包含xx时等条件,则需要用到if
Nginx中if语法为:if(condition){…},对给定的条件condition进行判断。如果为真,大括号内命令将被执行
if判断规则
- 当表达式只是一个变量时,如果值为空或任何以0开头的字符串都会当做false
- 直接比较变量和内容时,使用=或!=
- ~正则表达式匹配,~*不区分大小写的匹配,!~区分大小写的正则表达式不匹配,满足条件返回true
- -f和!-f用来判断是否存在文件
- -d和!-d用来判断是否存在目录
- -e和!-e用来判断是否存在文件或目录
- -x和!-x用来判断文件是否可执行
if使用举例
if条件中一般会使用到一些变量,这些变量有些是用户定义的,有些是系统本身存在的,关于变量相关内容请看下文[Nginx中如何使用变量?]
1 server { 2 if ($http_user_agent ~ MSIE) { 3 rewrite ^(.*)$ /msie/$1 break; 4 } 5 # 如果UA包含"MSIE",rewrite请求到/msid/目录下 6 7 if ($http_cookie ~* "id=([^;]+)(?:;|$)") { 8 set $id $1; 9 } 10 # 如果cookie匹配正则,设置变量$id等于正则引用部分 11 12 if ($request_method = POST) { 13 return 405; 14 } 15 # 如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302 16 17 if ($slow) { 18 limit_rate 10k; 19 } 20 # 限速,$slow可以通过 set 指令设置 21 22 if (!-f $request_filename){ 23 break; 24 proxy_pass http://127.0.0.1; 25 } 26 # 如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查 27 28 if ($args ~ post=140){ 29 rewrite ^ http://example.com/ permanent; 30 } 31 # 如果query string中包含"post=140",永久重定向到example.com 32 33 location ~* .(gif|jpg|png|swf|flv)$ { 34 valid_referers none blocked www.jefflei.com www.leizhenfang.com; 35 if ($invalid_referer) { 36 return 404; 37 } 38 # 防盗链 39 } 40 }
nginx变量如何使用?
Nginx也可以使用变量,变量分为系统变量和自定义变量
变量特点
- Nginx变量的创建只能发生在Nginx配置加载的时候,或者说Nginx启动的时候;
- Nginx变量的赋值操作则只会发生在请求实际处理的时候;
- 每个请求都有所有变量的独立副本,或者说都有各变量用来存放值的容器的独立副本,它们之间的值彼此互不干扰;
自定义变量
自定义变量通过set命令初始化和赋值,变量名前需要加$符号作为区分
1 # 设置变量$a = "helloworld"; 2 set $a hello world; 3 4 # 设置变量$b = "helloworld, helloworld"; 5 set $b "$a, $a";
系统变量
Nginx中的系统变量如下:
1 $args # 这个变量等于请求行中的参数,同$query_string 2 $content_length # 请求头中的Content-length字段。 3 $content_type # 请求头中的Content-Type字段。 4 $document_root # 当前请求在root指令中指定的值。 5 $host # 请求主机头字段,如果不存在则为服务器名称。 6 $http_user_agent # 客户端agent信息 7 $http_cookie # 客户端cookie信息 8 $limit_rate # 这个变量可以限制连接速率。 9 $request_method # 客户端请求的动作,通常为GET或POST。 10 $remote_addr # 客户端的IP地址。 11 $remote_port # 客户端的端口。 12 $remote_user # 已经经过Auth Basic Module验证的用户名。 13 $request_filename # 当前请求的文件路径,由root或alias指令与URI请求生成。 14 $scheme # HTTP方法(如http,https)。 15 $server_protocol # 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。 16 $server_addr # 服务器地址,在完成一次系统调用后可以确定这个值。 17 $server_name # 服务器名称。 18 $server_port # 请求到达服务器的端口号。 19 $request_uri # 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。 20 $uri # 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。 21 $document_uri # 与$uri相同。
nginx中一些常用的命令
- nginx -t 检查配置是否可用
- nginx -s reload 重启nginx
参考文献
- nginx服务器安装及配置文件详解
- pid 文件有哪些作用?
- nginx access_log日志
- Nginx错误日志(error_log)配置及信息详解
- 本博客 Nginx 配置之性能篇
- Nginx 启用gzip网站内容压缩
- nginx做负载均衡器以及proxy缓存配置
- NGINX配置超时时间
- CGI、FastCGI和PHP-FPM关系图解
- 优化Nginx中FastCGI参数的实例
- Nginx服务器性能优化的三大方面
- Nginx配置upstream实现负载均衡
- Nginx配置中的 root 与 alias 指令的区别
- Nginx 配置指令的执行顺序(六)
- 关于nginx中host, server_name, http_host的区别
- 使用nginx后如何在web应用中获取用户ip及原理解释
- HTTP 标头和 传统负载均衡器
- nginx proxy_next_upstream
- nginx配置location总结及rewrite规则写法
- nginx配置url重写
- 搞懂nginx的rewrite模块
转载:https://blog.csdn.net/zdplife/article/details/79563060