深入剖析Nginx架构及其不同使用场景下的配置

一、Nginx 整体架构概览

1. Nginx简介

Nginx 是采用 C 语言 编写的高性能 Web 服务器、反向代理服务器及邮件代理服务器,特点是:高并发、高可用、低内存占用、模块化设计

架构核心理念:

  • Master-Worker 多进程模型

  • 事件驱动(Event-Driven) + 异步非阻塞

  • 高度模块化设计


2. 进程模型

Nginx 的进程模型非常轻量,通常包含:

1. Master 进程

  • 启动时由 shell 进程 fork 出来

  • 主要负责:

    • 读取配置文件

    • 管理 Worker 子进程(启动/重启/关闭)

    • 平滑升级(不间断服务)

2. Worker 进程

  • 实际处理请求的进程

  • 默认情况下每个 CPU 一个 worker(可配置)

  • 每个 worker 独立工作,通过 epoll 等机制异步处理连接

3. Cache Manager/Loader(可选)

  • 用于管理磁盘缓存(如 proxy_cache)

  • 管理缓存的过期与空间

Worker 之间互不通信,避免锁竞争,共享资源通常通过共享内存实现。


3. 事件驱动与异步非阻塞机制

Nginx 使用Reactor 模型 + 非阻塞 IO,事件模型封装成 ngx_event 模块,底层可选择:

  • Linux: epoll

  • BSD: kqueue

  • Windows: IOCP

  • Others: select/poll

每个 worker 维护一个事件循环(event loop),处理以下类型事件:

  • 新连接事件(accept)

  • 读写事件(read/write)

  • 定时器事件(超时)

  • 信号事件

示例事件循环伪代码:

while (true) {
    events = epoll_wait(epoll_fd, timeout);
    for (event in events) {
        if (event == read) {
            handle_read();
        } else if (event == write) {
            handle_write();
        }
    }
    process_timers();
}

4. 模块化设计

Nginx 模块系统非常强大,主程序仅提供框架,几乎所有功能都通过模块扩展。

模块分类

类型 说明
核心模块 与配置、事件循环、进程管理相关
标准模块 官方提供,如 http, gzip, rewrite
第三方模块 社区开发,如 lua-nginx-module, ngx_brotli
事件模块 封装不同操作系统的 IO 模型(epoll/kqueue 等)
过滤模块 对请求或响应进行过滤、转换(如 gzip, chunk)
处理模块 提供服务逻辑,如 ngx_http_proxy_module

模块生命周期 Hook:

模块通过 Hook 函数注册以下生命周期点:

  • postconfiguration

  • init_module

  • init_process

  • init_thread

  • exit_thread

  • exit_process

  • exit_master


5. 请求处理流程

以 HTTP 请求为例,完整流程如下:

1. 请求接收

  • Worker 进程通过 epoll 监听 socket fd 上的 accept 事件

  • 建立连接后封装为 ngx_connection_t

2. 请求解析

  • 使用状态机解析 HTTP 请求头、方法、URI 等

  • 填充 ngx_http_request_t 结构

3. 查找 Location 配置

  • 基于 URI 匹配 location block

  • 加载对应 handler(如 proxy_pass)

4. 模块链处理

Nginx 通过模块链的方式处理请求,每个模块处理一部分逻辑:

HTTP 请求
→ handler 模块
→ access 模块
→ rewrite 模块
→ content 模块(如 proxy)
→ filter 模块(gzip,chunked)
→ output

每个模块通过 ngx_http_module_t 结构中的回调函数插入处理链。

5. 响应输出

  • 各模块处理完响应后输出到客户端

  • 使用 sendfile + writev 实现 零拷贝


6. 内存管理与连接池

Nginx 有自己的一套高性能内存池机制,用于避免频繁 malloc/free:

  • ngx_pool_t: 每个请求创建自己的内存池,生命周期跟随请求

  • 可申请小块内存(<4096)快速分配

  • 请求结束时统一释放内存池,避免内存泄漏

连接相关资源也使用对象池(如 ngx_connection_tngx_buf_t)复用,提高性能。


7. 配置解析系统

Nginx 配置文件是模块驱动的,结构清晰。

配置解析过程:

  1. Master 进程读取配置文件(nginx.conf

  2. 每个模块注册自己的配置指令及解析函数

  3. 创建配置结构体,填入配置参数

  4. 绑定到 ngx_cycle_t

支持嵌套结构、变量引用($host)、include 等高级配置特性。


8. 零拷贝机制(Zero Copy)

为了提升性能,Nginx 避免数据拷贝,使用以下机制:

技术 说明
sendfile() 直接从磁盘文件到 socket,无需中转缓冲区
mmap() 映射文件到内存
writev() 将多个缓冲区一次性写入 socket
splice() 在 pipe 与 socket 之间传输,无需用户态

这些机制显著降低了 CPU 消耗和内存拷贝,提高了吞吐量。


9. 共享内存与缓存管理

Nginx 提供共享内存机制支持:

  • 状态统计模块(如 stub_status)

  • 缓存(proxy_cache, fastcgi_cache)

  • 限流(limit_req, limit_conn)

  • Nginx Plus 状态页

通过 ngx_shm_zone_t 管理共享内存区域,使用 slab 分配器精细管理内存块。


10. 日志系统

Nginx 日志系统也高度模块化:

  • access_log, error_log

  • 格式化配置灵活:log_format

  • 支持异步写入、缓存 flush、缓冲池等

  • 每个请求独立生成 ngx_log_t 对象


11. Nginx 底层架构图示

         ┌────────────────────┐
         │    Master 进程      │
         └────────────────────┘
                   │
      ┌────────────┴────────────┐
      ▼                         ▼
┌─────────────┐         ┌─────────────┐
│ Worker 进程 │  ...    │ Worker 进程 │
└─────────────┘         └─────────────┘
       │ epoll / kqueue / IOCP
       ▼
┌──────────────────────────────────────┐
│       Reactor 模型:事件循环         │
├──────────────────────────────────────┤
│ Connection Pool + 内存池 + 模块链    │
├──────────────────────────────────────┤
│ HTTP / TCP 模块处理,输出响应        │
└──────────────────────────────────────┘

12. 小结

关键模块 技术点
高性能 异步非阻塞 IO,sendfile
高并发 多 worker,事件驱动
模块化 所有功能模块驱动
内存管理 内存池、连接池
高扩展性 插件化模块架构

二、Nginx配置详解并结合使用场景深入分析

1. 主配置(全局配置块)

主配置一般出现在 nginx.conf 的最上层,用于控制整个服务器级别的行为。

常见配置项:

配置项 含义和作用
user 指定 worker 子进程运行的系统用户
worker_processes 启动的 worker 数量,建议设置为 CPU 核心数
worker_cpu_affinity 绑定 CPU,提高性能(用于多核)
error_log 全局错误日志路径及级别(`debug
pid 指定 pid 文件路径
worker_rlimit_nofile 最大文件描述符限制

示例:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

使用场景分析:

  • 高并发服务:建议 worker_processes 设置为 auto,根据 CPU 自动适配。

  • Debug 排查问题时:可以临时设置 error_logdebug


2. events 块配置(事件模型)

控制 Nginx 的事件处理机制,位于 nginx.confevents 块中。

常见配置项:

配置项 含义和作用
worker_connections 每个 worker 支持的最大连接数(非客户端连接)
use 强制指定事件模型(如 epoll/kqueue)
multi_accept 是否每次尽可能多接受新连接

示例:

events {
    use epoll;
    worker_connections 10240;
}

使用场景分析:

  • 高连接量网站:worker_connections * worker_processes 决定最大并发连接数。

  • 性能调优:使用 epollkqueue(操作系统支持前提下)可显著提升性能。


3. http 块配置(Web 服务核心)

这是 Nginx 配置中最重要的一部分,包含:

  • 虚拟主机配置(server

  • 路由与 location 规则

  • 缓存、代理、gzip 等模块

  • 日志、限速、连接控制等功能


4. server 块(虚拟主机配置)

一个 server 表示一个网站服务,可监听不同端口/域名。

常见配置项:

配置项 含义和作用
listen 指定监听的端口和地址
server_name 指定虚拟主机域名
root 指定 web 根目录
index 默认首页文件
error_page 自定义错误页

示例:

server {
    listen 80;
    server_name www.example.com;
    root /var/www/example;
    index index.html index.htm;
    
    error_page 404 /404.html;
}

使用场景分析:

  • 部署多个站点时,通过 server_namelisten 实现虚拟主机划分。

  • 多端口监听(如 80 和 443)可以写多个 server


5. location 块(请求路由匹配)

定义请求 URI 匹配规则和处理方式,是 HTTP 配置的核心。

匹配类型:

类型 示例 含义
精确匹配 location = /foo 严格等于 /foo 时生效
前缀匹配 location /img/ URI 以 /img/ 开头
正则匹配 location ~ \.php$ 匹配以 .php 结尾的路径

示例:

location / {
    try_files $uri $uri/ =404;
}

location /images/ {
    root /data;
}

location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
}

使用场景分析:

  • 静态资源分流:不同类型资源设置不同缓存头、路径。

  • 正则匹配动态请求,如 PHP、API 等。


6. 反向代理(proxy)

用于将客户端请求转发到后端服务器,是 Nginx 的核心能力之一。

常见配置项:

配置项 说明
proxy_pass 设置代理后端地址
proxy_set_header 设置请求头信息,传递客户端信息
proxy_connect_timeout 连接后端超时时间
proxy_read_timeout 读取响应超时时间
proxy_redirect 修改后端跳转地址

示例:

location /api/ {
    proxy_pass http://backend_server/api/;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

使用场景分析:

  • 微服务网关:按路径路由不同服务。

  • 解决跨域问题:配合 add_header 设置 CORS。


7. 负载均衡配置(upstream)

Nginx 作为七层负载均衡器,可配置多台后端服务。

配置示例:

upstream backend {
    server 10.0.0.1:8080 weight=3;
    server 10.0.0.2:8080 max_fails=2 fail_timeout=30s;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

支持算法:

  • round-robin(默认)

  • least_conn

  • ip_hash

  • hash $request_uri consistent;(需第三方模块)

使用场景分析:

  • 动态后端多副本:如服务部署多个 pod 实例,使用 upstream 配置调度。

  • 实现后端故障自动摘除(max_fails, fail_timeout)。


8. 限流与连接控制

请求限速:

limit_req_zone $binary_remote_addr zone=req_limit:10m rate=1r/s;

server {
    location /login/ {
        limit_req zone=req_limit burst=5;
    }
}

并发连接数限制:

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location / {
        limit_conn addr 1;
    }
}

使用场景分析:

  • 防止暴力破解、接口刷爆:对登录、注册接口限速。

  • 限制单个 IP 并发连接,防止 DDoS。


9. 安全控制

拒绝某 IP:

deny 192.168.1.1;
allow 192.168.0.0/16;

强制 HTTPS:

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

设置头防御:

add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";

10. 缓存配置

静态资源缓存:

location ~* \.(jpg|png|gif|css|js)$ {
    expires 30d;
    access_log off;
}

反向代理缓存(proxy_cache):

proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache_zone:10m inactive=60m;

location /api/ {
    proxy_cache cache_zone;
    proxy_pass http://backend;
    proxy_cache_valid 200 1h;
}

11. 日志配置

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;

使用场景分析:

  • 业务分析:配合 ELK 分析用户行为。

  • 安全审计:统计恶意请求、慢请求等。


12. 常用变量(部分)

变量名 含义
$remote_addr 客户端 IP
$http_user_agent 客户端 UA
$request_uri 请求 URI
$host 请求的 Host 头
$upstream_addr 实际转发到的后端地址(proxy)

13. 小结:分类速查表

分类 功能
主配置 进程管理、日志、用户
events IO 模型、最大连接数
http/server 网站配置、虚拟主机
location 路由控制、反向代理、限速
upstream 负载均衡、服务池
cache 缓存目录、缓存策略
security 黑名单、头安全、重定向
logging 日志格式与存储路径

三、Nginx如何解决跨域问题

1. 什么是跨域?为什么会出现跨域问题?

1.1 浏览器的同源策略(Same-Origin Policy)

同源策略要求:只有协议、域名、端口都相同,才能互相访问资源

http://example.com:80/api/user ✅
http://example.com:8080/api/user ❌ (端口不同)
https://example.com/api/user ❌ (协议不同)
http://other.com/api/user ❌ (域名不同)

1.2 跨域行为触发场景

当以下前端行为访问非同源资源时,会触发跨域限制:

  • 使用 XMLHttpRequest, fetch, axios 发起请求

  • 请求类型为非简单请求(如 PUT, DELETE, application/json

  • 请求带有自定义头(如 Authorization

  • 页面中嵌入