Nginx
开篇:互联网的"前台接待员"
每天有无数请求涌向你的服务器,但后端应用往往只能处理有限的并发。这时候就需要一个"前台接待员" -- 静态文件自己处理,动态请求转发给后端,还能在多台服务器之间做调度。这个接待员,就是 Nginx。
Nginx 是一款高性能的反向代理服务器,占用内存小、并发能力强,能支持 5 万以上的并发连接。它是当今互联网架构中几乎无处不在的基础组件。
和 Node.js 相比,Nginx 擅长底层服务器资源的处理(静态资源、连接管理),Node.js 更擅长上层业务逻辑的处理。
正向代理 vs 反向代理
代理是 Nginx 的核心能力,但"正向"和"反向"经常让人混淆。记住一句话:给谁做代理,就叫什么代理。
正向代理:客户端向代理服务器发送请求并指定目标服务器,由代理去和目标服务器通信。真实客户端对服务器不可见。典型场景:科学上网、企业内网通过代理访问外网。
反向代理:客户端发送请求到 Nginx,Nginx 再把请求转发给后端的真实服务器,并将响应返回给客户端。真实服务器对客户端不可见。典型场景:负载均衡、隐藏后端架构。
| 对比项 | 正向代理 | 反向代理 |
|---|---|---|
| 代理对象 | 客户端 | 服务器 |
| 谁被隐藏 | 客户端对服务器不可见 | 服务器对客户端不可见 |
| 典型场景 | 科学上网、企业代理 | 负载均衡、隐藏后端 |
| 配置方 | 客户端配置代理 | 服务端配置代理 |
| 一句话 | 我知道我要访问谁,但让代理帮我去 | 我不知道最终是谁处理的 |
负载均衡
当单台服务器扛不住流量时,我们会部署多台服务器组成集群。Nginx 把请求分发到不同服务器上,就是负载均衡。
Nginx 支持多种负载均衡策略:
| 策略 | 配置关键字 | 说明 | 适用场景 |
|---|---|---|---|
| 轮询 | 默认 | 按顺序依次分发 | 服务器配置相同 |
| 加权轮询 | weight=3 | 性能好的分配更多请求 | 服务器配置不同 |
| IP Hash | ip_hash | 同一 IP 始终打到同一台 | 需要 Session 保持 |
| 最少连接 | least_conn | 优先分给连接数最少的 | 请求处理时间差异大 |
| URL Hash | hash $request_uri | 相同 URL 打到同一台 | 缓存命中率优化 |
upstream backend {
ip_hash;
server 192.168.1.10:8080 weight=3;
server 192.168.1.11:8080 weight=2;
server 192.168.1.12:8080 weight=1 backup; # 备用节点,正常时不参与
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}动静分离
Nginx 天生擅长处理静态资源(HTML、CSS、JS、图片),但对动态请求(Java、Python 后端逻辑)无能为力。动静分离就是让 Nginx 直接返回静态文件,只把动态请求转发给后端应用。
server {
listen 80;
server_name example.com;
# 静态资源 -- Nginx 直接处理
location /static/ {
root /usr/share/nginx/html;
expires 30d; # 浏览器缓存30天
access_log off; # 关闭日志减少IO
}
# 图片资源
location ~* \.(jpg|jpeg|png|gif|ico|svg)$ {
root /usr/share/nginx/html;
expires 7d;
}
# 动态请求 -- 转发给后端
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}好处很明显:静态资源走 Nginx 的高并发能力 + 缓存,后端专注处理业务逻辑,整体性能大幅提升,单个服务器的压力也降低了。
Nginx 核心配置
Nginx 的配置文件结构清晰,分为全局块、events 块和 http 块三层:
# ---- 全局块 ----
user nginx; # 运行用户
worker_processes auto; # 工作进程数,auto=CPU核数
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
# ---- events 块 ----
events {
use epoll; # Linux 高性能 I/O 模型
worker_connections 1024; # 每个进程最大连接数
}
# ---- http 块 ----
http {
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent';
access_log /var/log/nginx/access.log main;
sendfile on; # 高效文件传输
tcp_nopush on; # 减少网络报文段数量
keepalive_timeout 65; # 长连接超时
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf; # 加载子配置
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
deny 172.168.22.11; # 禁止某个 IP
allow 172.168.33.44; # 允许某个 IP
}
error_page 500 502 503 504 /50x.html;
}
}常用命令
# 安装
yum install nginx # CentOS
apt install nginx # Ubuntu
# 日常操作
systemctl start nginx # 启动
systemctl stop nginx # 停止
systemctl restart nginx # 重启
systemctl reload nginx # 重新加载配置(平滑重启,不中断服务)
systemctl status nginx # 查看状态
systemctl enable nginx # 开机自启
# 配置检测
nginx -t # 检测配置文件语法是否正确
nginx -T # 检测并打印完整配置location 匹配规则
location 是 Nginx 配置的核心,理解匹配优先级非常重要(从高到低):
| 优先级 | 符号 | 含义 | 示例 |
|---|---|---|---|
| 1 | = | 精确匹配 | location = /login { ... } |
| 2 | ^~ | 前缀匹配,命中后不再检查正则 | location ^~ /static/ { ... } |
| 3 | ~ | 正则匹配(区分大小写) | location ~ \.php$ { ... } |
| 4 | ~* | 正则匹配(不区分大小写) | `location ~* .(jpg |
| 5 | 无符号 | 普通前缀匹配 | location /api/ { ... } |
Docker 安装 Nginx
生产环境常用 Docker 部署 Nginx:
# 创建挂载目录
mkdir -p /mydata/nginx/{html,logs,conf}
# 启动(挂载配置、页面、日志目录)
docker run -d -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
nginx:1.24面试高频问答
Q1: Nginx 的主要使用场景有哪些?
关键词:反向代理、负载均衡、动静分离、安全网关
Nginx 最常见的四个场景:(1) 反向代理,隐藏后端服务器;(2) 负载均衡,分发请求到多台服务器;(3) 动静分离,静态资源直接返回,动态请求转发后端;(4) 安全网关,做访问控制(IP 黑白名单)、限流、SSL/HTTPS 终结。
Q2: 正向代理和反向代理的区别?
关键词:代理对象不同、隐藏对象不同
简单记:给谁做代理就叫什么代理。正向代理代理客户端,隐藏真实客户端,典型场景是科学上网。反向代理代理服务器,隐藏真实服务器,典型场景是负载均衡和安全隔离。
Q3: Nginx 怎么实现负载均衡?有哪些策略?
关键词:upstream、轮询、加权、IP Hash、最少连接
通过 upstream 定义后端服务器组,在 location 中用 proxy_pass 转发。常用策略:轮询(默认,按顺序分发)、加权轮询(weight,按性能分配)、IP Hash(同一 IP 固定打到同一台,解决 Session 问题)、最少连接(least_conn,优先分给负载最轻的)。还可以设置 backup 节点做容灾,down 标记节点下线。
小结
Nginx 是互联网架构的"瑞士军刀"。反向代理隐藏后端、负载均衡分流请求、动静分离提升性能 -- 掌握这三板斧就能应对大多数面试和实际场景。核心思想是分工协作:Nginx 擅长处理大量并发连接和静态资源,业务逻辑交给后端应用,各司其职才能发挥最大效能。