当前位置: 首页 > news >正文

Nginx配置文件介绍和基本使用

Nginx配置文件介绍和基本使用

Nginx 是一款高性能的 HTTP 服务器、反向代理服务器及电子邮件代理服务器,由俄罗斯工程师 Igor Sysoev 开发,并于2004年首次公开发布。以轻量级、高并发能力、稳定性和低资源消耗著称。

主要功能

  • HTTP服务器:可以作为静态网页服务器,处理大量的并发请求。
  • 反向代理服务器:能够将客户端请求转发给后端服务器,并将响应返回给客户端,支持负载均衡。
  • 邮件代理服务器:提供IMAP、POP3和SMTP协议的支持。
  • 高并发处理:单台服务器可支持数万并发连接。
  • 低内存占用:典型场景下内存占用仅数兆至数十兆。
  • 模块化设计:支持丰富的扩展模块(如 rewritesslhttp_gzip_module 等)。
  • 反向代理与负载均衡:可高效转发请求至后端服务器集群。
  • 静态资源处理:擅长处理静态文件(如图片、CSS、JS),性能优于传统 Apache 服务器。
  • 热部署:无需停止服务即可更新配置和二进制文件。
  • 其他特性:包括但不限于SSL/TLS加密、URL重写、gzip压缩、缓存等。

1、安装

1.1、联网Linux

# Ubuntu/Debian
# 更新软件源
sudo apt update
# 安装 Nginx
sudo apt install nginx# CentOS/RHEL
# 安装 epel 源(若未安装)
sudo yum install epel-release
# 安装 Nginx
sudo yum install nginx# 启动服务
sudo systemctl start nginx
# 查看状态(确保 active(running))
sudo systemctl status nginx
# 开机自启
sudo systemctl enable nginx# 测试配置文件语法
nginx -t
# 查看完整配置(包括默认值)
nginx -T# 调试日志
error_log /var/log/nginx/error.log debug;
# 使用 strace 调试
strace -p $(cat /var/run/nginx.pid)

1.2、Windows

  • 下载地址:http://nginx.org/en/download.html(选择 Windows 版本)。

  • 解压后,进入目录,双击 nginx.exe 启动。

  • 命令行启动 / 停止:

    # 启动
    start nginx
    # 重启
    nginx -s reload
    # 重新打开日志文件
    nginx -s reopen
    # 停止(快速停止)
    nginx -s stop
    # 优雅停止(处理完当前请求后停止)
    nginx -s quit
    

1.3、macOS

# 使用 Homebrew 安装
brew install nginx
# 启动服务
brew services start nginx
# 或手动启动
nginx -c /usr/local/etc/nginx/nginx.conf

路径:/usr/local/etc/nginx/nginx.conf

2、配置

使用核心就是其配置文件。

Nginx 的配置文件采用模块化结构,通过指令(directive)和上下文(context)组织。

Nginx 的配置文件是一个文本文件,通常命名为nginx.conf,它定义了 Nginx 如何处理请求、响应以及其他相关设置。

Nginx 的主要配置文件位于/etc/nginx/nginx.conf/usr/local/nginx/conf/nginx.conf。你也可以在这个目录下创建额外的配置文件,通过 include 指令引入主配置文件中。

配置文件结构

Nginx 配置文件的基本结构是由多个块(block)组成,每个块可以包含其他块或指令。

顶级块包括 main(全局设置)、httpserverlocation 等。

全局块 (main context)
├── events 块
└── http 块├── server 块 (虚拟主机)│   ├── location 块│   └── location 块└── server 块├── location 块└── location 块

主要块介绍如下

2.1、Main (全局)

位于配置文件的最外层,定义影响整个Nginx服务器的行为,如工作进程数(worker_processes)、错误日志位置(error_log)等。

常用指令

  • user: 指定Nginx工作进程运行的用户和组。
  • worker_processes: 设置工作进程的数量,推荐设置为CPU核心数。
  • error_log: 定义错误日志的位置和记录级别。
  • pid: 指定存储主进程ID的文件位置。

示例

user www-data;                  # 运行Nginx的用户和组,一般情况下默认都是nginx用户
worker_processes auto;          # 工作进程数,auto 自动检测 CPU 核心数(通常设为CPU核心数)
pid /run/nginx.pid;             # PID文件位置
error_log /var/log/nginx/error.log warn;  # 错误日志路径和级别# 工作进程最大打开文件数限制(提升并发能力)
worker_rlimit_nofile 100000;    # 每个worker能打开的文件描述符数量

错误日志说明

这一块的 error_log 日志主要用于记录Nginx运行过程中遇到的各种问题、警告和调试信息。包括但不限于启动失败、配置文件错误、资源限制(如打开文件数过多)、处理请求时发生的错误等。可以设置不同的日志级别来控制哪些级别的消息会被记录下来。可选的日志级别从低到高依次为:debug、info、notice、warn、error、crit、alert、emerg。例如:

error_log /var/log/nginx/error.log warn;

对于排查Nginx的运行故障非常有用,可以帮助管理员了解服务器的状态和可能的问题所在。

还有一类是访问日志,和这里的日志是不一样的,见下面小节。

2.2、Events

配置影响 Nginx 服务器与客户端网络连接的设置。

示例

events {worker_connections 1024;    # 每个worker进程的最大连接数multi_accept on;            # 一次接受所有(多个)新连接# 事件驱动模型(Linux 推荐 epoll,FreeBSD 推荐 kqueue)use epoll;                  # Linux高性能事件模型accept_mutex on;            # 启用互斥锁进行连接分发
}

2.3、Http

包含与HTTP相关的配置,可嵌套多个server块,每个server块代表一个虚拟主机。

常用指令

  • include: 包含其他配置文件,便于管理大量配置。
  • default_type: 默认MIME类型。
  • log_format: 自定义访问日志格式。
  • access_log: 访问日志的位置及使用的日志格式。
  • sendfile: 启用或禁用 sendfile() 函数以提高文件传输效率。
  • keepalive_timeout: 设置长连接超时时间。

示例

http {# 基本设置include /etc/nginx/mime.types;  # MIME类型映射文件default_type application/octet-stream;  # 默认MIME类型# 日志格式定义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 /var/log/nginx/access.log main;  # 访问日志# 性能优化sendfile on;                  # 启用高效文件传输模式tcp_nopush on;                # 仅在sendfile开启时有效tcp_nodelay on;               # 禁用Nagle算法# 长连接配置keepalive_timeout 65;         # 保持连接超时时间types_hash_max_size 2048;     # MIME类型哈希表大小# Gzip压缩gzip on;gzip_disable "msie6";         # 禁用IE6及以下版本的Gzip压缩gzip_vary on;                 # 是否在响应头部添加 Vary: Accept-Encoding 字段gzip_proxied any;             # 对所有代理请求启用Gzip压缩gzip_comp_level 6;            # 设置压缩级别为6gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;  # 指定哪些MIME类型的内容需要被压缩,默认仅压缩text/html类型# 虚拟主机配置(可包含多个 server 块),包含其他配置文件include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;
}

访问日志说明

访问日志记录了每个客户端请求的详细信息,适用于分析网站流量、用户行为、性能监控等方面。

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];

详细使用,遇到了再说,比如buffer、gzip等参数的使用。

内容:通常包含但不限于以下信息:

  • 客户端IP地址
  • 请求时间
  • 请求方法(GET、POST等)
  • 请求的URL路径
  • HTTP响应状态码
  • 发送到客户端的数据量
  • 引荐页面
  • 用户代理(浏览器类型等)

格式:可以通过log_format指令自定义访问日志的格式。默认情况下,Nginx使用“combined”格式,示例如下:

log_format combined '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log combined;

除了记录基本的HTTP请求信息外,还可以根据需要添加其他变量,如请求处理时间、是否缓存命中等,以满足特定的监控需求。

这里的日志是访问url请求的日志,和上面的错误日志是不一样的,更多见上面小节。

日志格式示例

log_format combined '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent"';

这是Nginx默认使用的格式,适用于大多数情况。

字段解释:

  • $remote_addr: 客户端IP地址。
  • $remote_user: 用于HTTP基本认证的用户名(如果没有则为-)。
  • $time_local: 服务器本地时间。
  • $request: 请求的第一行,包括方法、URL和协议版本。
  • $status: HTTP响应状态码。
  • $body_bytes_sent: 发送给客户端的字节数,不包括响应头的大小。
  • $http_referer: 来源页面(即用户是从哪个页面链接到当前页面的),注意这个字段是可选的,且可能为空。
  • $http_user_agent: 用户代理(User-Agent)字符串,包含了客户端浏览器和其他信息。

带有请求时间和上游服务器响应时间的格式

如果你想了解每个请求的处理时间和后端服务器的响应时间,可以使用以下格式:

log_format timed_combined '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent" ''$request_time $upstream_response_time';

新增字段解释:

  • $request_time: 请求处理总时间(从接收请求到发送响应完毕所花费的时间),单位是秒,精度达到毫秒级。
  • $upstream_response_time: 上游服务器(如Tomcat)响应时间,单位是秒。

JSON格式

对于需要结构化数据的情况,可以使用JSON格式的日志,便于后续使用ELK(Elasticsearch, Logstash, Kibana)或EFK(Elasticsearch, Fluentd, Kibana)等工具进行集中化日志分析:

log_format json '{"time": "$time_iso8601", ''"remote_addr": "$remote_addr", ''"remote_user": "$remote_user", ''"request": "$request", ''"status": $status, ''"body_bytes_sent": $body_bytes_sent, ''"request_time": $request_time, ''"upstream_response_time": "$upstream_response_time", ''"http_referer": "$http_referer", ''"http_user_agent": "$http_user_agent"}';
access_log /var/log/nginx/access.log json;

这种格式将日志条目以JSON格式输出,便于解析和自动化处理。

更多细节的高级格式

如果你需要更多的信息来进行深入分析,比如客户端的真实IP(通过X-Forwarded-For头)、请求ID(用于追踪特定请求)等,可以使用如下格式:

log_format advanced '$remote_addr - $remote_user [$time_local] ''"$request" $status $body_bytes_sent ''"$http_referer" "$http_user_agent" ''"$http_x_forwarded_for" "$request_id" ''$request_time $upstream_response_time';

新增字段解释:

  • $http_x_forwarded_for: 客户端的真实IP地址,通常在反向代理或负载均衡场景下使用。
  • $request_id: 可以通过设置$uid_got或类似的变量来生成一个唯一的请求ID,用于追踪特定请求。

选择适合你需求的日志格式,并确保日志文件不会过大影响性能,同时定期归档和清理旧日志。如果你正在使用集中化的日志管理工具,那么采用结构化的JSON格式可能会更加方便。

2.4、Server

用于定义虚拟主机(网站),可以有多个server块来服务不同的域名或端口。

常用指令

  • listen: 监听的IP地址和端口号。
  • server_name: 该服务器块处理的域名或IP地址。
  • root: 网站根目录的位置。
  • index: 默认索引文件名。

示例

server {listen 80;                   # 监听端口server_name example.com www.example.com;  # 服务器名称,域名root /var/www/example.com;    # 网站根目录index index.html index.htm;   # 默认索引文件# 错误页面error_page 404 /404.html;location = /404.html {internal;  # 仅内部访问}error_page 500 502 503 504 /50x.html;# 日志access_log /var/log/nginx/example.access.log;error_log /var/log/nginx/example.error.log;# Location块location / {try_files $uri $uri/ =404;}location ~ \.php$ {include snippets/fastcgi-php.conf;fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;}# 静态资源缓存策略location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {expires 30d;access_log off;add_header Cache-Control "public";}# 禁止访问隐藏文件location ~ /\. {deny all;}
}

2.5、Location(重要)

定义如何处理针对特定URL路径的请求,是server块内的子块。

常用指令

  • location: 根据请求的URI匹配规则来处理请求。
    • 使用前缀匹配(location /prefix)、精确匹配(location = /exact/path)、正则表达式匹配(location ~ pattern)等方式。
  • alias: 定义别名路径,替换路径前缀更灵活。
  • try_files: 尝试按顺序查找指定的文件或目录,直到找到为止,找不到则返回404。

root vs alias

  • root:会拼接 location 的前缀匹配,就是 前缀匹配 + root 后面的路径,就是说将请求的 URI 直接拼接到 root 指定的路径之后。

    会保留 location 匹配的前缀路径,并将其作为文件路径的一部分。

    使用场景

    • 适用于简单的路径映射,如将整个站点的静态资源指向同一目录(如 root /var/www/html;)。

    • 可在 httpserverlocation 块中使用。

  • alias:使用 alias 后面的路径替换location 的前缀匹配,并不会拼接前缀匹配;会移除 location 匹配的前缀路径(如 /static/),直接用 alias 路径替换,注意路径末尾必须带 /。

    使用场景

    • 必须与 location 配合使用,且只能在 location 块中生效。
    • 路径末尾必须包含 /,否则可能导致路径解析错误(如请求 /static/image.jpg 时,若 alias 为 /data,Nginx 会尝试访问 /datastatic/image.jpg,显然不存在)。
    • location 匹配模式不含末尾 /(如 location /static),alias 路径也可不加 /,但实际开发中建议统一使用带 / 的匹配模式和 alias 路径。

区别

  • 使用 root 时,服务器文件系统中必须存在与 location 前缀一致的子目录(如 /data/static/)。
  • 使用 alias 时,可直接映射到任意目录(如 /data/static_files/),无需保留前缀路径。

优先级

  • location 同时存在 rootalias 时,alias 会覆盖 root,因为 alias 专门用于路径替换。

正则 location 中的使用

  • 在正则匹配的 location(如 location ~ \.jpg$)中,只能使用 alias,不能使用 root

    location ~ \.(jpg|png|gif)$ {alias /data/images/;  # 正确用法
    }
    

整体示例

# 访问 http://yourdomain.com/images/logo.png# root,直接拼接,实际是:/var/www/static/images/logo.png
location /images/ {root /var/www/static/; #======================= ①
}# alias,移除前缀,实际是:/var/www/static/images/logo.png
location /images/ {alias /var/www/static/images/; #======================= ②
}# 注意,上述的 ① 和 ② 处的值不一样

语法格式

location [修饰符] 匹配模式 {# 配置指令
}

修饰符类型(优先级从高到低)

  • =:精确匹配,如果找到完全匹配,Nginx将停止搜索并使用此匹配。停止搜索后面的location,即使后面有更“精确”的正则表达式。
  • ^~:前缀匹配(否定前缀),不检查后面location的正则,比普通前缀匹配更高的优先级,常用于加速某些特定路径的匹配过程。
  • ~:区分大小写的正则匹配。
  • ~*:不区分大小写的正则匹配。
  • 无修饰符:前缀匹配,只要请求的URI以指定的字符串开头,就被认为是匹配的,Nginx会从最长到最短尝试匹配所有定义的前缀。
  • 正则表达式:正则表达式匹配是在前缀匹配之后进行的,并且一旦匹配成功,Nginx也会停止搜索(停止搜索后面的普通location),若转义特殊字符,请确保在正则表达式中正确使用反斜杠。

匹配优先级

  1. 精确匹配 (=) - 最高优先级
  2. 前缀匹配 (^~) - 特殊前缀(短路机制)
  3. 正则匹配 (~~*) - 按配置文件顺序
  4. 普通前缀匹配 (无修饰符) - 最低优先级

匹配顺序

  • 首先,Nginx尝试找到最具体的前缀匹配。如果有多个前缀匹配,选择最长的那个。
  • 如果找到了带有^~前缀的前缀匹配,并且它是最佳匹配,则直接使用它而不再检查正则表达式匹配。
  • 然后,Nginx检查正则表达式匹配。按照它们在配置文件中出现的顺序进行测试,一旦匹配即停止。
  • 如果没有正则表达式匹配被选中,先前找到的最佳前缀匹配将被使用。
server {location = /login { # 精确匹配/login[ configuration A ]}location /static/ { # 前缀匹配/static/,会先记住它,不会立即使用这个匹配,继续去检查是否有正则表达式匹配更合适[ configuration B ]}location ^~ /images/ { # 否定前缀匹配/images/,阻止后续正则匹配[ configuration C ]}location ~* \.(gif|jpg|png)$ { # 不区分大小写的正则表达式匹配图片文件[ configuration D ]}
}

在这个例子中:

  • 请求/login会匹配“configuration A”。
  • /static/style.css会匹配“configuration B”。
  • /images/logo.png会匹配“configuration C”,即使它也符合正则表达式location的条件,但由于^~的存在,不会进一步检查正则表达式。
  • 对于/documents/document.pdf,由于没有匹配的前缀或精确匹配,若存在其他匹配逻辑,将根据其情况决定;但如果请求是针对图像文件(如.jpg),则会匹配“configuration D”。

示例

# 精确匹配
location = / {                # 精确匹配首页# 特殊处理
}
location = /exact-match {# 仅匹配完全相同的路径 /exact-matchreturn 200 "Exact match!";
}# 前缀匹配
location /images/ {           # 匹配/images/开头的URIroot /data;expires 30d;              # 缓存30天
}
location ^~ /static/ {# 匹配以 /static/ 开头的路径,不继续正则匹配root /var/www;
}# 正则匹配
location ~ \.(php|php5)$ {# 匹配 .php 或 .php5 结尾的路径fastcgi_pass unix:/run/php/php8.1-fpm.sock;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;
}location ~* \.(jpg|jpeg|png|gif)$ {# 不区分大小写的正则匹配expires 30d;
}location ~ \.(gif|jpg|png)$ { # 匹配图片文件root /data/images;access_log off;           # 不记录访问日志
}location ~* \.php$ {          # 匹配PHP文件(不区分大小写)fastcgi_pass 127.0.0.1:9000;include fastcgi_params;
}# 通用匹配
location / {# 所有未匹配的请求都会落入此处try_files $uri $uri/ /index.php?$query_string;  # 尝试文件 → 目录 → PHP 处理
}

示例2

# 假设有以下配置:
server {location = /exact-match { ... }          # 1. 精确匹配location ^~ /prefix-special { ... }      # 2. 特殊前缀location ~ /regex-.* { ... }             # 3. 正则匹配1location ~ /prefix-.* { ... }            # 4. 正则匹配2location /prefix-normal { ... }          # 5. 普通前缀
}

当请求 /prefix-special/test 时:

  1. 先检查精确匹配 /exact-match → 不匹配。
  2. 检查 ^~ /prefix-special → 匹配成功!
  3. 立即停止,不再检查后面的正则和普通前缀。

匹配流程图

用户请求 URI ——>
|
|——→ 是否存在 = 精确匹配? → 是 → 使用并结束|否↓是否存在前缀匹配?(包括 ^~ 和普通前缀)↓选择最长匹配的前缀↓是否是 ^~ 类型? → 是 → 使用并结束|否↓继续检查正则表达式匹配(按配置顺序查找)↓找到第一个匹配的正则? → 是 → 使用并结束|否↓使用之前记录的最长前缀匹配↓都没找到? → 返回 404

说明(重要)

我们可以简单的理解为两大类匹配。

第一类就是 = 号匹配:

= 号匹配优先级最高,nginx 只要找到就停止向下或者继续匹配 location,就直接使用当前等号的location,类似于循环中的break关键字作用,该次路径代理结束;

第二类就是前缀匹配

nginx 会找所有的满足的前缀匹配 location,此时不管 ~^~ 符号,只管满足前缀匹配,且不会立即使用这个匹配,而是先记住它;等找到所有且记住所有之后,然后再看是否满足 ^~ 符号前缀的location,如果满足就使用当前这个,匹配结束,也类似break关键字;再者,如果没有 ^~ 符号前缀的location,就找 ~ 符号前缀的location,如果只有一个,则使用并结束当前匹配,类似break;如果有多个 ~ 符号前缀的location,则使用最长的location,使用并结束当前匹配,也类似break;

如果没有 ^~ 符号前缀的location 也没有 ~ 符号前缀的location,则使用最简单的前缀的location;如果只有一个就使用它,如果有多个就就使用满足且最长的那一个。

大致流程是这样,更详细的原理,可以查看官网。

2.6、Upstream

定义后端服务器组用于负载均衡:

upstream backend {server backend1.example.com weight=5;server backend2.example.com:8080;server unix:/tmp/backend3.sock;server backup1.example.com:8080 backup;# 负载均衡方法# least_conn;   # 最少连接# ip_hash;      # IP哈希# hash $request_uri consistent;  # 一致性哈希
}# 完整配置
http {# 定义上游服务器集群upstream backend_servers {# 轮询策略(默认)server backend1.example.com weight=5;  # 权重越高,分配请求越多server backend2.example.com weight=3;server backend3.example.com weight=2;# 其他负载均衡算法# ip_hash;  # 基于客户端 IP 哈希,确保同一客户端始终访问同一服务器# least_conn;  # 最少连接数优先# fair;  # 响应时间优先(需安装 ngx_http_upstream_fair 模块)# 健康检查check interval=3000 rise=2 fall=5 timeout=1000 type=http;check_http_send "HEAD /health_check HTTP/1.0\r\n\r\n";check_http_expect_alive http_2xx http_3xx;}server {listen 80;server_name loadbalancer.example.com;location / {proxy_pass http://backend_servers;}}
}

2.7、Mail

配置邮件代理服务器:

mail {auth_http localhost:9000/auth;proxy_pass_error_message on;server {listen 110;protocol pop3;proxy on;}server {listen 25;protocol smtp;smtp_auth login plain;proxy on;}
}

3、常用指令详解

3.1、基本指令

3.1.1、listen

监听地址和端口:

listen 80;
listen 443 ssl;
listen [::]:80 ipv6only=on;
3.1.2、server_name

服务器名称,支持通配符和正则:

server_name example.com *.example.com ~^www\d+\.example\.com$;
3.1.3、root

定义文档根目录:

root /var/www/html;
3.1.4、index

定义默认索引文件:

index index.html index.htm index.php;

3.2、访问控制

3.2.1、allow/deny

IP访问控制:

location /admin/ {allow 192.168.1.0/24;deny all;
}# 基于 IP 的访问控制
location /admin {allow 192.168.1.0/24;  # 允许内网访问allow 203.0.113.45;    # 允许特定 IPdeny all;              # 其他 IP 拒绝
}
3.2.2、auth_basic

基本认证:

auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;# 基于 HTTP 基本认证的访问控制
location /secret {auth_basic "Restricted Area";auth_basic_user_file /etc/nginx/.htpasswd;  # 使用 htpasswd 生成密码文件
}
3.2.3、防盗链配置
location ~* \.(jpg|jpeg|png|gif|mp3|pdf)$ {valid_referers none blocked example.com *.example.com;if ($invalid_referer) {return 403;  # 非法引用返回 403# 或重定向到本地图片# rewrite ^/ http://example.com/forbidden.png;}
}

3.3、代理相关

3.3.1、proxy_pass

反向代理:

location / {proxy_pass http://backend;
}
3.3.2、proxy_set_header

设置代理头:

# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;server {listen 80;server_name proxy.example.com;location / {proxy_pass http://backend_server;  # 后端服务器地址proxy_set_header Host $host;  # 传递原始请求的 Host 头proxy_set_header X-Real-IP $remote_addr;  # 传递客户端真实 IPproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;  # 传递请求协议(http/https)# 超时设置proxy_connect_timeout 5s;proxy_send_timeout 60s;proxy_read_timeout 60s;# 缓冲区设置proxy_buffer_size 16k;proxy_buffers 4 32k;proxy_busy_buffers_size 64k;}
}
3.3.3、cors 跨域问题
server {listen 80;server_name proxy.example.com;location / {add_header Access-Control-Allow-Origin 'http://localhost:8000' always;  add_header Access-Control-Allow-Headers '*';  add_header Access-Control-Allow-Methods '*';  add_header Access-Control-Allow-Credentials 'true';  if ($request_method = 'OPTIONS') {  return 204;  }  proxy_pass http://backend_server;  # 后端服务器地址}
}
3.3.4、SSL/TLS配置
# ssl_certificate /path/to/cert.pem;
# ssl_certificate_key /path/to/key.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;server {listen 443 ssl http2;       # 启用 HTTP/2server_name secure.example.com;# SSL 证书配置ssl_certificate /etc/nginx/ssl/cert.pem;ssl_certificate_key /etc/nginx/ssl/key.pem;# SSL 优化配置ssl_protocols TLSv1.2 TLSv1.3;ssl_prefer_server_ciphers on;ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;ssl_session_cache shared:SSL:10m;ssl_session_timeout 1d;ssl_session_tickets off;# HSTS 头部(增强 HTTPS 安全性)add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;# 网站根目录root /var/www/secure;
}# HTTP 自动跳转 HTTPS
server {listen 80;server_name secure.example.com;return 301 https://$host$request_uri;
}

使用本地测试证书

要在本地环境中使用Nginx配置SSL进行测试,你需要创建一个自签名的SSL证书,并在Nginx中配置它。

mkdir -p /opt/data/nginx_https/conf/ssl
# 使用 openssl 创建
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout localhost.key -out localhost.crt

运行上述命令将生成一个有效期为365天的自签名证书(localhost.crt)和对应的私钥(localhost.key)。

执行此命令时,系统会提示你输入一些信息,如国家、省份等。对于本地测试,这些信息可以随意填写。

然后参照上述配置文件配置即可:

server {listen 443 ssl;server_name yourdomain.com;ssl_certificate /etc/nginx/ssl/localhost.crt;ssl_certificate_key /etc/nginx/ssl/localhost.key;location / {# 配置其他参数}
}

注意:监听端口处,一定加上 ssl ,开启https功能。

3.3.5、websocket配置
server {listen 443 ssl;server_name yourdomain.com;ssl_certificate /path/to/your/certificate.crt;ssl_certificate_key /path/to/your/private.key;location /wss/ {proxy_pass http://backend_server;  # 后端WebSocket服务器地址proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_set_header Host $host;# 下面是可选的超时设置proxy_read_timeout 86400s;proxy_send_timeout 86400s;}
}
  • listen 443 ssl;:监听443端口,并开启SSL。
  • ssl_certificatessl_certificate_key:指定你的SSL证书和私钥路径。
  • proxy_pass:指向处理WebSocket连接的实际后端服务器地址。
  • proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";:这些行告诉Nginx将HTTP连接升级到WebSocket协议。
  • 超时设置可以防止连接因为长时间没有活动而被关闭。

3.4、重写和重定向

3.4.1、rewrite

URL重写:

# 格式
rewrite regex replacement [flag];
# flag:last|break|redirect|permanentrewrite ^/old/(.*)$ /new/$1 permanent;
3.4.2、return

返回状态码或重定向,相比 rewrite 指令,return 更加直观和高效:

# 格式
return code [text];
return code URL;
return URL;# return 301 https://$host$request_uri;
# return 403;# 移除尾部斜杠
rewrite ^/(.*)/$ /$1 permanent;# 移动端跳转
if ($http_user_agent ~* "mobile|android|iphone") {rewrite ^ http://m.example.com$request_uri permanent;
}# 网站维护模式
if (-f $document_root/maintenance.html) {return 503;
}
error_page 503 @maintenance;
location @maintenance {rewrite ^(.*)$ /maintenance.html break;
}

3.5、FastCGI 配置(PHP 处理)

示例

server {listen 80;server_name php.example.com;root /var/www/php;index index.php index.html;# 处理 PHP 请求location ~ \.(php|php5)$ {fastcgi_pass unix:/run/php/php8.1-fpm.sock;  # PHP-FPM Unix 套接字# 或使用 TCP 连接:fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;include fastcgi_params;# 安全优化:禁用 path_infofastcgi_split_path_info ^(.+\.php)(/.+)$;fastcgi_param PATH_INFO $fastcgi_path_info;fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;}# 禁止访问 .htaccess 文件location ~ /\.ht {deny all;}
}

4、实践建议

4.1、模块化配置

将不同功能的配置拆分到单独文件中,通过 include 指令引入。

4.2、安全配置

server_tokens off;  # 隐藏Nginx版本号
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

4.3、性能优化

aio on;                     # 异步I/O
directio 4m;                # 大文件直接I/O
open_file_cache max=1000;   # 文件描述符缓存# 开启 gzip 压缩
gzip on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml application/javascript application/xml;
gzip_vary on;# 文件缓存配置
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|css|js|ico|woff|woff2|ttf|eot|svg|otf)$ {expires 30d;add_header Cache-Control"public";access_log off;
}# 商品页面缓存
# 对于商品页面,可以缓存一部分动态内容,如价格和评论数量,以提高响应速度并减少对后端的压力,
# 通过proxy_cache_valid 200 10m配置,缓存200状态码的响应10分钟,避免频繁访问后端获取相同数据。
location /product/{proxy_cache cache_zone;proxy_cache_key $uri;proxy_cache_valid 200 10m;proxy_cache_valid 404 1m;proxy_cache_use_stale error timeout updating;
}# API响应缓存,对于电商网站的API接口,可能会有一些数据变化不频繁,可以进行缓存
# 通过上述缓存策略,Nginx帮助电商网站提高了性能,减少了后端负担,提升了用户的访问速度和体验
location /api/{proxy_cache cache_zone;proxy_cache_valid 200 5m;proxy_cache_use_stale error timeout updating;
}

4.4、错误处理

error_page 404 /custom_404.html;
location = /custom_404.html {internal;root /usr/share/nginx/html;
}

错误页面说明

当客户端请求资源时,如果服务器遇到问题或无法满足请求,它会返回一个HTTP状态码来表示具体的情况。常见的HTTP状态码包括:

  • 404 Not Found: 请求的资源未找到。
  • 500 Internal Server Error: 服务器内部错误。
  • 502 Bad Gateway: 作为网关或代理服务器从上游服务器收到无效响应。
  • 503 Service Unavailable: 由于临时维护或过载,服务器暂时无法处理请求。
  • 504 Gateway Timeout: 作为网关或代理服务器未及时从上游服务器收到响应。

设置自定义错误页面

在Nginx中,你可以使用error_page指令来指定对于特定HTTP状态码应该显示的错误页面。

基本语法

error_page code [code...] =new_code uri;
  • code: 要处理的HTTP状态码,可以是一个或多个。
  • =new_code: 可选参数,允许你更改返回给客户端的状态码(不常用)。
  • uri: 当发生指定的错误时要使用的错误页面的位置。

示例配置

  • 简单示例:为最常见的几个错误代码设置自定义错误页面。

    server {listen 80;server_name example.com;error_page 404 /404.html;error_page 500 502 503 504 /50x.html;location / {root /var/www/example.com/html;index index.html;}# 定义错误页面的位置location = /404.html {root /var/www/example.com/errors;}location = /50x.html {root /var/www/example.com/errors;}
    }
    

    在这个例子中:

    • 对于404 Not Found错误,将返回/var/www/example.com/errors/404.html文件。
    • 对于500, 502, 503, 504错误,将返回/var/www/example.com/errors/50x.html文件。
  • 重定向到外部URL:如果你想让用户在遇到错误时被重定向到另一个站点上的错误页面。

    server {listen 80;server_name example.com;error_page 404 = http://example.com/error-page-not-found;error_page 500 502 503 504 = http://example.com/error-page-server-error;
    }
    
  • 动态生成错误页面:如果你希望通过后端应用动态生成错误页面,可以将请求转发给FastCGI或其他后端服务。

    server {listen 80;server_name example.com;error_page 404 /dynamic_404;location = /dynamic_404 {fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;include fastcgi_params;}
    }
    
  • 返回不同状态码:有时候你可能想改变返回给客户端的状态码。例如,将所有404错误改为返回200状态码(虽然通常不推荐)。

    server {listen 80;server_name example.com;error_page 404 =200 /custom_404.html;location = /custom_404.html {root /var/www/example.com/errors;}
    }
    

4.5、日志分割

当Nginx的访问日志文件变得过大时,这不仅会占用大量的磁盘空间,还可能影响到服务器性能和日志分析效率。处理过大的访问日志文件通常采用**日志轮转(log rotation)**的方法。日志轮转可以定期重命名旧的日志文件,并通知Nginx重新打开新的日志文件以继续记录新产生的日志信息。

logrotate 是一个非常流行的用于管理日志文件的工具,它可以自动完成日志文件的轮转、压缩、删除旧日志等操作。

通常,logrotate 的 Nginx 配置文件位于 /etc/logrotate.d/nginx 或者你可以创建一个新的配置文件。下面是一个基本的配置示例,使用 cron 任务和 logrotate 工具定期分割日志:

# 创建 logrotate 配置文件 /etc/logrotate.d/nginx
/var/log/nginx/*.log {dailymissingokrotate 52compressdelaycompressnotifemptycreate 0640 www-data admsharedscriptspostrotateif [ -f /var/run/nginx.pid ]; thenkill -USR1 `cat /var/run/nginx.pid`fiendscript
}/var/log/nginx/*.log {daily                        # 每天轮转一次missingok                    # 如果日志丢失,不报错rotate 14                    # 保留最近14个日志文件compress                     # 轮转后压缩日志文件delaycompress                # 延迟压缩,直到下一次轮转notifempty                   # 如果日志为空,则不轮转create 0640 www-data adm     # 创建新日志文件的所有者和权限sharedscripts                # 共享脚本执行(下面的postrotate脚本)postrotate[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`endscript
}
  • daily: 设置日志每天轮转。
  • missingok: 如果日志文件不存在,不要给出错误信息。
  • rotate 14: 只保留最近14个归档的日志文件,超过这个数量的老日志文件将被删除。
  • compress: 在轮转后压缩旧的日志文件。
  • delaycompress: 推迟压缩,直到下次轮转。这样,最新的归档文件不会被压缩,直到下一次轮转发生。
  • notifempty: 如果日志文件为空,则不进行轮转。
  • create: 定义新日志文件的权限和所有者。
  • postrotate/endscript: 在轮转完成后执行的命令。这里的命令是向Nginx发送一个USR1信号,让Nginx重新打开日志文件,以便开始写入新的日志文件。

如何测试 logrotate 配置

你可以使用以下命令手动运行 logrotate 并查看其输出,确保配置正确无误:

logrotate -d /etc/logrotate.d/nginx

-d 参数表示调试模式,它会显示 logrotate 将要做的事情但并不会真正执行任何操作。如果想要实际执行轮转,可以去掉 -d 参数直接运行。

4.6、多项目之单个server

示例如下:

server {listen 80;server_name yourdomain.com;location /project1/ {alias /path/to/your/nginx/html/project1/;try_files $uri $uri/ /index.html;}location /project2/ {alias /path/to/your/nginx/html/project2/;try_files $uri $uri/ /index.html;}location /project3/ {alias /path/to/your/nginx/html/project3/;try_files $uri $uri/ /index.html;}
}

解释

  • alias:指定实际的文件系统路径,注意这里使用的是 alias 而不是 root,因为对于 location /projectX/ 这样的配置,alias 更加适合。它会将 URL 路径中的 /projectX/ 部分替换为你指定的实际路径。
  • try_files:尝试找到请求的文件或目录。如果找不到,则回退到 index.html。这对于单页应用(SPA)特别有用,因为它允许路由处理未找到的文件。

4.7、多项目之多个server

每个 server 块可以对应一个特定的域名或子域名,并指向不同的项目目录。这种方式使得管理和扩展更加灵活,特别是当你有多个独立的项目需要以不同的域名访问时。

示例如下:

# Project 1 configuration
server {listen 80;server_name project1.yourdomain.com;root /path/to/your/nginx/html/project1;index index.html;location / {try_files $uri $uri/ /index.html;}
}# Project 2 configuration
server {listen 80;server_name project2.yourdomain.com;root /path/to/your/nginx/html/project2;index index.html;location / {try_files $uri $uri/ /index.html;}
}# Project 3 configuration
server {listen 80;server_name project3.yourdomain.com;root /path/to/your/nginx/html/project3;index index.html;location / {try_files $uri $uri/ /index.html;}
}

解释

  • server_name:指定每个项目的域名。确保你已经正确配置了DNS解析,将这些子域名指向你的服务器IP地址。

  • 其它:可以建立多个配置文件,然后使用 include 指令包含所有即可。

4.8、请求头缓存

Cache-Control 是 HTTP 响应头中的一个重要字段,用于定义请求和响应遵循的缓存机制。

它提供了多种指令来控制缓存的行为,包括但不限于浏览器缓存、代理服务器缓存等。

请求头可以包含多个指令,不同指令之间使用逗号分隔。

缓存行为控制

  • public:表示响应可以被任何缓存存储,包括中间代理服务器在内的公共缓存。
  • private:指示响应是针对单个用户的,不应由共享缓存(如代理服务器)存储。但允许客户端(如浏览器)进行缓存。
  • no-store:告知所有缓存不要存储关于客户端请求或服务器响应的任何内容。这对于包含敏感信息的响应特别有用。
  • no-cache:表示在使用缓存副本之前必须先向源服务器验证资源的有效性。注意,这并不意味着“不缓存”,而是要求每次都需要重新验证。

过期时间控制

  • max-age=:指定从现在开始到该资源被认为过期为止的最大秒数。例如,max-age=3600 表示资源将在一小时后过期。
  • s-maxage=:类似于 max-age,但它仅适用于共享缓存(如代理服务器),并且优先级高于 max-ageExpires 头。
  • min-fresh=:要求返回的资源至少在未来给定秒数内仍然新鲜。
  • max-stale[=]:指示客户端愿意接受已过期的响应,可选参数指定了客户端愿意接受的最大过期时间。

其他指令

  • must-revalidate:一旦资源过期,在再次使用前必须先向源服务器验证其有效性,不允许使用过期的数据。
  • proxy-revalidate:与 must-revalidate 类似,但是仅对共享缓存有效。
  • immutable:表示资源的内容不会随时间变化,因此如果已经缓存了该资源,则无需重新验证其有效性。这通常用于静态资源,如 CSS 和 JavaScript 文件。

4.9、下载文件配置

假如是/var/www/downloads 目录(下载目录配置),配置如下:

server {listen 80;server_name yourdomain.com;############## 1、使用 alias ##############location /downloads/ {alias /usr/share/nginx/html/files/;autoindex on; # 启用目录浏览autoindex_exact_size off; # 显示文件大小时更易读autoindex_localtime on; # 使用本地时间显示文件日期# 设置适当的默认类型default_type application/octet-stream;# 匹配多种文件类型并设置为附件下载if ($request_filename ~* ^.*?\.(jpg|jpeg|png|gif|pdf|txt|json|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$) {# 可选: 添加 Content-Disposition 头部,强制浏览器下载而不是尝试显示文件add_header Content-Disposition 'attachment';}}############## 2、使用 root ##############location /files/ {root /usr/share/nginx/html/;autoindex on; # 启用目录浏览autoindex_exact_size off; # 显示文件大小时更易读autoindex_localtime on; # 使用本地时间显示文件日期default_type application/octet-stream; # 设置适当的默认类型# 匹配多种文件类型并设置为附件下载if ($request_filename ~* ^.*?\.(jpg|jpeg|png|gif|pdf|txt|json|zip|rar|7z|doc|docx|xls|xlsx|ppt|pptx)$) {# 可选: 添加 Content-Disposition 头部,强制浏览器下载而不是尝试显示文件add_header Content-Disposition 'attachment';}}
}
  • alias:指定实际的文件系统路径。注意这里使用的是 alias 而不是 root。对于带有斜杠结尾的 location(如 /downloads/),alias 更适合,因为它会替换掉 location 匹配的部分。
  • autoindex on:启用目录列表功能,允许用户浏览目录内容。如果你不希望公开目录结构,则可以去掉这一行。
  • default_type application/octet-stream:设定默认 MIME 类型为二进制流,这样大多数浏览器会选择下载而不是直接打开文件。
  • add_header Content-Disposition ‘attachment’:强制浏览器总是提示下载文件,而不是试图直接在浏览器中打开它们。这对于确保所有类型的文件都被下载而不是被渲染非常重要。

注意事项

  • 权限控制:确保 Nginx 进程对 /var/www/downloads 目录及其子目录具有正确的读取权限。
  • 访问限制:考虑是否需要对某些敏感文件进行额外的安全措施,比如 IP 白名单、HTTP 基本认证等。
  • 文件验证:如果允许用户上传文件到下载目录,请务必检查文件名和内容以防止恶意文件上传导致的安全问题。

4.10、其它

  1. 精确匹配优先:确定唯一的路径使用 =
  2. 静态资源用 ^~:确保快速响应且不被其他规则干扰
  3. 动态内容用正则:复杂匹配需求使用 ~~*
  4. 通用路径普通前缀:不需要特殊处理的普通路径

5、常见错误排查

错误现象可能原因解决方法
nginx: [emerg] bind() to 0.0.0.0:80 failed端口被占用sudo lsof -i :80 查看占用进程并停止
配置修改后无生效未执行 nginx -s reload执行重载命令
502 Bad Gateway后端服务器不可用检查后端服务状态及 proxy_pass 配置
静态文件 404 错误文件权限或路径问题chown -R www-data:www-data /var/www
日志显示 too many open files文件描述符限制过低修改 /etc/security/limits.conf 增加限制

完毕。

http://www.lryc.cn/news/575634.html

相关文章:

  • Excel处理控件Aspose.Cells教程:如何使用 Java 将图片添加到 Excel
  • 从零构建vue3项目(二)
  • 机器学习在智能农业中的创新应用与未来趋势
  • 永磁无刷电机旋转原理
  • 进程和线程的区别?
  • 128.最长连续序列
  • 本地开发Anchor智能合约:效率翻倍的秘密
  • windows下 tomcat的安装部署
  • 机器学习17-发展历史补充
  • 第一章-人工智能概述-机器学习基础与应用(1/36)
  • spring-ai 1.0.0 (1)模型调用能力
  • day43 复习日(猫狗图像分类)
  • 算法第48天|单调栈:42. 接雨水、84.柱状图中最大的矩形
  • 从零开始理解百度语音识别API的Python实现
  • 抖音图文带货和短视频带货有什么区别
  • 深入解析设备管理系统新趋势:物联网与云原生驱动的智能化实践
  • OpenBayes 一周速览丨Nanonets-OCR-s深度语义理解,精准结构化转换;HLE人类问题推理基准上线,含2.5k题目,助力封闭式评估体系构建
  • COZE API上传文件 直接从前端发送就可以,而通过后端发请求给CozeAPI就不行,为什么?
  • 【百日精通JAVA | 数据结构篇】 一文了解泛型体系
  • 新手向:Anaconda3的安装与使用方法
  • AMS流媒体服务器-新版(h265-flv)
  • FFMpeg的AVFrame数据格式解析
  • IDE如何快速切换JLINK版本
  • vue 开启 source-map 后构建速度会很慢
  • Android杂谈(一):悬浮球
  • 随记:WebMvcConfigurationSupport 和WebMvcConfigurer 的区别
  • DevSecOps时代下测试工具的全新范式:从孤立到融合的质变之路
  • ubuntu22.04系统kubeadm部署k8s高可用集群
  • 伏羲微官网企业建站授权证书/防伪查询/三合一应用【前端开源】
  • 2D写实交互数字人如何重塑服务体验?