Nginx

yuhuo2022-03-28开发工具
参考链接

安装管理

Linux 版

安装 nginx:

# yum
yum install -y nginx
# apt
apt install -y nginx

通过 systemctl 命令进行管理:

  • systemctl start nginx:启动
  • systemctl enable nginx:开机自启动
  • systemctl stop nginx:关闭
  • systemctl restart nginx:重启
  • systemctl status nginx:查看运行状态

通过 nginx 自身的命令进行管理:

  • nginx:启动
  • nginx -s reopen:重启
  • nginx -s reload:重新加载配置文件(优雅重启,推荐使用)
  • nginx -s stop:强制停止
  • nginx -s quit:安全退出
  • nginx -t:检测配置文件地址 以及检测配置是否正常
  • nginx -v:显示版本信息并退出

Windows 版

Nginx 官网下载open in new window,解压即可。

通过 nginx 自身的命令进行管理,PowerShell 进入 nginx 目录,并使用 ./nginx 命令,如:

./nginx
./nginx -s stop

Windows 自身命令:

  • start nginx:启动(同样需要进入 nginx 目录,推荐,因为 ./nginx 会导致当前终端不可用)
  • taskkill /IM nginx.exe /F:关闭所有 Nginx 进程(当不小心启动了多次 Nginx 时,./nginx -s stop 已经无法关闭,此时只能通过 taskkill

全局配置

Linux 版配置文件:/etc/nginx/nginx.conf,Windows 版配置文件:nginx/conf/nginx.conf

# 运行 Nginx 的用户(windows 不支持该配置)
user  nobody; # - 默认 -

# Nginx 包含一个主进程(读取和评估配置并且维护工作进程)和多个工作进程(处理实际请求)
# 工作进程数(推荐为 CPU 核数)
worker_processes  2;
# 自动根据 CUP 核数配置
worker_processes  auto;

# 错误日志的位置和级别(级别省缺时默认 error)
error_log  logs/error.log; # - 默认 -
error_log  logs/error.log  warn; 

# 进程编号记录文件位置
# 启动 Nginx 时自动创建该文件,通过 Nginx 命令关闭时自动删除(通过 taskkill 关闭则不会删除)
pid        logs/nginx.pid; # - 默认 -

# 事件模型
events {
	# 最大并发连接数
    worker_connections  1024;
}

# http服务器
http {}

错误日志级别

从高到低分别为:

  1. emerg:紧急信息
  2. alert:立即处理信息
  3. crit:严重错误信息
  4. error:错误信息(默认)
  5. warn:警告信息
  6. notice:重要信息
  7. info:一般信息
  8. debug:调试信息

错误日志将记录当前级别及以上级别的信息,即级别越低记录的信息越多。常用的级别是 warn | error | crit。

http

http {
	# 引入其他配置文件
    include		mime.types;
    
    # mime.types 指定了文件后缀与 Content-Type 的映射关系
    # types {
    #	text/html                                        html htm shtml;
    #	text/css                                         css;
    #	...
    # }
    # 当文件后缀在 types 配置中不存在时,默认的 Content-Type,
    default_type  application/octet-stream;
	
	# 自定义日志格式
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
	
	# 访问日志的位置和格式,默认如下
    access_log  logs/access.log  combined;    
    # 使用自定义日志格式
    access_log  logs/access.log  main;
    # 关闭访问日志
    access_log 	off;
    
	# 是否启用系统调用来传输文件(提高效率)
    sendfile  	on; # - 默认 -
    
    # 是否延迟推送数据(存满 TCP 缓冲区再发送,提高传输效率,牺牲实时性),适合静态内容分发
    # 仅在 sendfile on 时有效
    tcp_nopush  off; # - 默认 -
    
    # 是否立即推送数据(与 tcp_nopush 相反),适合实时数据服务
    # 仅在 keep-alive 开启时有效,即 keepalive_timeout > 0
    tcp_nodelay	on; # - 默认 -
    
    # 推荐 sendfile,tcp_nopush,tcp_nodelay 三者都开启以提高性能
    # Nginx 会优先使用 tcp_nopush,当最后一个数据包没有填满 TCP 缓冲区时再使用 tcp_nodelay 发送
	
	# TCP长连接的时间,单位秒
    keepalive_timeout  75; # - 默认 -
    # 为0即表示不开启长连接
    #keepalive_timeout  0;
	
	# 是否开启压缩(减少传输数据量,提高传输速度,增加 CPU 开销)
    gzip  off; # - 默认 -
    
    # 定义一个变量,根据其他变量的值进行赋值
    map $animal $food {
        default apple; # 默认
        cat     banana; # 当 $animal 为 cat 时,$food 为 banana
        ""      ""; # 空字符串需要加双引号,非空字符串加不加双引号都可
    }
	
	# 服务
    server {
    	# 设置变量
    	set $animal cat;
    }
}

server

listen

监听的 IP 和端口(一个主机可能有多个 IP)。

server {
    # - 默认 -
    listen       *:80;
    
    # 省缺 IP 时,默认所有 IP ,即同 *:80
    listen       80;
    # 省缺端口时,默认 80 端口
    listen       127.0.0.1;
    
    # 监听 443 端口,并使用 ssl 协议
    listen       443 ssl;
    # 使用 HPPT2(必须基于 ssl),默认使用 HTTP1.1
    listen       443 ssl http2;    
}

以上仅支持 IPv4,IPv6 必须再单独设置一次 listen。

server {
	# 相当于 *:80
    listen       [::]:80;
    
    # ::1 相当于 127.0.0.1,省缺端口同样默认 80 端口
    listen       [::1];
}

server_name

域名匹配。当访问域名与每个 server 都匹配不上时,默认匹配第一个 server。

server {
    # - 默认 -
    server_name  localhost; 
    
    # 可以配置多个域名
    server_name  yuhuo.online www.yuhuo.online;
    
    # 可以使用 alias 配置别名,但实际直接配置多个域名即可,效果一样
    server_name  yuhuo.online alias www.yuhuo.online;
}

ssl_*

ssl 相关配置。

server {
    listen       443 ssl;
   
	# ssl 证书
    ssl_certificate      xxx/cert.pem; # 或使用 .crt 文件
    ssl_certificate_key  xxx/cert.key;
    
	# ssl 缓存
    ssl_session_cache    shared:SSL:1m; 
    ssl_session_timeout  5m;
    
    # ssl加密算法
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
}

charset

设置字符集,将添加到 Content-Type 的属性中。可用于 location。

server {
	# 不设置,Content-Type = text/html
	# 设置后,Content-Type = text/html; charset=utf-8
	charset utf-8;
}

index

默认文件。可用于 location。

server {
    # - 默认 -
    index  index.html index.htm;
}

root

根目录。可用于 location。

server {
    # - 默认 -
    root   html; 
}

error_page

当出现对应错误码时,转发到指定页面。可用于 location。

server {
    error_page  500 502 503 504  /50x.html;
    error_page  404              /404.html;
}

set

设置变量。可用于 location。

server {
	set $color green;
}

if

条件判断。可用于 location。

server {
	set $color red;
	
	# 精确匹配
	if($color = red) {
		set $food tomato;
	}
	# 正则匹配
	if($color ~ red) {
		set $food tomato;
	}
	# 正则匹配(不区分大小写)
	if($color ~* Red) {
		set $food tomato;
	}
}

deny

拒绝访问,返回 403。可用于 location。

server {
	# 阻止指定 IP 访问
	deny 192.168.1.1;
	
	# 阻止所有 IP 访问
	deny all;
}

allow

允许访问,与 deny 配合使用,按顺序匹配第一个。可用于 location。

server {
	# 允许指定 IP 访问
	allow 192.168.1.1;
	
	# 允许所有 IP 访问
	allow all;
}

rewrite

转发与重定向。可用于 location。

server {
	# 语法:rewrite regex replacement [flag];

	# last(默认):内部重定向,重新匹配规则
    rewrite ^/last$ /abc.html last;

    # break:内部重定向,只匹配当前规则
    rewrite ^/break$ /abc.html break;
	
	# permanent:301 永久重定向
    rewrite ^/permanent$ /abc.html permanent;

    # redirect:302 临时重定向
    rewrite ^/redirect$ /abc.html redirect;      
}

last与break

当 rewrite 处于 server 块中,last 与 break 表现是一致的,重定向地址会在 server 块内重新匹配 location。

当 rewrite 处于 location 块中时,break 只根据当前 location 指定的 root 或 alias 进行重定向,而 last 会跳回 server 块重新匹配 location。

try_files

检查文件是否存在。可用于 location。

server {
	# 语法1:try_files file ... uri;
	# 在当前环境的 root 或 alias 中,按顺序查找所有 file,
	# 所有 file 都无则根据 uri 内部重定向
	try_files $uri $uri/ /index.html;
	
	# (注:如果设置了 try_files,没有设置 $uri/,那N)
   	
   	# 语法2:try_files file ... =code;
   	# 所有 file 都无则根据 code 内部重定向
	try_files $uri $uri/ =404;
}

file与uri

file 与 uri 写法是一样的,根据是否最后一位做区分。

uri 作为回退页面必须有效存在,若直到访问 uri 都失败,则报 500 错误。

如果设置了 try_files 但没有指定 $uri/,那 Nginx 将按照 try_files 的规则来。当访问目录时,不会默认重定向到 目录/ 了。

return

直接返回状态码和响应体。可用于 location。

server {
	# 返回状态码
	return 500;

	# 只返回状态码和响应体
    add_header Content-Type application/json;
    return 200 '{"message": "success"}';

	# 当状态码为3XX时,第二个参数为重定向地址
	# 示例将 http 重定向到 https
	return 301 https://$server_name$request_uri;
}

location

路径匹配。

server {
    # 精确匹配
    location = /abc.html {
        add_header myHeader 1;
    }
    # 前缀匹配(指定 url 开头)
    location ^~ /abc {
    	add_header myHeader 2;
    }
    # 通用匹配(指定 url 开头,与前缀匹配区别在于优先级)
    location /ab {
    	add_header myHeader 3;
    }
    # 正则匹配
    location ~ abc {
    	add_header myHeader 4;
    }
    # 正则匹配(不区分大小写)
    location ~* Abc {
    	add_header myHeader 5;
    }
}

匹配优先级

  1. 精确匹配优先级最高,一旦匹配成功即终止匹配;
  2. 前缀匹配和通用匹配优先级相同,匹配表达式最长者;
  3. 如果第 2 步最终匹配的是前缀匹配,则终止匹配;
  4. 如果第 2 步最终匹配的是通用匹配,则继续进行正则匹配,如果正则匹配成功则使用正则匹配。

location

index

当 URL 是以 / 结尾时,Nginx 将返回对应目录下的默认文件。

当 URL 非 / 结尾时,如访问 /abc,Nginx 将检索该 URL 指定的路径,如果目标是一个文件则直接返回。如果目标是文件夹,则重定向到 /abc/ 再次发起请求。

当直接请求域名,如 yuhuo.online,则浏览器将直接以 yuhuo.online/ 发起请求。

# 1、请求 /abc,检索到 abc 是目录,重定向到 /abc/
# 2、请求 /abc/,将返回 /abc/default.html
location /abc {
	index  default.html;
}

root

根目录。

location /bar {
    # 相对路径,相对于 nginx 目录
    root   html;
	# 绝对路径
	root	d:/root;
}

当访问 /bar/abc.html 时,执行拼接操作:

// 根目录拼接 URL
"d:/root" + "/bar/abc.html"

最终请求到 d:/root/bar/abc.html

斜杠后缀问题

当 root 为 d/root/ 时,拼接结果为 d:/root//bar/abc.html,连续斜杠在 Nginx 中是可以正常请求的,即根目录加不加斜杠后缀都可以。

alias

别名目录。

location /foo {
	# 相对路径,相对于 nginx 目录
	alias   html;
	# 绝对路径
	alias	d:/alias;
}

当访问 /foo/abc.html 时,执行替换操作:

// location 中的路径替换为别名目录
"/foo/abc.html".replace("/foo", "d:/alias")

最终请求 d:/alias/abc.html

斜杠后缀问题

当访问 /foof/abc.html 时,替换结果为 d:/aliasf/abc.html,造成错误。

当把 location 匹配路径改成 /foo/ 时,访问 /foo/abc.html ,替换结果为 d:/aliasabc.html,亦造成错误。

因此使用别名目录时,需要把 location 匹配路径和 alias 都加上斜杠后缀,才不容易造成错误。

location /foo/ {
	alias	d:/alias/;
}

proxy_*

反向代理

http {
	# 当 $http_upgrade 有值时,$connection_upgrade 为 "upgrade"
	map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }
    # 定义一组服务器
    upstream back_server { 
        server 127.0.0.1:6060; 
        # weight:设置权重,默认为 1
        server 127.0.0.1:8080 weight=2;
        # down:暂停使用
        server 127.0.0.1:9090 down;
        # backup:备用,当正常机器繁忙或不可用时使用
        server 127.0.0.1:7070 backup;
    } 
    server {
        location /api/ {
            # 反向代理地址
            # 与 alias 类似,执行替换操作
            # 即访问 /api/get,代理到 http://localhost:3000/get
            proxy_pass   http://localhost:3000/;
            
            # 使用负载均衡服务器
            proxy_pass   http://back_server/;

            # websocket 支持:
            # 确保基于 HTTP 1.1 版本进行握手
            # 请求头 Upgrade: websocket
            # 请求头 Connection: upgrade
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;

            # 设置来源相关请求头
            proxy_set_header   X-Real-IP         $remote_addr;
            proxy_set_header   Host              $http_host;
            proxy_set_header   X-Forwarded-Host  $http_host;
            proxy_set_header   X-Forwarded-Port  $server_port;
            proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }
    }
}

expires

设置强缓存,作用于 Expires 响应头

# 给图片文件设置 7 天强缓存
location ~* \.(gif|png|jpg)$ {
	expires 7d;
}

add_header

设置响应头

# 跨域相关
location /api  {
	add_header  Access-Control-Allow-Origin  http://yuhuo.online;
	add_header  Access-Control-Allow-Methods  *;
	add_header  Access-Control-Allow-Credentials  true;
}

# html文件协商缓存
location ~* \.html$ {
	add_header Cache-Control no-cache;
}

内置变量

(以访问 http://yuhuo.online:81/abc/?menu=1&tab=2 为例)

变量名说明示例值
$remote_addr客户端 IP 地址127.0.0.1
$remote_user客户端用户名(需要配置身份认证才有值,默认为空)
$scheme协议名http
$server_port服务器端口号80
$request请求起始行GET /abc.html HTTP/1.1
$request_uri原始请求链接(带参数)/abc/?menu=1&tab=2
$uri经过 rewrite 或 index 后(若有)的实际处理链接/abc/index.html
$args请求参数menu=1&tab=2
$server_name匹配到的 server_namelocalhost
$http_host请求头 HOST 字段yuhuo.online:81
$host等于 $http_host(不带端口号),不存在则等于 $server_nameyuhuo.online
$http_upgrade请求头 Upgrade 字段websocket
$http_referer请求头 Referer 字段https://www.baidu.com/
$http_user_agent请求头 User-Agent 字段Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0
$http_x_forwarded_for使用代理转发时的客户端原始 IP 地址
$time_local服务器的本地时间04/Jun/2024:10:43:54 +0800
$status响应状态码200
$body_bytes_sent响应体的字节数0
Last Updated 2024/6/5 11:39:44