nginx 配置相关

processes

  • master process:nginx 主进程,负责管理 worker 进程和读取配置,不处理具体请求。
  • worker process:实际处理客户端请求的进程,数量一般等于 CPU 核心数。2 核就有 2 个 worker。
  • cache manager process:nginx 缓存管理进程,用于清理过期缓存文件,不计入worker_processes。

案例1:

如果现在有一个 2核 的服务器,nginx 配置 worker_processes auto; 执行ps -ef|grep nginx之后

js 复制代码
root     31722     1  0 13:20 ?        00:00:00 nginx: master process ...
www      31723 31722  0 13:20 ?        00:00:00 nginx: worker process
www      31724 31722  0 13:20 ?        00:00:00 nginx: worker process
www      31725 31722  0 13:20 ?        00:00:00 nginx: cache manager process

为什么会多一个进程

当启用了 nginx 的 缓存功能 (例如 proxy_cache_path),nginx 会额外启动 cache managercache loader 进程:

  • cache manager:定期检查缓存目录,删除过期的缓存文件。
  • cache loader :在 nginx 启动时加载磁盘上的缓存元数据到内存,启动完成后会退出。
    验证方法:nginx.conf 里搜索 proxy_cache_pathfastcgi_cache_path

worker_connections

js 复制代码
events{
    worker_connections 1024;
}

在 Nginx 配置中,events 块的 worker_connections 用于定义单个 worker 进程可同时处理的最大连接数 (默认通常为 1024)。若将其配置得 "非常大"(如远超系统承载能力的 10 万、100 万),不会单纯带来 "连接数提升" 的好处,反而会引发一系列系统资源过载、性能反降甚至服务崩溃的问题,具体后果可从资源消耗、系统限制、Nginx 自身逻辑三个维度拆解:

一、核心后果:系统资源被过度占用,引发连锁故障

worker_connections 并非 "配置越大越好"------ 每个连接(即使是空闲连接)都需要消耗系统的内存文件描述符,配置过大会直接导致这两类核心资源耗尽。

  1. 内存耗尽(最直接、最致命的后果)
    Nginx 的每个连接(包括 TCP 连接、HTTP 连接)都需要占用一块 "连接结构体" 内存(约 2KB~10KB,取决于连接类型和 Nginx 版本),同时 Linux 内核为每个 TCP 连接也会分配 "套接字(socket)缓冲区"(默认约 8KB 接收缓冲区 + 8KB 发送缓冲区,可通过 sysctl 调整)。
    worker_connections 配置过大时(如 100 万),即使实际连接数未达上限,Nginx 启动时也可能因 "预分配连接资源" 或 "内核为潜在连接预留缓冲区" 导致内存被大量占用:
  • 若服务器物理内存 / 虚拟内存不足,会触发 OOM(Out Of Memory)杀手:系统会强制杀死占用内存最高的进程(通常是 Nginx worker 进程),直接导致 Nginx 服务崩溃;
  • 若内存未完全耗尽,剩余内存会被大量用于连接缓冲,导致 Nginx 处理 "实际请求"(如解析 HTTP 头、转发静态文件)的内存不足,引发请求处理延迟飙升、超时率上升;
  • 极端情况下,系统内存耗尽会导致其他服务(如数据库、监控工具)也被 OOM 杀死,引发整机故障。
  1. 文件描述符(FD)耗尽,新连接无法建立
    在 Linux 系统中,一切皆文件 ------Nginx 的每个连接(socket)、打开的配置文件、日志文件都需要占用一个 "文件描述符(File Descriptor,FD)"。
    worker_connections 的最大值受限于两个层面的 FD 限制,配置过大会直接突破限制:
  • 进程级 FD 限制 :Linux 对单个进程的最大 FD 数有默认限制(如 ulimit -n 默认值通常为 1024 或 65535)。若 worker_connections 超过该值,Nginx 启动时会报错 too many open files,worker 进程无法正常启动;
  • 系统级 FD 限制 :Linux 还会限制整机的最大 FD 数(通过 sysctl -a | grep fs.file-max 查看,默认可能为几十万)。若 worker_connections × worker_processes(总最大连接数)超过系统级限制,即使进程级 FD 已调大,新连接仍会被内核拒绝,表现为 "客户端无法建立连接(Connection Refused)"。 即使手动调大 FD 限制(如通过 ulimit -n 1000000),也会导致系统 FD 资源被 Nginx 独占,其他进程(如 SSH、日志收集工具)无法获取 FD,进而无法正常工作。

二、性能反降:连接数远超 "实际处理能力",资源错配

Nginx 的 "连接处理" 并非孤立 ------ 每个连接背后可能对应一个 HTTP 请求,而请求处理需要 CPU 计算 (解析请求头、执行路由逻辑)、磁盘 I/O (读取静态文件)或 网络 I/O (反向代理到后端服务)。

worker_connections 配置过大,会出现 "连接数远超实际处理能力" 的情况:

  • CPU 过载:单个 worker 进程是 "单线程、事件驱动" 的,若同时有几十万连接触发请求,worker 会陷入 "频繁处理事件循环" 的状态,无法高效处理核心请求(如静态文件转发),导致 CPU 使用率飙升至 100%,请求响应时间(RTT)从毫秒级变为秒级;
  • I/O 瓶颈凸显 :即使 CPU 未过载,磁盘 I/O(如机械硬盘每秒只能处理几百次读写)或网络带宽(如 1G 网卡每秒最大传输约 100MB)也会成为瓶颈。此时多余的连接只会处于 "排队等待 I/O" 的状态,不仅无法提升吞吐量,还会因连接超时(如 keepalive_timeout)导致大量重试,进一步加剧 I/O 压力;
  • 空闲连接浪费资源 :实际业务中,大量连接是 "长连接(keepalive)" 或 "空闲连接"(如客户端建立连接后未发送请求)。若 worker_connections 过大,这些空闲连接会长期占用内存和 FD,挤占 "活跃连接" 的资源,导致活跃请求被阻塞。

三、Nginx 自身逻辑限制:配置过大可能触发启动失败或异常

Nginx 对 worker_connections 有隐性逻辑限制,并非 "配置多少就支持多少":

  1. 启动时校验失败 :若 worker_connections 超过 worker_rlimit_nofile(Nginx 进程级 FD 限制,默认继承系统 ulimit -n),Nginx 启动日志会输出 worker_connections exceed open file resource limit,直接启动失败;
  2. 连接数与 worker 进程的匹配问题 :总最大连接数 = worker_processes × worker_connections(通常建议 worker_processes 等于 CPU 核心数)。若 worker_connections 过大,总连接数可能远超服务器的 "TCP 端口范围"(Linux 端口默认范围是 1024~65535,即单个 IP 最多支持约 6.4 万 outbound 连接)------ 若 Nginx 作为反向代理(需主动连接后端服务),会因 "无法分配新端口" 导致后端连接失败;
  3. 事件模型限制 :Nginx 依赖 Linux 的事件模型(如 epoll)处理连接,epoll 的 "最大监听连接数" 受限于 fs.epoll.max_user_watches(默认约 10 万)。若 worker_connections 超过该值,epoll 无法注册新连接,Nginx 会无法感知新连接请求,表现为 "客户端连接超时,但 Nginx 日志无任何记录"。

四、总结:合理配置 worker_connections 的原则

worker_connections 的合理值并非固定,需结合服务器硬件(CPU、内存、带宽)、业务场景(长连接 / 短连接、请求量)、系统限制综合计算,核心原则如下:

  1. 不超过系统 / 进程 FD 限制 :确保 worker_connections ≤ worker_rlimit_nofile(建议 worker_rlimit_nofile 手动设置为 65535 或更高,避免依赖系统默认值);
  2. 不超过内存承载能力 :按 "每个连接占用 20KB 内存" 估算(保守值),若服务器内存为 8GB,可分配给 Nginx 连接的内存若为 4GB,则单 worker 最大连接数 ≈ 4GB / 20KB ≈ 20 万(需结合 worker_processes 分摊);
  3. 匹配实际业务吞吐量 :通过监控工具(如 nginx-status、Prometheus)观察 "实际最大并发连接数",通常配置为 "实际峰值的 1.2~1.5 倍" 即可(如实际峰值 1 万连接,配置 1.5 万即可,无需追求几十万);
  4. 参考内核参数 :调优相关内核参数以匹配 worker_connections,如:
ini 复制代码
# 系统级最大 FD 数
sysctl -w fs.file-max=1000000
# epoll 最大监听数
sysctl -w fs.epoll.max_user_watches=1000000
# TCP 连接超时回收(减少空闲连接)
sysctl -w net.ipv4.tcp_keepalive_time=600

总之,worker_connections 是 "系统资源与业务需求的平衡参数",而非 "越大越好的性能开关"。配置过大会直接触发资源耗尽、性能反降甚至服务崩溃,合理的做法是 "基于实际监控数据,结合硬件上限逐步调优"。

http

include mime.types;

1. 什么是 MIME 类型

mime.types 文件是 Nginx 用来映射文件扩展名与 MIME 类型的配置文件

它的主要作用是:当 Nginx 处理静态文件时,告诉浏览器(或其他客户端)该文件的类型,从而让客户端正确解析和显示内容。

MIME(Multipurpose Internet Mail Extensions)类型是一种标准化的方式,用来表示文档、文件或字节流的性质和格式。

  • 在 HTTP 协议中,通过响应头 Content-Type 告诉客户端返回的文件类型。
  • 例如:
    • text/html 表示 HTML 页面
    • application/javascript 表示 JavaScript 文件
    • image/png 表示 PNG 图片

如果服务器返回的 Content-Type 不正确,浏览器可能会:

  • 直接下载文件而不是显示
  • 显示乱码
  • 无法正确执行脚本或渲染图片

2. mime.types 的作用

mime.types 文件里定义了 "文件扩展名" 和 "MIME 类型" 的对应关系,例如:

js 复制代码
types {
    text/html   html htm shtml;
    text/css    css;
    text/xml    xml;
    image/gif   gif;
    image/jpeg  jpeg jpg;
    application/javascript js;
    application/json json;
}
  • 左边是 MIME 类型
  • 右边是对应的文件扩展名(多个扩展名用空格分隔) 当 Nginx 处理一个 .js 文件时:
  1. 查找 mime.types,发现 .js 对应 application/javascript
  2. 在 HTTP 响应头中加入:
js 复制代码
Content-Type: application/javascript
  1. 浏览器收到后,就知道这是 JavaScript 文件,会执行而不是下载。

3. Nginx 中如何使用 mime.types

nginx.conf 中,通常会这样引用:

js 复制代码
http {
    include       mime.types;
    default_type  application/octet-stream;
}
  • include mime.types;:加载 mime.types 文件中的映射关系
  • default_type application/octet-stream;:如果文件扩展名没有在 mime.types 中找到匹配项,就使用默认类型(通常会触发浏览器流式下载该文件)

4. 如果不配置 mime.types 会怎样

  • 所有未匹配到类型的文件都会返回 application/octet-stream
  • 浏览器可能会下载这些文件,而不是直接显示或执行
  • 例如 .html 文件不会被解析为网页,而是直接下载

server

server 主要是用来 定义一个虚拟主机(Virtual Host) 的配置。当有请求到达时,如何处理针对某个域名(或 IP + 端口)的访问

核心指令说明

  • listen
    指定监听的端口,例如 80443 ssl
  • server_name
    指定匹配的域名,可以写多个,空格分隔。
  • location
    根据 URL 路径匹配不同的处理规则,例如反向代理、静态文件等。
  • root
    指定静态文件的根目录。
  • index
    默认首页文件名。
  • access_log / error_log
    访问日志和错误日志路径。

多域名部署多站点

通过 server_name 指令区分不同域名,共用 80/443 端口。

基本配置思路

  • 一个服务器监听 80/443 端口
  • server_name 区分不同域名
  • 每个域名对应不同的根目录或反向代理
ini 复制代码
# 站点A配置
server {
    listen 80;
    server_name site-a.com www.site-a.com;
    
    root /var/www/site-a;
    index index.html index.htm;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
}

# 站点B配置
server {
    listen 80;
    server_name site-b.com www.site-b.com;
    
    root /var/www/site-b;
    index index.html index.htm;
    
    location / {
        try_files $uri $uri/ /index.html;
    }
}
相关推荐
知识分享小能手2 小时前
微信小程序入门学习教程,从入门到精通,微信小程序常用API(下)——知识点详解 + 案例实战(5)
前端·javascript·学习·微信小程序·小程序·vue·前端开发
对不起初见3 小时前
PlantUML 完整教程:从入门到精通
前端·后端
东方掌管牛马的神4 小时前
oh-my-zsh 配置与使用技巧
前端
你的人类朋友4 小时前
HTTP请求结合HMAC增加安全性
前端·后端·安全
aidingni8884 小时前
掌握 TCJS 游戏摄像系统:打造动态影院级体验
前端·javascript
有梦想的攻城狮4 小时前
从0开始学vue:npm命令详解
前端·vue.js·npm
我是日安5 小时前
从零到一打造 Vue3 响应式系统 Day 23 - Watch:基础实现
前端·javascript·vue.js
FogLetter5 小时前
TypeScript 泛型:让类型也拥有“函数式”超能力
前端·typescript