Nginx
参考链接
安装管理
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 官网下载,解压即可。
通过 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 {}
错误日志级别
从高到低分别为:
- emerg:紧急信息
- alert:立即处理信息
- crit:严重错误信息
- error:错误信息(默认)
- warn:警告信息
- notice:重要信息
- info:一般信息
- 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;
}
}
匹配优先级
- 精确匹配优先级最高,一旦匹配成功即终止匹配;
- 前缀匹配和通用匹配优先级相同,匹配表达式最长者;
- 如果第 2 步最终匹配的是前缀匹配,则终止匹配;
- 如果第 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_name | localhost |
$http_host | 请求头 HOST 字段 | yuhuo.online:81 |
$host | 等于 $http_host(不带端口号),不存在则等于 $server_name | yuhuo.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 |