Nginx笔记


Nginx 复习

Nginx 概述

Nginx(发音为”engine x”)是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。Nginx由Igor Sysoev于2004年首次公开发布,用于解决C10K问题(即服务器同时处理10,000个客户端连接的问题)。

  • HTTP 服务器:它可以像 Apache、Tomcat 一样,直接把服务器上的静态文件(比如 HTML、图片、CSS、JS)返回给用户的浏览器。
  • 反向代理服务器:这是它最重要、最常见的角色。它作为后端服务(比如你的 Java、Go、Python 应用)的“门户”,接收所有用户的请求,然后再把请求转发给后端的具体服务去处理。

Nginx 核心特性总结

1. 高并发、高性能 (High Concurrency & High Performance)

  • 这是 Nginx 最广为人知的标签。它能以极低的内存和 CPU 资源消耗,轻松维持数万甚至数十万级别的并发连接。
  • 核心原因:它从根本上解决了 C10K 问题,是为高并发场景而生的。

2. 事件驱动的异步非阻塞架构 (Event-Driven, Asynchronous Non-Blocking)

  • 这是实现“高并发、高性能”的技术基石
  • 工作方式:Nginx 在处理网络连接和请求时,不会因为某个任务(如等待客户端发送数据或等待后端返回结果)而“傻等”(阻塞)。它会注册一个“事件”,然后立即去处理其他任务。当等待的任务完成后,它会接收到通知,再回来处理后续步骤。
  • 结果:用极少数的工作进程就能“应付”海量的并发任务,大大节省了系统资源。

3. 强大的代理与网关层 (Robust Proxy and Gateway Layer)

  • Nginx 不仅仅是简单的请求转发,它是一个功能丰富的应用网关
  • 体现在
    • 反向代理:隐藏和保护后端服务。
    • 负载均衡:将请求压力分摊到多个后端服务器。
    • 安全屏障:可配置访问控制、速率限制,抵御部分网络攻击。
    • 性能优化:能执行 SSL 加密卸载、内容缓存、Gzip 压缩等,为后端减负。

4. 明确的职责分离 (Clear Separation of Concerns)

  • Nginx 完美地将 网络连接管理业务逻辑处理 这两个职责分离开。
  • 职责划分
    • Nginx:专心处理所有与客户端之间的网络 I/O,无论连接是快是慢。
    • 后端服务:从繁杂的网络问题中解脱出来,专心处理业务逻辑数据 I/O(如数据库读写)。
  • 结果:架构更清晰,使得各个部分可以独立优化和扩展。

5. 忠实的“问题报告者” (Faithful Problem Reporter)

  • 当后端服务出现问题时,Nginx 不会隐藏问题,而是会明确地向客户端报告。
  • 典型例子
    • 502 Bad Gateway:后端服务不可达或已崩溃。
    • 504 Gateway Timeout:后端服务处理请求太慢,超时了。

Nginx 的常见应用场景

  • **静态资源服务器:**高效地提供静态文件如HTML、CSS、JavaScript、图片等。
  • **反向代理服务器:**接收客户端请求并转发到后端服务器。
  • **负载均衡器:**分发请求到多个后端服务器,提高系统整体性能和可靠性。
  • **HTTP缓存:**缓存静态内容,减少后端服务器的负载。
  • **API网关:**作为API请求的入口点,处理路由、认证、限流等功能。

与其他Web服务器的比较

相比Apache等传统Web服务器,Nginx在处理高并发连接方面表现更佳,资源消耗更低。与此同时,Nginx的配置相对简单,学习曲线较平缓。

Nginx 的工作模型

Nginx 的高性能秘密,就藏在它独特的工作模型里。这个模型可以拆分成两个层面来理解:

  • 宏观的进程架构:它是如何组织自己的进程的?(Master-Worker 模型)
  • 微观的工作方式:每个进程是如何处理海量连接的?(I/O 多路复用)

Master-Worker 多进程模型

当你在服务器上启动 Nginx 后,用 ps -ef | grep nginx 命令查看,通常会看到至少两个进程:一个 Master 进程和一个或多个 Worker 进程

1. Master 进程 (主进程 / “管理者”)

Master 进程的角色是“领导”和“管理员”,它不直接处理任何用户的网络请求。它的主要工作是:

  • 读取并验证配置:启动时,它会读取 nginx.conf 配置文件,检查语法是否正确。
  • 创建和绑定端口:它会负责监听配置文件中指定的端口(如 80, 443)。
  • 管理 Worker 进程
    • 根据配置(worker_processes 指令)或者服务器的 CPU核心数,创建指定数量的 Worker 进程。
    • 监控 Worker 进程的健康状态,如果某个 Worker 意外死掉了,Master 会立刻重新拉起一个新的。
    • 接收来自管理员的控制信号,实现 Nginx 的平滑升级、优雅重启、停止服务等。例如,当你执行 nginx -s reload 来热加载配置时,就是 Master 进程在工作。

简单说,Master 进程就像一个“工头”,负责准备工作环境、招募并管理工人,但它自己不上一线干活。

2. Worker 进程 (工作进程 / “工人”)

Worker 进程才是真正处理用户请求的“一线员工”。

  • 处理连接和请求:所有的用户连接和请求,都是由 Worker 进程来接收、处理和响应的。
  • 相互独立:每个 Worker 进程都是一个独立的、单线程的进程。它们之间几乎没有共享数据,处理请求时互不干扰,这保证了高可靠性,一个 Worker 的崩溃不会影响其他 Worker。
  • 共享监听端口:所有 Worker 进程都会共同监听由 Master 进程打开的端口。当一个新连接到来时,所有 Worker 会通过操作系统的机制(如 accept_mutex 锁)来“争抢”这个连接,最终只有一个 Worker 会成功接收并处理它。

这个 “一个管理者 + 多个高效工人” 的模型有几个巨大的好处:

  • 稳定性:Master 作为守护进程,保证了 Worker 的稳定运行。Worker 之间相互隔离,一个出问题不影响全局。
  • 高可用性:可以在不停止服务的情况下,通过向 Master 发送信号来平滑地升级程序、更新配置。
  • 利用多核:可以配置与 CPU 核心数相等的 Worker 进程数,充分利用多核 CPU 的处理能力。

每个 Worker 进程都是单线程的,它凭什么能独自处理成千上万的并发连接呢?

I/O 多路复用 (以 epoll 为例)

Worker 进程高效的秘密武器,就是 I/O 多路复用 (I/O Multiplexing)。在 Linux 系统上,它具体的技术实现就是 **epoll,**应用程序可以通过调用 epoll_create, epoll_ctl, epoll_wait 这几个函数,来委托内核去帮它高效地管理大量的网络连接。

  1. 一个 Worker 进程把自己关心的所有连接(Socket)都注册到 epoll 系统中。
  2. 然后 Worker 进程就休眠了,调用 epoll_wait() 等待事件发生,几乎不占 CPU。
  3. 当某个连接上有数据传来、或可以发送数据时(即 I/O 事件就绪),操作系统会通知 Worker 进程,并把所有已就绪的连接列表告诉它。
  4. Worker 进程被唤醒,拿到这个“就绪列表”,然后依次处理这些连接上的请求。处理完后,继续回去“睡觉”,等待下一次的事件通知。

总结:

Nginx 的高性能模型 = Master-Worker 多进程架构 (充分利用多核、稳定可靠) + I/O 多路复用 epoll (单个 Worker 进程高效处理海量连接的核心技术)。

Nginx 的配置与核心指令

Nginx 的安装与目录结构

通常,我们通过包管理器(如 yumapt-get)安装 Nginx。

记住以下几个核心位置至关重要:

  • 主配置文件: /etc/nginx/nginx.conf
    • 这是 Nginx 的“大脑”,几乎所有的配置都从这里开始。
  • 可拆分的配置目录: /etc/nginx/conf.d/
    • 在实践中,我们很少把所有配置都写在 nginx.conf 这一个文件里。通常,nginx.conf 会通过 include /etc/nginx/conf.d/*.conf; 这样的指令,把这个目录下的所有 .conf 文件都加载进来。
    • 最佳实践:每为一个网站或一个服务做代理,就在 conf.d 目录下新建一个独立的配置文件(如 my_app.conf)。这让配置管理变得非常清晰。
  • 日志文件目录: /var/log/nginx/
    • access.log: 访问日志。记录了每一个请求的详细信息(谁访问的、访问了什么、何时访问、响应状态等)。是排查业务问题和做数据分析的基础。
    • error.log: 错误日志。记录了 Nginx 启动、运行过程中的所有错误信息。当 Nginx 启动失败或者出现 5xx 错误时,第一时间就应该来这里找线索。
  • 默认网站根目录: /usr/share/nginx/html/
    • 当你安装完 Nginx 第一次启动,在浏览器里访问服务器 IP,看到的那个“Welcome to Nginx!”页面,就是存放在这个目录下的 index.html

Nginx 的基本控制命令

我们通常使用 nginx 这个可执行文件(或者通过 systemctl),配合不同的参数来控制它。

  • 测试配置nginx -t
    • 极其重要! 在你修改了任何 .conf 配置文件后,永远不要直接重启 Nginx。先执行 nginx -t,它会检查所有配置文件的语法。如果没问题,它会提示 syntax is oktest is successful。这能避免因为一个小小的语法错误(比如少个分号)导致整个网站宕机。
  • 启动 Nginxnginxsystemctl start nginx
    • 直接执行 nginx 命令(或使用 systemctl)。
  • 停止 Nginx
    • nginx -s stop:快速停止,不管当前有无正在处理的请求,直接“一刀切”。
    • nginx -s quit:优雅停止 (graceful stop),会等待当前所有正在处理的请求完成后,再关闭进程。
  • 重载配置 (热加载)nginx -s reload
    • 核心功能! 这也是 Master-Worker 模型优势的体现。当执行 reload 时:
      1. Master 进程会先去检查配置(类似 nginx -t)。
      2. 如果配置无误,Master 会启动新的 Worker 进程(使用新配置)。
      3. 同时,Master 会向老的 Worker 进程发送“优雅停止”的信号。
      4. 老的 Worker 进程不再接受新的连接,并在处理完手头所有请求后自行退出。
    • 整个过程服务不中断,用户的访问完全无感知,这是生产环境中更新配置的标准操作。

Nginx 核心指令解析

#================ 全局块 (Global Block) ================
# 这部分没有花括号,是最高层级的指令。
user  nginx;
worker_processes  auto; # 通常设置为 auto 或 CPU 核心数
error_log /var/log/nginx/error.log warn;
#====================================================

#================ events 块 ================
# 配置与网络连接相关的参数
events {
    worker_connections  1024; # 每个 worker 进程能处理的最大连接数
    use epoll; # 在 Linux 上使用 epoll 模型,性能最高
}
#===========================================

#================ http 块 ================
# 这是配置 Web 服务和代理功能最核心的块
http {
    # --- http 全局配置 ---
    # 定义了可以在 http 块下所有 server 块中使用的公共配置
    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;
    sendfile        on;
    keepalive_timeout  65;

    # --- server 块 (定义一个虚拟主机) ---
    server {
        listen       80; # 监听 80 端口
        server_name  www.example.com; # 对应的域名

        # --- location 块 (定义请求路由规则) ---
        location / {
            root   /usr/share/nginx/html; # 网站根目录
            index  index.html index.htm;   # 默认首页文件
        }

        location /api/ {
            # 这里的规则会匹配所有 "www.example.com/api/..." 的请求
            # 比如,可以把请求转发给后端服务
            proxy_pass http://backend_server_address;
        }
    }

    # --- 可以定义第二个 server 块 ---
    server {
        listen 80;
        server_name another.example.com;
        # ... 针对 another.example.com 的配置 ...
    }
}
#===========================================

全局块 (Global Block)

  • *user**
    指定 Nginx 的 Worker 进程以哪个用户和用户组的身份运行。出于安全考虑,通常会指定为一个权限较低的专用用户(如 nginxwww-data)。
  • *worker_processes**
    设置 Worker 进程的数量。这是性能调优的关键,最佳实践是设置为 auto,Nginx 会自动检测服务器的 CPU 核心数并以此作为 Worker 数量。
  • *error_log**
    定义全局的错误日志文件路径和记录级别。当 Nginx 遇到问题时(如配置错误、启动失败),这里是寻找线索的首要地点。
  • *pid**
    指定存放 Master 进程 ID 的文件路径。这个文件主要用于脚本自动化控制 Nginx。

events

  • *worker_connections**
    设置每一个 Worker 进程能够同时处理的最大连接数。这是 Nginx 并发能力的核心指标。服务器的总并发能力理论上等于 worker_processes * worker_connections
  • *use**
    指定 Nginx 使用的 I/O 多路复用模型。如我们所讨论的,在 Linux 上 Nginx 会自动选择最高效的 epoll,所以此项一般无需配置。

http

  • *include**
    用于引入其他的配置文件,是保持主配置文件 nginx.conf 简洁的最佳实践。include /etc/nginx/conf.d/*.conf; 就是一个典型的例子。mime.types 这个文件里定义了文件扩展名和MIME类型(Content-Type)之间的对应关系。比如,它里面有这样的内容:text/html html;image/jpeg jpg jpeg;。浏览器需要根据服务器返回的 Content-Type 头来决定如何展示一个文件(是当成网页渲染,还是当成图片显示)。
  • *access_log**
    设置访问日志的存放路径和使用的格式。可以设置 off 来关闭日志记录。
  • *log_format**
    自定义访问日志的格式。可以添加更多变量(如 $request_time, $upstream_response_time)来记录请求耗时等信息,对于性能分析非常有用。
  • *sendfile**
    一个性能优化指令。设置为 on 会启用操作系统高效的文件传输模式(零拷贝),可以让 Nginx 在传输静态文件时更快、更节省资源。
  • *keepalive_timeout**
    设置 HTTP 长连接的超时时间。合理的设置可以减少客户端与服务器之间频繁建立和断开 TCP 连接的开销,提升性能。
  • *client_max_body_size**
    限制客户端请求体(Request Body)的最大尺寸。当用户需要上传文件时,如果文件大小超过这个值,Nginx 会返回 413 Request Entity Too Large 错误。这是控制资源滥用的重要指令。

server

  • *listen**
    指定虚拟主机监听的端口号。可以附加 ssl 参数来表示此端口用于 HTTPS 通信。例如:listen 443 ssl;
  • *server_name**
    指定虚拟主机的域名。Nginx 通过请求头中的 Host 字段来匹配对应的 server_name,从而决定由哪个 server 块来处理该请求。这是实现虚拟主机的关键。

location

这是 Nginx 配置中最核心、最灵活的部分,决定了如何处理具体的请求 URI。

  • *root**
    指定静态文件的根目录。当请求匹配到这个 location 时,Nginx 会将请求的 URI 拼接到 root 指定的路径后,去硬盘上寻找对应的文件。

    server {
        listen 80;
        server_name example.com;
    
        # 示例: 访问 http://example.com/images/logo.png
        location /images/ {
            root /var/www/app; 
            # Nginx 寻找的物理路径是:
            # /var/www/app   +   /images/logo.png
            # 结果: /var/www/app/images/logo.png
        }
    }
    
  • *index**
    当请求的 URI 是一个目录时,指定默认去查找的文件名。例如,访问 http://example.com/ 时,Nginx 会依次尝试查找 root 目录下的 index.htmlindex.htm 文件。

    • 访问 http://example.com/:Nginx 会先寻找 /var/www/app/index.html,如果找不到,再寻找 /var/www/app/index.php
    location / {
        root /var/www/app;
        index index.html index.php; # 优先找 index.html, 找不到再找 index.php
    }
    
  • *proxy_pass**反向代理的核心指令。它指定了要将请求转发到的后端服务器地址。地址可以是 IP:Port、域名,或者是一个通过 upstream 块定义的服务器组。

    • 访问 http://example.com/api/users
    • 注意proxy_pass 后面地址的 / 非常关键:
      • / (http://.../):表示将原始 URI 中匹配 location 的部分(/api/)去掉后再拼接;Nginx 会将请求转发到 http://127.0.0.1:8080/users
      • 不带 / (http://...):表示将原始 URI 原封不动地拼接到后面;Nginx 会将请求转发到 http://127.0.0.1:8080/api/users
    location /api/ {
        # 将所有 /api/ 开头的请求转发给运行在 8080 端口的后端应用
        proxy_pass http://127.0.0.1:8080/;
    }
    
  • *try_files**
    按顺序检查指定的文件或目录是否存在。如果存在,就返回该文件;如果都不存在,就执行最后一个参数指定的操作(通常是内部重定向)。在配置单页应用(SPA)的路由时非常有用,例如 try_files $uri $uri/ /index.html;

    • 访问 http://example.com/user/profile
      1. $uri:Nginx 尝试寻找文件 /var/www/spa-app/user/profile失败
      2. $uri/:Nginx 尝试寻找目录 /var/www/spa-app/user/profile/ 下的 index 文件(即 index.html)。失败
      3. /index.html:前面都失败后,Nginx 会发起一个内部重定向,去请求并返回 /index.html
    • 效果:无论用户访问哪个路径,最终都会返回 /index.html,浏览器 URL 保持不变,后续的路由交由前端 JS 来处理。
    location / {
        root /var/www/spa-app;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
    
  • *alias**
    root 类似,也是用来指定文件路径,但它的路径拼接行为不同。alias 会用指定的路径替换location 匹配到的 URI 部分。

    • root vs alias 关键区别root 是拼接完整 URI,alias 是替换 location URI。使用 alias 时,路径末尾的 / 通常很重要。
    server {
        # 示例: 访问 http://example.com/assets/logo.png
        # 注意,/assets/ 目录可能在项目目录之外
        location /assets/ {
            alias /var/www/other_static_files/;
            # Nginx 寻找的物理路径是:
            # /var/www/other_static_files/   +   logo.png (注意 /assets/ 被替换掉了)
            # 结果: /var/www/other_static_files/logo.png
        }
    }
    

Nginx核心功能三大支柱

1. 静态资源服务器 (Static Resource Server)

虽然我们现在更多地将 Nginx 用作反向代理,但它最初就是作为一个超高性能的 Web 服务器而设计的,其处理静态文件(图片、CSS、JS、HTML文件等)的能力至今仍然是业界标杆。

我们之前已经知道,通过 rootindex 指令就可以让它工作起来。但面试中,面试官更想知道的是:

  1. 为什么 Nginx 处理静态文件那么快?
  2. 有哪些优化的手段?

A. Nginx 高性能的背后原理

Nginx 的性能优势源于它的架构设计,主要体现在两点:

  • I/O 多路复用 (epoll): 我们在第一站已经深入探讨过。它让 Nginx 能用极少的进程处理海量的并发连接,避免了为每个连接创建新进程/线程的巨大开销。
  • sendfile 系统调用: 这是一个关键的性能“黑科技”。
    • 传统方式:一个程序(如 Web 服务器)想把一个文件发送出去,需要先把文件内容从硬盘读到内核缓冲区,然后再从内核缓冲区复制到应用程序的内存中,最后再从应用程序内存复制回内核的 Socket 缓冲区,才能通过网卡发送。这个过程有两次不必要的数据拷贝,浪费 CPU 和内存。
    • sendfile 方式:Nginx 使用 sendfile 系统调用,它告诉内核:“请把这个文件的内容直接从你的内核缓冲区发送到那个网络连接的 Socket 缓冲区去”。数据完全在内核空间内进行传输,不需要拷贝到应用程序(Nginx)的内存中。这个过程被称为**“零拷贝” (Zero-copy)**,极大地提升了文件传输效率,降低了 CPU 消耗。

正是因为 epoll + sendfile 这对组合拳,Nginx 才成为了处理静态文件的王者。


B. 静态资源服务的优化配置

让 Nginx 工作起来很简单,但要把它配置到最优,还需要一些额外的指令。这些优化手段主要围绕两个目标:减轻服务器压力加速客户端访问

开启高效传输模式

这些指令通常放在 http 块中,它们能进一步发挥 Nginx 和操作系统的性能。

http {
    # 启用 sendfile "零拷贝" 模式
    sendfile on;

    # 在 sendfile 开启的情况下,优化网络包的发送。
    # 它会将响应头和文件内容一次性发送出去,而不是先发头再发内容。
    tcp_nopush on;
}

2. 配置浏览器缓存 (expires)

这是最重要的静态资源优化手段。它通过设置 HTTP 响应头,告诉浏览器这个文件可以在本地缓存多久,下次请求时就无需再从服务器下载了。

# 匹配所有图片、CSS、JS 等静态资源
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
    root /path/to/your/assets;
    
    # 设置缓存过期时间为 30 天
    expires 30d; 
}
  • 对于不常变化、且文件名唯一的静态资源(如带 hash 的 JS 文件 main.a4b8c1.js),可以设置非常长的缓存时间,如 expires 1y; (一年)。
  • 对于像 index.html 这样可能随时更新的文件,通常不设置强缓存,或者设置为 expires -1;,让浏览器每次都来服务器验证。

3. 开启 Gzip 压缩

对于文本类文件(HTML, CSS, JS, JSON),在传输前进行压缩,可以极大地减小文件体积,加快传输速度。图片(JPG/PNG)和视频本身已经是压缩格式,不需要再用 Gzip。

http {
    # 开启 Gzip
    gzip on;
    
    # 指定哪些类型的文件需要被压缩
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 其他优化,比如设置最小压缩文件大小,避免压缩过小的文件
    gzip_min_length 1k;
}

gzip 指令通常放在 http 块中,对所有网站生效。

总结一下

一个优化良好的静态资源服务器配置,会充分利用 Nginx 的 sendfile 机制,并通过 expiresgzip 指令,最大化地减少网络传输量和请求次数。

反向代理与负载均衡

A. 负载均衡 (Load Balancing)

是什么?
负载均衡是将网络请求分发多个后端服务器上去处理的机制。它是构建高可用、可扩展服务的基石。

为什么?

  1. 分担压力 (Scalability):单台服务器性能有上限,通过增加服务器数量来线性提升处理能力。
  2. 提高可用性 (High Availability):当某台后端服务器宕机时,Nginx 会自动将其从分发列表中剔除,将请求发往其他健康的服务器,保证服务不中断。

怎么配?
通过 upstreamproxy_pass 两个指令配合完成。

  1. upstream:用来定义一组后端服务器。这个块必须写在 http 块中。
  2. proxy_pass:在 location 块中,将其指向 upstream 定义的组名。

示例:

http {
    # 1. 定义一个名为 "backend_servers" 的后端服务器集群
    upstream backend_servers {
        server 192.168.1.100:8080; # 服务器1
        server 192.168.1.101:8080; # 服务器2
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            # 2. 将所有请求转发到 "backend_servers" 集群
            proxy_pass http://backend_servers;
        }
    }
}

B. 负载均衡核心策略

Nginx 提供了多种策略来决定请求到底该发给哪台服务器。

  1. 轮询 (Round Robin) - 默认策略
    • 行为:按顺序,一人一次。第一个请求给服务器1,第二个给服务器2,第三个再给服务器1…
    • 配置:无需任何额外配置。
  2. 权重 (Weight)
    • 行为:根据指定的权重比例来分配请求。权重越高的服务器,被分配到的请求就越多。适用于服务器性能不一的场景。
    • 配置server 192.168.1.100:8080 weight=3;
  3. IP 哈希 (ip_hash)
    • 行为:根据客户端的 IP 地址进行哈希计算,确保同一个客户端的请求,总是被转发到同一台后端服务器
    • 为什么:解决 Session 共享问题。如果用户在服务器A登录了,下一个请求被分到了服务器B,服务器B没有它的登录信息,就会导致用户需要重新登录。ip_hash 可以避免这种情况。
    • 配置:在 upstream 块里加上 ip_hash; 即可。
  4. 最少连接 (least_conn)
    • 行为:将请求优先分配给当前活跃连接数最少的后端服务器。适用于请求处理时间长短不一的场景,能者多劳。
    • 配置:在 upstream 块里加上 least_conn;

C. 健康检查

upstream 块可以配置简单的健康检查机制。

  • max_fails=3:在 fail_timeout 时间内,请求后端失败达到3次,则认为该服务器宕机。
  • fail_timeout=10s:暂停向该服务器转发请求10秒,10秒后会再次尝试。

进阶与优化专题

A. HTTPS 配置

是什么:为网站启用 SSL/TLS 加密,使 HTTP 协议变为更安全的 HTTPS。
怎么配

  1. 准备好你的域名证书(.crt 文件)和私钥(.key 文件)。
  2. 修改 server 块的配置。

示例

server {
    # 1. 监听 443 端口,并开启 ssl
    listen 443 ssl http2; # http2 可以顺便开启,提升性能
    server_name example.com;

    # 2. 指定证书和私钥的路径
    ssl_certificate /path/to/your/certificate.crt;
    ssl_certificate_key /path/to/your/private.key;

    # 可选:配置 SSL 协议和加密套件,增强安全性
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:...';

    # ... 其他 location 配置 ...
}

# 可选但强烈推荐:将所有 HTTP 请求强制重定向到 HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

B. Nginx 缓存

是什么:将后端服务器返回的内容在 Nginx 上缓存一份。对于不常变化的内容,Nginx 可以直接从缓存中返回,不必再请求后端,极大减轻后端压力。
怎么配

  1. proxy_cache_path: 在 http 块中,定义一块缓存区域的物理路径和规则。
  2. proxy_cache: 在 location 块中,启用上面定义好的缓存。

示例

http {
    # 1. 定义一个名为 "my_cache" 的缓存区
    # 路径在 /var/nginx/cache, 占用100m磁盘空间, 1天内未被访问则自动清除
    proxy_cache_path /var/nginx/cache levels=1:2 keys_zone=my_cache:10m max_size=100m inactive=1d;

    server {
        # ...
        location /some/path/ {
            # 2. 在这个 location 启用名为 "my_cache" 的缓存
            proxy_cache my_cache;
            proxy_pass http://backend_servers;
        }
    }
}

C. 跨域问题处理(CORS)

当前端应用和后端 API 不在同一个域名下时,浏览器会出于安全策略阻止请求。可以通过 Nginx 在响应中添加特定的头信息来解决。

location /api/ {
    # 允许来自任何源的请求
    add_header 'Access-Control-Allow-Origin' '*';
    # 允许的请求方法
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    # 允许的请求头
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type';

    # ... proxy_pass 等指令 ...
}

D. 快速排错

  1. 第一步:修改配置后,永远先执行 nginx -t 检查语法。
  2. 第二步:遇到问题(如页面打不开),立刻查看日志:
    • error.log: 查看 Nginx 自身是否有错误,比如无法连接后端、权限问题等。
    • access.log: 查看请求是否到达 Nginx,以及 Nginx 返回的状态码是什么。
  3. 理解关键状态码:
    • 502 Bad Gateway: 网关坏了。Nginx 无法连接到后端服务,或者后端服务挂了、返回了无效响应。问题在后端应用本身
    • 504 Gateway Timeout: 网关超时。Nginx 成功连接到了后端,但后端处理请求太慢,超过了 Nginx 的等待时间。问题是后端应用性能低下或卡死

  目录