Nginx使用教程
在后端架构与服务端运维中,Nginx 是一款轻量级、高性能的 HTTP 和反向代理 web 服务器。根据官方的设计规范与日常高频使用场景,Nginx 的核心功能总共可被归纳为四大类:
- 1. 基础 Web 服务器(Web Server):指的是 Nginx 自身可以直接作为静态资源服务器,高效处理 HTML、CSS、图片等静态文件的访问请求;
- 2. 反向代理(Reverse Proxy):指的是 Nginx 作为前端服务器接收客户端请求,再将其隐式地转发给内网真正的后端服务进行处理,从而保护隐藏后端并实现灵活路由;
- 3. 负载均衡(Load Balancing):指的是当后端有多个应用实例时,Nginx 通过特定算法将大量的并发请求均匀或按需分发到不同的服务器上,缓解单节点压力;
- 4. 动静分离(Static/Dynamic Separation):指的是利用 Nginx 的路由匹配能力,将动态请求(如 API 接口)转发给后端(如 Tomcat/Node.js),而静态请求直接由 Nginx 响应,最大化利用各自的处理优势。
(注:Nginx 同样支持邮件代理(IMAP/POP3)和 TCP/UDP 层的代理处理,但日常 Web 领域主要高频使用上述几类。在进行具体的配置前,我们需要先掌握 Nginx 的基础架构与配置文件组成。)
一. Nginx的架构特性与运行机制
Nginx 之所以具备极高的并发处理能力,得益于其基于事件驱动(Event-driven)的异步非阻塞机制,以及多进程的 Master-Worker 架构。
1. Master-Worker 多进程模型
Nginx 在启动后,会在后台运行一个Master进程和多个Worker进程。
- Master 进程(主进程) :主要负责读取和评估配置,以及管理 Worker 进程(如接收重载信号、启动/重启/停止 Worker 进程)。它本身不处理网络请求。
- Worker 进程(工作进程) :实际处理来自客户端的网络请求。Worker 进程的数量通常会被配置为与服务器的 CPU 核心数一致,从而将上下文切换的损耗降到最低。
(注:多个 Worker 进程之间是相互独立的。如果某个请求导致一个 Worker 进程异常崩溃,其他 Worker 进程依然可以正常对外提供服务,Master 进程也会迅速拉起一个新的 Worker 进程。)
二. 常用基础控制操作
日常对 Nginx 的操作基本集中在服务的启停、配置文件的重载以及语法校验上。
1. 基础命令行指令
(1). start & stop & quit & reload - 服务的启停与重载
作用:对 Nginx 服务执行启动、强制停止、优雅退出、平滑重载配置操作。
bash
nginx # 启动服务
nginx -s stop # 强制停止服务 (快速关闭,不等待请求处理完)
nginx -s quit # 优雅停止服务 (等待当前正在处理的请求结束后关闭)
nginx -s reload # 平滑重载配置 (无需重启服务,让新配置生效)
参数:
- -s (signal): 向 Master 进程发送信号操作。
(2). test - 配置文件校验
作用:在修改完 nginx.conf 后,测试配置文件的语法是否正确,以防直接 reload 导致服务宕机。
bash
nginx -t # 测试默认路径下的配置文件并输出结果
nginx -T # 测试配置文件并把具体配置内容打印到屏幕
返回值:
- 成功: 终端输出
nginx: configuration file /etc/nginx/nginx.conf test is successful即代表语法正确。
三. Nginx配置文件 (nginx.conf) 与目录结构
Nginx 的核心配置系统是由层次分明的模块(Block)组成的。整体可以自顶向下分为三大块:全局块、events 块和 http 块。
1. 核心层级解析
nginx
# 1. 全局块 (Global Block):配置影响 Nginx 全局的指令,如工作进程数、错误日志等。
worker_processes auto; # 根据 CPU 核心数自动生成对应的 Worker 进程数
# 2. Events 块 (Events Block):配置影响 Nginx 服务器或与用户的网络连接。
events {
worker_connections 1024; # 每个 Worker 进程支持的最大并发连接数
}
# 3. HTTP 块 (HTTP Block):Nginx 配置最核心的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
# 4. Server 块 (Server Block):配置虚拟主机的相关参数,一个 HTTP 块可以包含多个 Server 块。
server {
listen 80; # 监听端口
server_name localhost; # 监听的域名或 IP
# 5. Location 块 (Location Block):配置请求路由及页面处理策略。
location / {
root html; # 静态资源根目录
index index.html index.htm; # 默认首页
}
}
# 【核心解耦机制】导入外部独立配置文件
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
2. /etc/nginx/ 目录结构与解耦
在现代 Linux(如 Ubuntu/Debian)的生产环境中,为了方便维护,我们绝对不会把所有网站的 server 块都塞进主文件 nginx.conf 中。Nginx 利用 include 指令和特定的目录结构实现了完美解耦:
/etc/nginx/nginx.conf:全局主配置文件。只负责底层性能参数、日志格式设定等。/etc/nginx/sites-available/(可用站点仓库) :这是你写配置的地方! 这里存放着你所有项目的独立配置文件(如my_cpp_app,my_blog)。但是,放在这里的配置默认是不生效的。/etc/nginx/sites-enabled/(已启用站点展示柜) :这是 Nginx 真正加载的地方! 我们通常通过命令,将sites-available里面的文件在此处创建一个软链接(快捷方式)。想下线网站,直接删掉快捷方式即可,配置原文件依然保留在可用仓库中。
四. 路由匹配运算 (Location Ops)
Location 指令是 Nginx 中最重要的路由匹配规则,用于根据用户请求的 URI 来决定如何处理该请求。
1. Location 的匹配修饰符与优先级
| 匹配符 | 语法示例 | 描述与匹配规则 | 优先级 |
|---|---|---|---|
= |
location = /api |
精确匹配:请求的 URI 必须和设定的字符串严格一样。 | 最高 (1) |
^~ |
location ^~ /static/ |
普通前缀匹配(非正则) :如果匹配到此规则,则停止后续所有的正则匹配搜索。 | 较高 (2) |
~ |
location ~ \.png$ |
区分大小写的正则匹配:常用于匹配特定后缀的文件。 | 中等 (3) |
~* |
location ~* \.png$ |
不区分大小写的正则匹配。 | 中等 (3) |
| 无 | location / |
通用前缀匹配:当所有规则都无法匹配时,作为保底方案。(也叫默认匹配)。 | 最低 (4) |
总结匹配机制:精确匹配 = 最优先 -> 接着匹配长前缀,若带有 ^~ 则终止正则 -> 若没有 ^~ 则记住最长前缀并继续搜索正则 ~ 或 ~* -> 若正则匹配成功则使用正则,若失败则退回使用最长前缀。
示例:
nginx
server {
listen 80;
server_name example.com;
# 1. 只有访问 http://example.com/ 才能命中此条
location = / {
return 200 "Exact match";
}
# 2. 访问 /images/a.jpg 等所有以 /images/ 开头的路径 (匹配后立即停止后续正则匹配)
location ^~ /images/ {
root /data/www;
}
# 3. 区分大小写的正则,匹配 .gif, .jpg, .jpeg 结尾的请求
location ~ \.(gif|jpg|jpeg)$ {
root /data/images;
}
}
五. 核心应用实战运算 (Core Applications)
1. 反向代理 (Reverse Proxy)
(1). proxy_pass - 转发请求运算
作用:将前端接收到的客户端 HTTP 请求,隐式转发给后端的实际处理服务器(如 C++ 后端 / Node.js 等)。
nginx
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
参数与避坑说明:
- 代理地址 (proxy_pass): 填入后端服务的完整 URL。
- 末尾斜杠 (/) 截断法则:这是 Nginx 反向代理最容易踩坑的地方!
- 如果
proxy_pass末尾带/: 如http://127.0.0.1:8080/。Nginx 会丢弃 掉 location 的匹配前缀/api/。客户端访问/api/user时,C++ 后端实际收到的是/user。 - 如果
proxy_pass末尾不带/: 如http://127.0.0.1:8080。Nginx 会原封不动保留前缀 。客户端访问/api/user时,C++ 后端实际收到的依然是/api/user。
2. 负载均衡 (Load Balancing)
(1). upstream - 服务器集群池构造
作用:定义一组后端服务器。结合 proxy_pass 使用,可以将流量按照设定的算法分散到这组服务器中。
nginx
upstream backend_pool {
# 默认算法:轮询 (Round Robin)
server 192.168.1.10:8080 weight=5; # weight:权重值,数字越大分配的流量越多
server 192.168.1.11:8080 weight=1;
server 192.168.1.12:8080 backup; # backup:备用节点,只有当其他节点全挂了才启用
}
server {
listen 80;
location / {
proxy_pass http://backend_pool; # 代理到上述集群池
}
}
常见负载均衡算法运算:
- 轮询 (Round Robin):默认规则,请求按时间顺序逐一分配到不同节点。
- 权重 (Weight) :人为干预,指定轮询几率,
weight和访问比率成正比。 - ip_hash :按照客户端 IP 的 hash 结果分配,可以解决由于负载均衡导致的 Session 跨域丢失问题。
六. 综合实战演练:将本地 C++ 后端程序与域名绑定
真实场景:你用 C++ 编写并编译了一个 HTTP 服务端程序(如 ./my_cpp_app),它在服务器后台本地监听了 8999 端口。现在,你需要让用户通过外网域名 http://app.chenzijian.com 访问到它。
步骤 1:确保 C++ 后端处于运行状态
首先,找到你的程序路径并在后台启动它(实际生产中通常会用 systemd 或 nohup 托管):
bash
./my_cpp_app 8999 &
步骤 2:在配置仓库中创建独立配置文件
进入 Nginx 的 sites-available 目录,为你的 C++ 项目专门新建一个文件:
bash
sudo nano /etc/nginx/sites-available/cpp_project
步骤 3:编写反向代理 Server 块
将以下内容写入该文件中。注意观察 proxy_set_header 的使用 ,由于 Nginx 挡在最前面,如果不加这些头信息,你的 C++ 后端看到的访问者 IP 将永远是 127.0.0.1:
nginx
server {
# 监听 80 端口 (HTTP默认端口)
listen 80;
# 绑定你的真实域名
server_name app.chenzijian.com;
# 路由所有请求 (/)
location / {
# 核心:将流量无缝转发给本地跑在 8999 端口的 C++ 程序
proxy_pass http://127.0.0.1:8999;
# 核心请求头设置:将客户端的真实信息透传给 C++ 后端
proxy_set_header Host $host; # 传递用户请求的真实域名
proxy_set_header X-Real-IP $remote_addr; # 传递用户的真实公网 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递链路 IP
}
}
步骤 4:创建软链接以"激活"配置
配置文件写好后,它只是在仓库里。我们需要把它链接到展示柜 (sites-enabled) 才能生效:
bash
sudo ln -s /etc/nginx/sites-available/cpp_project /etc/nginx/sites-enabled/
步骤 5:语法校验并平滑重载
最后,永远记得在重启前测试语法,然后重载服务让刚才绑定的域名上线:
bash
sudo nginx -t # 必须看到 test is successful
sudo nginx -s reload # 平滑重载配置,不影响其他正在运行的网站
部署完成!此时用户在浏览器输入 http://app.chenzijian.com,Nginx 就会自动接管请求,并悄悄将其送达给你内部的 C++ 守护进程 (127.0.0.1:8999) 处理了。