Nginx使用经验总结,好记性不比烂笔头(键盘)
- Nginx
- 2021-09-09
- 1290热度
- 0评论
基础知识
- 配置文件中以
#
开始的行,或者是前面有若干空格或者 TAB,然后再跟#
的行,都被认为是注释 - 在 nginx.conf 中,包含若干配置项。每个配置项由配置指令和指令参数 2 个部分构成。指令参数也就是配置指令对应的配置值。
- 配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引起来。
- 指令的参数使用一个或者多个空格或者 TAB 字符与指令分开。指令的参数有一个或者多个 TOKEN 串组成。TOKEN 串之间由空格或者 TAB 键分隔。
- 这个是一个简单配置项:error_page 500 502 503 504 /50x.html;
- 使用if指令时,if和{}中间需要一个空格;
Server语句
每个虚拟主机一个对应的 server 配置项,配置项里面包含该虚拟主机相关的配置。在提供 mail 服务的代理时,也可以建立若干 server,每个 server 通过监听的地址来区分。
- listen,用于指定虚拟机的监听端口(listen 80;)
- index,用于指定是首页文件(index index.html index.htm index.php;)
- root,用于指定虚拟机目录(root /data/www/w3cschool;)
- location,用于对收到的不同的链接的请求进行不同的处理,如下是设定指定类型的链接的请求的过期时间为1小时...
#JS和CSS缓存时间设置 location ~ .*.(js|css)?$ { expires 1h; } #定义访问php脚本时,将会执行本location{}部分指令 location ~ .php$ { proxy_pass http://127.0.0.1; //proxy_pass后面指定要访问的url链接,用proxy_pass实现代理。 }
- access_log,指定网站访问日志的存储路径,log_format 指令用于设置日志的记录格式,值为Off则关闭。
- error_page,当出现指定状态码是时,返回指定页面(error_page 500 502 503 504 /50x.html; //当状态码为500、502、503、504时,则访问50x.html)
SSL相关配置
### 以下为ssl相关配置
ssl_certificate cert.pem; //指定pem文件路径
ssl_certificate_key cert.key; //指定key文件路径
ssl_session_cache shared:SSL:1m; //指定session cache大小
ssl_session_timeout 5m; //指定session超时时间
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; //指定ssl协议
ssl_ciphers HIGH:!aNULL:!MD5; //指定ssl算法
ssl_prefer_server_ciphers on; //优先采取服务器算法s
全局变量
- $args,$query_string 请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
- $content_length http请求信息里面的“Content-Length”
- $conten_type http请求信息里面的“Content-Type”
- $document_root nginx虚拟主机配置文件中的root参数对应的值
- $document_uri 当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的参数。
- $host 主机头,也就是域名。
- $http_user_agent 客户端的详细信息,也就是浏览器的标识。
- $http_cookie 客户端的cookie信息
- $limit_rate 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示为0.
- $remote_addr 客户端的公网ip
- $remote_port 客户端的port
- $remote_user 如果nginx有配置认证,该变量代表客户端认证的用户名
- $request_body_file 做反向代理时发给后端服务器的本地资源的名称
- $request_uri 请求的连接,包括$document_uri和$args
- $request_method 请求的方法,GET、POST等
- $scheme 请求的协议,如ftp,http,https
- $server_protocol 客户端请求资源用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0
- $server_addr 服务器ip地址
- $server_name 服务器的主机名
- $server_port 服务器的端口号
- $uri 和$document_uri相同
- $http_referer 客户端请求时的referer,通俗讲就是该请求时通过哪个连接跳进来的,也就是我们在百度搜一个关键字,然后可以点击条目跳进一个网站,点击的那个链接就是你的referer,用curl -e可以指定。
IF语句
在server和location两种配置块内可以使用nginx的IF条件判断,当条件成立时执行指定的指令,条件可以为以下几种:
1.正则表达式
# ~ 为区分大小写匹配;
# ~* 为不区分大小写匹配;
# !~ 不匹配某个区分大小写的正则;
# !~* 不匹配某个不区分大小写的正则;
#下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /nginx-ie/$1 break;
}
整个正则表达式字符串一般不需要加引号,但如果含有右花括号「}」或者分号「;」字符时,必须要给整个正则表达式添加引号。
2.文件目录匹配
#-f和!-f判断是否存在文件
# -d和!-d判断是否存在目录
#-e和!-e判断是否存在文件或目录
#-x和!-x判断文件是否可执行
#设定nginx在文件和目录不存在的时候重定向:
if (!-e $request_filename) {
proxy_pass http://127.0.0.1/;
}
Return语句
该指令一般用于对请求的客户端直接返回响应状态码。在该作用域内return后面的所有nginx配置都是无效的。 可以使用在server、location以及if配置中。 除了支持跟状态码,还可以跟字符串或者url链接,该语句只会影响当前所在的代码块。
#301重定向,直接带server块内使用,后面的所有指令都不会执行
return 301 https://nicen.cn$request_uri;
#输出HTML也行
return 200 "<html><script>window.location.href='//$host$request_uri';</script></html>";
Deny语句
Deny用于拒绝访问,可在sever和location中使用
deny all; #拒绝访问
allow 208.97.167.194; #允许指定IP访问
Rewrite 命令
- 它可以用在server, location 和IF条件判断块中,格式为:rewrite 正则表达式 替换目标 flag标记
- flag标记可以用以下几种格式
last – 停止当前这个请求,并根据rewrite匹配的规则重新发起一个请求。新请求又从第一阶段开始执行…
break – 中止Rewirte,不在继续匹配,相对last,break并不会重新发起一个请求,只是跳过当前的rewrite阶段,并执行本请求后续的执行阶段…
redirect – 重定向到指定的链接,返回临时重定向的HTTP状态302
permanent – 重定向到指定的链接,返回永久重定向的HTTP状态301
Set语句
set 指令是用于定义一个变量,并且赋值,可在server、location、if代码块中使用。
Nginx配置文件中文详解:https://www.w3cschool.cn/nginx/nginx-d1aw28wa.html
try_files命令
try_files是nginx中http_core核心模块所带的指令,主要是能替代一些rewrite的指令,提高解析效率。
- 它可以用在server, location 和IF条件判断块中,格式为:rewrite 正则表达式 替换目标 flag标记
- 按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理,如果给出的file都没有匹配到,则重新请求最后一个参数给定的uri,就是新的location匹配;
location / { try_files $uri $uri/ /index.php?$query_string; } location ~ .*.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; }
当用户请求 http://localhost/example 时,这里的 $uri 就是 /example。
try_files 会到硬盘里尝试找这个文件。如果存在名为 /root/example(其中root 是项目代码安装目录)的文件,就直接把这个文件的内容发送给用户。
显然,目录中没有叫 example 的文件。然后就看 uri/,增加了一个 /,也就是看有没有名为 /root/example/ 的目录。
又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到 http://localhost/index.php
这个请求会被 location ~ .*.(php|php5)?$ { ... } catch 住,也就是进入 FastCGI 的处理程序。而具体的 URI 及参数是在 REQUEST_URI 中传递给 FastCGI 和 PHP 程序的,因此不受 URI 变化的影响。
break命令
该指令用于中断当前相同作用域中的其他 Nginx 配置。
与该指令处于同一作用域的 Nginx 配置中,位于它前面的指令配置生效,位于后面的指令配置无效。
Nginx 服务器在根据配置处理请求的过程中遇到该指令时,回到上一层作用域继续向下读取配置。该指令可以在 server 块和 location 块以及 if 块中使用,其语法结构为:break;
问题总结
- location的匹配存在优先级的问题,前面比后面先匹配;绝对比正则先匹配。往往重写不生效时就是没有匹配到指定的块。(例如重写一个PHP文件的请求时,在PHP-CGI块的后面,所以一直返回404)。
- 修改配置文件后,一定要重启NGINX。
正向代理和反向代理
在Nginx的环境下,通过不同协议访问时可代理http、https等不同的协议。
正向代理:局域网的主机访问互联网的资源;(proxy_pass指令,目标为外网地址)
反向代理:互联网主机访问局域网内某台主机的资源(proxy_pass指令,目标为局域网地址)。
反向代理websocket时,默认情况下,如果代理服务器在 60 秒内没有传输任何数据,连接将被关闭。
1.proxy_hide_header field 指令
其中,field为需要隐藏的头域。该指令可以在 http 块、server 块或者 location 块中进行配置。
2.proxy_pass_header field 指令
默认情况下,Nginx 服务器在发送响应报文时,报文头中不包含「Date」、「Server」、「X-Accel」等来自被代理服务器的头域信息。该指令可以设置这些头域信息以被发送,其语法结构为:
3.proxy_pass_request_body 指令
该指令用于配置是否将客户端请求的请求体发送给代理服务器,其语法结构为: proxy_pass_request_body on|off;默认设置为开启(on),开关可以在 http 块、server 块或者 location 块中进行配置。
4.proxy_pass_request_headers on|off
该指令用于配置是否将客户端请求的请求头发送给代理服务器,其语法结构为:
5.proxy_set_header field value 指令
该指令可以更改 Nginx 服务器接收到的客户端请求的请求头信息,然后将新的请求头发送给被代理的服务器,field为指定的字段,value为字段值。
6.proxy_set_body value
该指令可以更改 Nginx 服务器接收到的客户端请求的请求体信息,然后将新的请求体发送给被代理的服务器;
7.proxy_bind address
官方文档中对该指令的解释是,强制将与代理主机的连接绑定到指定的 IP 地址,通俗来讲就是,在配置了多个基于名称或者基于 IP 的主机的情况下,如果我们希望代理连接由指定的主机处理,就可以使用该指令进行配置,address为指定的IP;
8.proxy_connect_timeout time
指令,该指令配置 Nginx 服务器与后端被代理服务器尝试建立连接的超时时间。默认为60s;
9.proxy_read_timeout time
该指令配置 Nginx 服务器向后端被代理服务器组发出 read 请求后等待响应的超时时间,time默认为60s;
10.proxy_send_timeout time
该指令配置 Nginx 服务器向后端被代理服务器组发出 write 请求后等待响应的超时时间,time默认为60s;
11.proxy_http_version version
该指令用于设置用于 Nginx 服务器提供代理服务的 HTTP 协议版本,默认设置为 1.0 版本,1.1 版本支持 upsteam 服务器组设置中的 keepalive 指令;
12.proxy_method method
该指令用于设置 Nginx 服务器请求被代理服务器时使用的请求方法,一般为 POST 或者 GET。设置了该指令,客户端的请求方法将被忽略。
13.proxy_ignore_client_abort on | off
该指令用于设置在客户端中断网络请求时,Nginx 服务器是否中断对被代理服务器的请求,默认设置为 off,当客户端中断网络请求时,Nginx 服务器中断对被代理服务器的请求。
14.proxy_ignore_headers field ...
该指令用于设置一些 HTTP 响应头中的头域,Nginx 服务器接收到被代理服务器的响应数据后,不会处理被设置的头域。其中,field为要设置的 HTTP 响应头的头域,例如「X-Accel-Redirect」、「X-Accel-Expires」、「Expires」、「Cache-Control」或「Set-Cookie」等。
15.proxy_redirect 指令
该指令用于修改被代理服务器返回的响应头中的 Location 头域和「Refresh」头域,与 proxy_pass 指令配合使用。比如,Nginx 服务器通过 proxy_pass 指令将客户端的请求地址重写为被代理服务器的地址,那么 Nginx 服务器返回给客户端的响应头中「Location」头域显示的地址就应该和客户端发起请求的地址相对应,而不是代理服务器直接返回的地址信息,否则就会出问题。该指令解决了这个问题,可以把代理服务器返回的地址信息更改为需要的地址信息。其语法结构为:
proxy_redirect redirect replacement;
proxy_redirect default;
proxy_redirect off;
redirect,匹配「Location」头域值的字符串,支持变量的使用和正则表达式。
replacement,用于替换redirect变量内容的字符串,支持变量的使用。
对于第 1 个结构,>假设被代理服务器返回的响应头中「Location」头域为:
Location: http://localhost:8081/proxy/some/uri/
该指令设置为:
proxy_redirect http://localhost:8081/proxy/ http://myweb/frontend/;
Nginx 服务器会将「Location」头域的信息更改为:
Location: http://myweb/frontend//some/uri/
这样,客户端收到的响应信息头部中的「Location」头域也就被更改了。
结构 2 使用 default,代表使用 location 块的uri变量作为replacement,并使用 proxy_pass 变量作为redirect。请看下面两段配置,它们的配置效果是等同的。
location /server/
{
proxy_pass http://proxyserver/source/;
proxy_redirect default;
}
location /server/
{
proxy_pass http://proxyserver/source/;
proxy_redirect http://proxyserver/source/ /server/;
}
使用结构 3 可以将当前作用域下所有的 proxy_redirect 指令配置全部设置为无效。
17.proxy_intercept_errors on | off;
该指令用于配置一个状态是开启还是关闭。在开启该状态时,如果被代理的服务器返回的 HTTP 状态代码为 400 或者大于 400,则 Nginx 服务器使用自己定义的错误页(使用 error_page 指令);如果是关闭该状态,Nginx 服务器直接将被代理服务器返回的 HTTP 状态返回给客户端。
18.proxy_headers_hash_ max _size size
该指令用于配置存放 HTTP 报文头的哈希表的容量,size 为 HTTP 报文头哈希表的容量上限,默认为 512 个字符,即:proxy_headers_hash_ max _size 512;Nginx 服务器为了能够快速检索 HTTP 报文头中的各项信息,比如服务器名称、MIME 类型、请求头名称等,使用哈希表存储这些信息。Nginx 服务器在申请存放 HTTP 报文头的空间时,通常以固定大小为单位申请,该大小由 proxy_headers_hash_bucket_size 指令配置。在 Nginx 配置中,不仅能够配置整个哈希表的大小上限,对大部分的内容项,也可以配置其大小上限,比如 server_names_hash_max_size 指令和 server_names_hash_bucket_size 指令用来设置服务器名称的字符数长度。
19.proxy_headers_hash_bucket_size size;
该指令用于设置 Nginx 服务器申请存放 HTTP 报文头的哈希表容量的单位大小。该指令的具体作用在上面 proxy_headers_hash_max_size 指令的使用中已经说明。size 为设置的容量,默认为 64 个字符。
20.proxy_next_upstream status …;
在配置 Nginx 服务器反向代理功能时,如果使用 upstream 指令配置了一组服务器作为被代理服务器,服务器组中各服务器的访问规则遵循 upstream 指令配置的轮询规则,同时可以使用该指令配置在发生哪些异常情况时,将请求顺次交由下一个组内服务器处理。status为设置的服务器返回状态,可以是一个或者多个。这些状态包括error,在建立连接、向被代理的服务器发送请求或者读取响应头时服务器发生连接错误。
timeout,在建立连接、向被代理的服务器发送请求或者读取响应头时服务器发生连接超时。
invalid_header,被代理的服务器返回的响应头为空或者无效。
http_500 | http_502 | http_503 | http_504 | http_404,被代理的服务器返回 500、502、503、504 或者 404 状态代码。
off,无法将请求发送给被代理的服务器。与被代理的服务器进行数据传输的过程中发送错误的请求,不包含在该指令支持的状态之内。
21.proxy_ssl_session_reuse on | off
该指令用于配置是否使用基于 SSL 安全协议的会话连接(“https://”)被代理的服务器,默认设置为开启(on)状态。如果我们在错误日志中发现「SSL3_GET_FINISHED:digest check failed」的情况,可以将该指令配置为关闭(off)状态。
问题总结
- 使用腾讯云CDN时,进行websokect反向代理时,由于cdn链接最多保持10s,将会导致websokect中断。