Nginx使用经验总结,好记性不比烂笔头(键盘)

2023-02-17 13:51:22 浏览数 (1)

基础知识

  1.  配置文件中以#开始的行,或者是前面有若干空格或者 TAB,然后再跟#的行,都被认为是注释
  2. 在 nginx.conf 中,包含若干配置项。每个配置项由配置指令和指令参数 2 个部分构成。指令参数也就是配置指令对应的配置值。
    •  配置指令是一个字符串,可以用单引号或者双引号括起来,也可以不括。但是如果配置指令包含空格,一定要引起来。
    • 指令的参数使用一个或者多个空格或者 TAB 字符与指令分开。指令的参数有一个或者多个 TOKEN 串组成。TOKEN 串之间由空格或者 TAB 键分隔。
    • 这个是一个简单配置项:error_page 500 502 503 504 /50x.html;
  3. 使用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小时...

代码语言:javascript复制
#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相关配置

代码语言:javascript复制
### 以下为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

全局变量

  1. $args,$query_string  请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2
  2. $content_length  http请求信息里面的“Content-Length”
  3. $conten_type  http请求信息里面的“Content-Type”
  4. $document_root  nginx虚拟主机配置文件中的root参数对应的值
  5. $document_uri  当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的参数。
  6. $host  主机头,也就是域名。
  7. $http_user_agent  客户端的详细信息,也就是浏览器的标识。
  8. $http_cookie  客户端的cookie信息
  9. $limit_rate  如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置,则显示为0.
  10. $remote_addr  客户端的公网ip
  11. $remote_port  客户端的port
  12. $remote_user  如果nginx有配置认证,该变量代表客户端认证的用户名
  13. $request_body_file  做反向代理时发给后端服务器的本地资源的名称
  14. $request_uri  请求的连接,包括$document_uri和$args
  15. $request_method 请求的方法,GET、POST等
  16. $scheme  请求的协议,如ftp,http,https
  17. $server_protocol  客户端请求资源用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0
  18. $server_addr  服务器ip地址
  19. $server_name  服务器的主机名
  20. $server_port  服务器的端口号
  21. $uri  和$document_uri相同
  22. $http_referer  客户端请求时的referer,通俗讲就是该请求时通过哪个连接跳进来的,也就是我们在百度搜一个关键字,然后可以点击条目跳进一个网站,点击的那个链接就是你的referer,用curl -e可以指定。

IF语句

提示

可以使用 =、!= 比较字符串是否相等,进行比较时字符串不需要加引号,IF跟括号之间必须有一个空格。

在server和location两种配置块内可以使用nginx的IF条件判断,当条件成立时执行指定的指令,条件可以为以下几种:

1.正则表达式

代码语言:javascript复制
# ~ 为区分大小写匹配;
# ~* 为不区分大小写匹配;
# !~ 不匹配某个区分大小写的正则;
# !~* 不匹配某个不区分大小写的正则;
#下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下: 
if ($http_user_agent ~ MSIE) { 
     rewrite ^(.*)$ /nginx-ie/$1 break;
 }

整个正则表达式字符串一般不需要加引号,但如果含有右花括号「}」或者分号「;」字符时,必须要给整个正则表达式添加引号。

2.文件目录匹配

代码语言:javascript复制
#-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链接,该语句只会影响当前所在的代码块。

代码语言:javascript复制
#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中使用

代码语言:javascript复制
deny all; #拒绝访问
allow 208.97.167.194; #允许指定IP访问

Rewrite 命令

  1. 它可以用在server, location 和IF条件判断块中,格式为:rewrite 正则表达式 替换目标 flag标记
  2. 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匹配;

代码语言:javascript复制
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;

问题总结

  1. location的匹配存在优先级的问题,前面比后面先匹配;绝对比正则先匹配。往往重写不生效时就是没有匹配到指定的块。(例如重写一个PHP文件的请求时,在PHP-CGI块的后面,所以一直返回404)。
  2. 修改配置文件后,一定要重启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」头域显示的地址就应该和客户端发起请求的地址相对应,而不是代理服务器直接返回的地址信息,否则就会出问题。该指令解决了这个问题,可以把代理服务器返回的地址信息更改为需要的地址信息。其语法结构为:

代码语言:javascript复制
proxy_redirect redirect replacement; 
proxy_redirect default; 
proxy_redirect off;

redirect,匹配「Location」头域值的字符串,支持变量的使用和正则表达式。 replacement,用于替换redirect变量内容的字符串,支持变量的使用。

对于第 1 个结构,>假设被代理服务器返回的响应头中「Location」头域为:

代码语言:javascript复制
Location: http://localhost:8081/proxy/some/uri/

该指令设置为:

代码语言:javascript复制
proxy_redirect  http://localhost:8081/proxy/  http://myweb/frontend/;

Nginx 服务器会将「Location」头域的信息更改为:

代码语言:javascript复制
Location: http://myweb/frontend//some/uri/

这样,客户端收到的响应信息头部中的「Location」头域也就被更改了。

结构 2 使用 default,代表使用 location 块的uri变量作为replacement,并使用 proxy_pass 变量作为redirect。请看下面两段配置,它们的配置效果是等同的。

代码语言:javascript复制
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)状态。

问题总结

  1. 使用腾讯云CDN时,进行websokect反向代理时,由于cdn链接最多保持10s,将会导致websokect中断。

0 人点赞