0%

关于 Nginx 的那些事

Nginx 是一款高性能的 HTTP 和反向代理服务器,它以其高并发、高性能、低内存占用而闻名,在平时的工作中,我们也经常用到它,以下,就来总结一下 Nginx 相关的知识。

Nginx 的主要用途

Nginx 在后端架构中扮演着多种关键角色:

  • 静态资源服务: 直接提供图片、CSS、JavaScript、HTML 文件等静态资源,性能极高。

  • 反向代理 (Reverse Proxy): 这是 Nginx 最常用的功能之一,它接收客户端请求,然后将请求转发给后端的应用服务器(如 Tomcat、Node.js、Python Django/Flask 等),并将应用服务器的响应返回给客户端。优点: 隐藏后端服务器 IP、负载均衡、高安全性、统一入口。

  • 负载均衡 (Load Balancing): 将客户端请求分发到多个后端服务器,实现流量的均匀分配,提高系统的可用性和扩展性。

  • API 网关: 作为所有微服务的统一入口,处理认证、授权、限流、熔断等。

  • Web 服务器: 部署简单的 Web 应用。

  • HTTPS/SSL 终结: 负责处理 SSL/TLS 加密解密,将加密流量转换为明文转发给后端,减轻后端服务器的压力。

  • 动静分离: Nginx 处理静态资源,后端应用服务器处理动态请求,提高整体性能。

  • URL 重写与转发: 根据规则修改或重定向 URL。

Nginx 的架构

Nginx 的核心是其主从进程模型

  • Master Process (主进程):

    • 负责读取和验证配置文件。
    • 管理 Worker 进程的生命周期(启动、停止、重启)。
    • 处理端口绑定。
    • 在配置更改时,实现平滑升级。
  • Worker Processes (工作进程):

    • 所有实际的网络请求处理都在 Worker 进程中完成。
    • 每个 Worker 进程都是单线程的。
    • 采用事件驱动模型(如 epoll、kqueue),能够在一个线程内高效处理大量并发连接。当一个请求到达时,Worker 进程不会为它创建一个新线程,而是将请求注册到事件循环中,然后继续处理其他请求。当数据准备好时,事件循环会通知 Worker 进程处理该请求。
    • Worker 进程之间通过共享内存通信(例如共享一些配置信息、缓存数据)。

Nginx 常用配置

Nginx 的配置非常灵活,主要通过 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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 全局块:配置影响 Nginx 服务器整体运行的参数
user nginx; # 工作进程运行用户
worker_processes auto; # 工作进程数,auto 表示根据 CPU 核心数自动调整

error_log /var/log/nginx/error.log warn; # 错误日志路径及级别
pid /var/run/nginx.pid; # Nginx Master 进程 PID 文件

events {
# 事件块:配置 Nginx 工作模式和连接数上限
worker_connections 1024; # 每个工作进程的最大连接数
use epoll; # 使用 epoll 事件模型 (Linux)
}

http {
# HTTP 块:配置 HTTP 服务器相关参数
include mime.types; # 引入 MIME 类型映射文件
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; # 开启高效传输模式
keepalive_timeout 65; # 长连接超时时间

# gzip on; # 开启 Gzip 压缩

# server 块:定义一个虚拟主机
server {
listen 80; # 监听端口
server_name localhost; # 域名或 IP 地址

# location 块:定义请求的路由规则
location / {
root /usr/share/nginx/html; # 静态文件根目录
index index.html index.htm; # 默认索引文件
}

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

# 反向代理示例
location /api/ {
proxy_pass http://backend_servers; # 转发到名为 backend_servers 的上游服务器组
proxy_set_header Host $host; # 传递原始Host头
proxy_set_header X-Real-IP $remote_addr; # 传递真实客户端IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递代理链中的所有IP
proxy_connect_timeout 60s; # 连接后端超时
proxy_send_timeout 60s; # 发送数据超时
proxy_read_timeout 60s; # 读取数据超时
}
}

# upstream 块:定义后端服务器组,用于负载均衡
upstream backend_servers {
# 负载均衡策略:默认是轮询 (Round Robin)
# weight:权重,weight越大分配的请求越多
# ip_hash:按客户端IP哈希,保证同一客户端请求总是发到同一服务器
# least_conn:最少连接数
# fair (第三方模块):响应时间最短
server 192.168.1.100:8080 weight=5; # 后端服务器1
server 192.168.1.101:8080 weight=1; # 后端服务器2
server 192.168.1.102:8080 backup; # 备用服务器
}
}

常用指令解释

  • user: 指定 worker 进程运行的用户和组。

  • worker_processes: 启动多少个 worker 进程。通常设置为 auto 或 CPU 核心数。

  • error_log: 错误日志路径和级别。

  • pid: Nginx master 进程的 PID 文件。

  • events: 配置 Nginx 的工作模式和最大连接数。

    • worker_connections: 单个 worker 进程允许的最大并发连接数。
    • use: 指定使用的事件模型,如 epoll (Linux)、kqueue (FreeBSD/macOS)。
  • http: HTTP 服务器的配置块。

    • include mime.types: 引入文件类型映射。
    • default_type: 默认的文件类型。
    • log_format: 定义访问日志的格式。
    • access_log: 访问日志路径和格式。
    • sendfile on: 启用零拷贝技术,提高静态文件传输效率。
    • keepalive_timeout: 客户端连接的保持活动时间。
    • gzip on: 启用 Gzip 压缩,减少传输数据量。
  • server: 定义一个虚拟主机。

    • listen: 监听的端口。
    • server_name: 绑定的域名。
  • location: 基于请求 URI 匹配的规则块。

    • root: 定义文件系统的根目录。
    • index: 定义默认索引文件。
    • proxy_pass: 将请求转发到后端服务器。
    • proxy_set_header: 设置转发请求头,非常重要,用于将客户端真实 IP 等信息传递给后端。
  • upstream: 定义一组后端服务器,用于负载均衡。

    • server: 定义后端服务器的地址和端口。
    • 负载均衡算法: weight (权重轮询,默认)、ip_hash (基于客户端 IP 哈希)、least_conn (最少连接)。

常用的命令

1
2
3
4
5
sudo systemctl start nginx # 启动 Nginx
sudo systemctl stop nginx # 停止 Nginx
sudo systemctl restart nginx # 重启 Nginx
sudo systemctl reload nginx # (平滑重启,重新加载配置,不中断连接)
sudo nginx -t # 检查配置是否有效