跳到主要内容

nginx 实战配置

小林
后端开发工程师, 专注Go开发、微服务和云原生

本文详解 nginx 核心配置结构,涵盖简单指令、块指令与context作用域层级。重点解析worker_processes、include等核心模块指令,以及静态资源服务、SPA部署、反向代理和负载均衡等实战配置

jetpack.png

示例

nginx.conf
user  nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;


events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
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 /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

配置文件结构

nginx 的配置文件由指令(directives)组成, 分为简单指令(simple directives)和块指令(block directives)

简单指令

简单指令由指令名称、参数和末尾分号 ; 组成, 名称和参数用空格分隔.

例如下面指令属于简单指令

user  nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;

块指令

块指令使用大括号 {} 包裹其他指令, 并且不用分号结尾, 这点跟 C 语言有点像

下面指令中 eventshttp 都属于块指令

events {
worker_connections 1024;
}


http {
include /etc/nginx/mime.types;
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 /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}

context

nginx 的一个块指令内部可以形成一个作用域, 称为 context

main context

没有被任何块指令包裹, 位于最外层的作用域称为 main context

示例

# main context

http {
# http context
server {
# server context
location {
# location context
}
}
}

模块

nginx 由模块组成, 每个模块有对应的指令用于配置模块的功能

nginx 内置以下核心模块, 用于配置 HTTP、邮件、TCP/UDP 服务

还有其他扩展模块, 详细列表可参考官方文档 Modules reference

core module

ngx_core_module 是 nginx 最核心的一个模块, 包含 nginx 最基础的指令, 用于配置 nginx 的全局参数

基础配置指令

  • user - 定义 worker 进程运行的用户和组
  • worker_processes - 设置 worker 进程数量(可设为具体数值或 auto)
  • error_log - 配置错误日志文件路径和日志级别
  • pid - 指定存储主进程 PID 的文件路径
  • include - 包含其他配置文件或匹配特定掩码的文件
  • env - 保留、修改或创建环境变量
  • daemon - 确定 Nginx 是否以守护进程方式运行

进程管理指令

  • master_process - 控制是否启动 worker 进程
  • worker_cpu_affinity - 将 worker 进程绑定到特定 CPU 核心
  • worker_priority - 设置 worker 进程的调度优先级
  • worker_rlimit_core - 设置 core 文件大小限制
  • worker_rlimit_nofile - 设置 worker 进程可打开文件描述符数量限制
  • worker_shutdown_timeout - 配置 worker 进程优雅关闭的超时时间
  • working_directory - 定义 worker 进程的工作目录

高级功能指令

  • load_module - 加载动态模块(.so 文件)
  • thread_pool - 定义用于多线程读取和发送文件的线程池
  • pcre_jit - 启用或禁用正则表达式的"即时编译"功能
  • timer_resolution - 降低 worker 进程中的计时器精度
  • lock_file - 指定锁文件前缀(用于实现 accept_mutex 等功能)
  • ssl_engine - 定义硬件 SSL 加速器名称
  • ssl_object_cache_inheritable - 配置 SSL 对象在配置重载时是否继承

调试相关指令

  • debug_points - 用于内部错误检测时创建 core 文件或停止进程
  • debug_connection - 为特定客户端连接启用调试日志

include

需要特别介绍一下 include 指令, 它允许将配置拆分为多个文件,实现配置的模块化管理

基础语法

include file | mask;
  • file: 单个配置文件的绝对/相对路径(如 mime.types)
  • mask: 支持通配符的文件匹配模式(如 conf.d/*.conf)
  • include 指令可以在任何上下文(context)中使用

下面是基于 include 指令进行模块化管理的最佳实践

标准目录结构

/etc/nginx/
├── nginx.conf # 主配置
├── conf.d/ # 通用配置
│ ├── gzip.conf
│ └── security.conf
├── sites-available/ # 所有站点配置
│ ├── example.com.conf
│ └── api.example.com.conf
└── sites-enabled/ # 启用的站点(软链接到 sites-available)
└── example.com.conf → ../sites-available/example.com.conf
nginx.conf
http {
include mime.types;
include conf.d/*.conf;
include sites-enabled/*.conf;
}

HTTP module

HTTP 的核心模块为 ngx_http_core_module

最简配置

nginx.conf
events {}

http {
server {
location / {}
}
}

配置说明

  • http
    所有 HTTP/HTTPS 服务相关配置必须置于 http 块内. 该块作为核心配置层级, 用于定义全局 HTTP 规则(如 MIME 类型、默认内容类型等)
  • server
    定义虚拟主机(Virtual Host), 用于处理特定域名或端口的请求. 当前配置中省略了 listenserver_name 指令, 因此将采用以下默认值:
    • listen: 默认监听 80 端口(HTTP 标准端口)
    • server_name: 默认为空字符串, 可匹配所有未明确指定的域名(即通过 IP 地址或任意域名访问的请求)
  • location
    定义 URI 路径匹配规则, 然后返回块内的文件给到请求, 其中 / 表示匹配所有请求路径. 当前配置中:
    • root: 未显式配置时, 默认路径为 html
    • index: 未指定时, 默认索引文件为 index.html

上面配置的实际效果

  • 用户访问 http://ip:80/index.html(可省略为 http://ip), 返回 html/index.html 文件内容

添加页面

mkdir html && echo "Hello, world!" > html/index.html

访问页面

img

完整的配置如下

http {
server {
listen 80;
server_name "";
location / {
root html;
index index.html;
}
}
}

静态资源服务

nginx 可作为静态资源服务, 配置如下

server {
location / {
root /data/www;
}

location /images/ {
root /data;
}

# 匹配 .gif .jpg .png 扩展名结尾
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}

单页面应用

单页面应用(如 React/Vue/Angular)使用前端路由, 所有路径(如 /about、/dashboard)均由前端 JavaScript 处理, 服务器上不存在对应物理路径

默认配置下, 当用户直接访问 /about 时, nginx 会尝试查找服务器上的 /about 目录或文件, 由于文件不存在会返回 404 错误

配置单页面应用需要使用 try_files 指令, 该指令会在找不到文件时返回一个兜底路径, 这样就能将找不到静态资源的请求都返回到 index.html 页面, 交由前端路由处理

server {
location / {
root html;
index index.html;
try_files $uri $uri/ /index.html;
}
}

反向代理

可以使用 proxy_pass 指令将请求代理到后端服务

server {
location /api {
proxy_pass http://localhost:8080/;
}
}

负载均衡

负载均衡可以将请求代理到多个后端实例, 实现服务的高可用

nginx 使用 uptream 指令实现负载均衡, 通过定义后端服务器组实现流量分发

http {
upstream myapp1 {
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://myapp1; # 指向upstream定义的组
}
}
}

nginx 负载均衡支持三种算法, 包括

  • 轮询(round-robin): 依次将请求分配给每个服务器, 支持按权重比例分配请求, nginx 默认使用轮询算法
  • 最少连接(least-connected): 将请求分配给当前活跃连接数最少的服务器
  • IP哈希(ip-hash): 根据客户端 IP 计算哈希值, 固定分配到特定服务器
配置最少连接算法
    upstream myapp1 {
least_conn;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
配置 IP 哈希算法
upstream myapp1 {
ip_hash;
server srv1.example.com;
server srv2.example.com;
server srv3.example.com;
}
配置加权轮询
    upstream myapp1 {
server srv1.example.com weight=3;
server srv2.example.com;
server srv3.example.com;
}

nginx 自带健康检查机制, 如果某个服务实例不可用, nginx 会将其标记为不可用, 并在一段时间内避免将后续的传入请求分发至该服务器

SSL module

nginx 的 SSL 加密由 ngx_http_ssl_module 模块提供

server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate www.example.com.crt;
ssl_certificate_key www.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}

为确保所有流量都通过HTTPS, 应设置 HTTP 到 HTTPS 的重定向

server {
listen 80;
server_name default_server;
return 301 https://$host$request_uri;
}

参考