前言

在现代 Web 架构中,Nginx 是一个你无论如何都绕不开的名字。它如同一位身手不凡的瑞士军刀,以其卓越的性能、稳定性和丰富的功能,在全球超过三分之一的网站中扮演着至关重要的角色。无论你是后端开发者、运维工程师,还是一个希望深入了解网站如何工作的技术爱好者,掌握 Nginx 都是一项非常有价值的技能。

本文深度学习并提炼了优秀的开源教程 dunwu/nginx-tutorial 的精华,旨在为你提供一份从零开始、内容详尽、直击核心的 Nginx 学习指南。让我们一起揭开 Nginx 的神秘面纱,看看它究竟是如何工作的。

一、Nginx 是什么?为什么选择它?

Nginx (发音为 “engine-x”) 首先是一个高性能的 HTTP 和反向代理 Web 服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器

与传统的 Apache 服务器不同,Nginx 采用了一种完全不同的架构模型:事件驱动、异步非阻塞

  • 传统模型 (如 Apache):每个请求都会创建一个新的进程或线程来处理。当并发连接数非常高时,会消耗大量的内存和 CPU 资源,导致服务器性能急剧下降。
  • Nginx 模型:一个工作进程 (worker process) 就可以处理成千上万个并发连接。它通过一个高效的事件循环机制(如 epoll, kqueue)来监听和处理网络事件,只有当一个事件(如新的连接、数据可读/可写)发生时,才会去处理它,处理完后立刻释放资源去响应下一个事件。

正是这种先进的架构,赋予了 Nginx 以下核心优势:

  1. 高并发、高性能:在处理大量并发连接时,Nginx 的内存和 CPU 占用极低。官方数据显示,它可以轻松支持数万甚至数十万的并发连接。
  2. 高可靠性:Nginx 的架构稳定,且主工作进程和 worker 工作进程分离,一个 worker 进程的异常不会影响到其他进程。
  3. 高扩展性:Nginx 的功能通过模块化的方式组织,你可以根据需要轻松添加或移除模块。
  4. 热部署:可以在不停止服务的情况下,平滑地升级 Nginx 版本、更换日志文件、更新配置文件。

二、Nginx 的安装与核心命令

在大多数 Linux 发行版中,安装 Nginx 都非常简单。

在 Debian/Ubuntu 系统中:

1
2
sudo apt update
sudo apt install nginx

在 CentOS/RHEL 系统中:

1
2
sudo yum install epel-release
sudo yum install nginx

安装完成后,你可以使用 systemd 来管理 Nginx 服务:

  • sudo systemctl start nginx:启动 Nginx
  • sudo systemctl stop nginx:停止 Nginx
  • sudo systemctl restart nginx:重启 Nginx
  • sudo systemctl reload nginx平滑重载配置 (推荐,在不停止服务的情况下让新配置生效)
  • sudo systemctl enable nginx:设置开机自启
  • sudo systemctl status nginx:查看 Nginx 状态

在操作配置文件后,一个至关重要的命令是检查配置语法是否正确:

1
sudo nginx -t

如果看到 syntax is oktest is successful 的提示,说明你的配置没有语法错误,可以安全地 reload

三、Nginx 配置文件的核心结构

Nginx 的所有魔力都蕴含在它的配置文件中。默认的配置文件通常位于 /etc/nginx/nginx.conf

一个典型的 nginx.conf 文件结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 全局块
user www-data;
worker_processes auto; # worker 进程数,通常设置为 auto 或 CPU 核心数
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

# events 块
events {
worker_connections 768; # 每个 worker 进程的最大连接数
}

# http 块
http {
# --- http 全局配置 ---
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
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;
error_log /var/log/nginx/error.log;

# Gzip 压缩配置
gzip on;
gzip_vary on;
gzip_proxied any;
# ... 其他 gzip 配置

# --- 虚拟主机 (Server) 配置 ---
# 使用 include 指令来加载其他配置文件,保持主文件整洁
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

这个结构可以分为三个主要部分:

  1. 全局块 (Global Block):配置影响 Nginx 全局的指令,例如运行 Nginx 的用户、工作进程数等。
  2. Events 块:配置影响 Nginx 服务器与用户网络连接的指令,例如每个工作进程的最大连接数。
  3. HTTP 块:这是配置最频繁的部分,它包含了对 HTTP 协议的所有配置。HTTP 块内部又可以包含多个 Server 块
    • Server 块:也称为“虚拟主机”,它定义了一个具体的网站或应用。通过 listen (监听端口) 和 server_name (域名) 来区分不同的虚拟主机。
    • Location 块:Server 块中最核心的部分。它根据用户请求的 URI 来匹配不同的规则,并执行相应的处理指令(如返回文件、代理到后端服务等)。

四、Nginx 的核心应用场景(附配置实例)

1. 静态资源 Web 服务器

这是 Nginx 最基本的功能。假设你的网站静态文件(HTML, CSS, JS, 图片)都存放在 /var/www/my-website 目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80; # 监听 80 端口
server_name www.yourdomain.com; # 你的域名

# 配置网站根目录和默认主页
location / {
root /var/www/my-website;
index index.html index.htm;
}

# 配置错误页面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

这个配置意味着,当用户访问 http://www.yourdomain.com/ 时,Nginx 会去 /var/www/my-website 目录下查找 index.htmlindex.htm 并返回给用户。

2. 反向代理 (Reverse Proxy)

反向代理是 Nginx 最重要的应用场景。它作为客户端和后端真实服务器之间的中间人,接收客户端请求,然后转发给后端的应用服务器(如 Node.js, Python, Java 应用),并将后端服务器的响应返回给客户端。

这样做的好处是:

  • 隐藏后端服务:客户端只与 Nginx 通信,不知道后端服务器的具体细节,增加了安全性。
  • 统一入口:所有请求都通过 Nginx,方便进行统一的日志记录、安全控制和负载均衡。

假设你有一个在本地 8080 端口运行的 Node.js 应用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
listen 80;
server_name api.yourdomain.com;

location / {
# 将所有请求转发给 http://127.0.0.1:8080
proxy_pass http://127.0.0.1:8080;

# 设置一些重要的代理头信息
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

3. 负载均衡 (Load Balancing)

当你的网站流量巨大,单个应用服务器无法承受时,就需要部署多个服务器组成集群。负载均衡就是将进来的请求平均分配到集群中的多个服务器上,从而提高整个系统的处理能力和可用性。

Nginx 使用 upstream 模块来实现负载均衡。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 定义一个名为 "backend_servers" 的上游服务器集群
upstream backend_servers {
# 默认是轮询 (round-robin) 策略
server 192.168.1.100:8080;
server 192.168.1.101:8080;
server 192.168.1.102:8080;
}

server {
listen 80;
server_name www.yourdomain.com;

location / {
# 将请求转发到定义的服务器集群
proxy_pass http://backend_servers;
}
}

Nginx 支持多种负载均衡策略:

  • round-robin (轮询):默认策略,按顺序逐一分配。
  • least_conn (最少连接):将请求分配给当前连接数最少的服务器。
  • ip_hash (IP 哈希):根据请求的源 IP 地址进行哈希计算,确保来自同一个客户端的请求总是被分配到同一个后端服务器。这对于需要维持 session 的应用非常有用。

4. 配置 HTTPS (SSL/TLS)

在今天的互联网环境中,为网站启用 HTTPS 是必须的。你需要拥有一个 SSL 证书(可以通过 Let’s Encrypt 免费获取)。

假设你的证书文件是 fullchain.pem,私钥文件是 privkey.pem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
server {
listen 80;
server_name www.yourdomain.com;

# 将所有 HTTP 请求重定向到 HTTPS
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2; # 监听 443 端口,并启用 SSL 和 HTTP/2
server_name www.yourdomain.com;

# 配置证书和私钥的路径
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

# SSL/TLS 安全性优化配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:...'; # 使用推荐的加密套件
ssl_prefer_server_ciphers on;

location / {
root /var/www/my-website;
index index.html;
}
}

五、Location 匹配规则的深入理解

location 的匹配规则是 Nginx 配置中最灵活也最容易混淆的部分。掌握它至关重要。

Nginx 会按照以下顺序来查找匹配的 location:

  1. 精确匹配 (=)location = /path,必须与请求的 URI 完全相同。一旦匹配成功,立即停止搜索。
  2. 前缀匹配 (^~)location ^~ /path,以某个路径开头。一旦匹配成功,也立即停止搜索。这主要用于在正则匹配之前优先匹配某个常规路径。
  3. 正则表达式匹配 (~~*)
    • ~:区分大小写的正则匹配。
    • ~*:不区分大小写的正则匹配。
      Nginx 会按照配置文件中的书写顺序从上到下进行正则匹配,一旦匹配成功,就停止搜索。
  4. 常规前缀匹配location /path,不带任何修饰符。Nginx 会选择最长匹配的那个前缀。

匹配顺序总结:
( = ) > ( ^~ ) > ( ~~* ) > ( 最长前缀匹配 )

一个典型的例子是分离动态和静态请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
# ...
location / {
# 默认规则,所有未匹配到的请求都走这里,转发给后端应用
proxy_pass http://backend_servers;
}

location ~* \.(gif|jpg|jpeg|png|css|js)$ {
# 对所有以图片或 css/js 结尾的请求
# 使用正则匹配,并直接从本地文件系统返回
root /var/www/assets;
expires 30d; # 设置浏览器缓存 30 天
}
}

结语

我们从 Nginx 的核心理念出发,一路走过了安装、配置、核心命令,并深入探讨了其最重要的四大应用场景:静态服务器、反向代理、负载均衡和 HTTPS 配置。

Nginx 的功能远不止于此,它还包括强大的缓存、限流、URL 重写、访问控制等高级功能。但掌握了本文所述的核心知识,你已经足以应对 90% 以上的日常工作需求,并为进一步的深入学习打下了坚实的基础。

最好的学习方式永远是实践。去搭建你自己的服务,亲手修改配置,观察它的变化,解决遇到的问题。希望这篇指南能成为你探索 Nginx 世界的有力起点。

本文内容深度参考和学习了 GitHub 上的优秀开源项目:dunwu/nginx-tutorial,在此向原作者表示感谢。