提前须知(TIPS)

  • 博主主要是使用的是 centos-stream 的服务器系统,如果说你是使用的是其他的系统,请你自己学会调研和调试即可

  • 在这个过程中可能会使用到的工具提供:

    • VMWARE 进行的是运行虚拟机吧,尽可能和博主保持一直吧,可以自己找一找 vmware 17 pro 的安装包吧,保持一直哟

    • WindTerm 进行的是远程连接服务器,进行操作的工具

    • putty 最喜欢的一个远程操控服务器的工具吧,很好用的讷,可以自己找一找资源连接吧

  • 可以阅读和学习的文档

安装 Nginx

  • 这里先简单说一下不用的系统用的工具吧

    • ubuntu 核心使用的是 apt 进行的依赖的安装以及环境的搭建吧

    • centos<=7 核心使用的是 yum 进行的是依赖的安装以及环境的搭建吧

    • centos-stream 这个是 centos 的升级版本吧,也是 centos >= 8 的别名吧,核心使用的工具是 dnf

    • macos 对于很多实习了的小伙伴,都会接收到公司配备的 macos 为了快速的上手开发和调试,可以使用的工具是 brew

    • docker|podman 两个容器化的工具吧,但是国内一般用的是 podman ,docker使用需要网络好,以及为了 podman 兼容 docker 的实现,一般为在配置文件中进行取别名实现和 docker 兼容,因为市面上常用的是 docker 很多人最开始接触容器化也是用的 docker,所以说为了命令行的兼容实现,此时就是可以取别名实现的讷

  • 首先进行安装 nginx

    • ubuntu 用户视角考量

      • apt install nginx

    • centos 用户视角考量

      • yum install nginx

    • centos-stream 用户视角考量

      • dnf install nginx

    • 容器化用户考量

      • 注意我这里的话是进行了 podman 的别名设置了的,完全兼容 docker 的所有的命令吧

      • docker pull nginx

Nginx 常用命令

  • systemctl start nginx

  • systemctl enable nginx

  • systemctl status nginx

  • nginx -t

  • systemctl reload nginx

  • systemctl restart nginx 重启nginx服务的讷

  • ps -ef | grep nginx 查看进程的讷

Nginx 理论

总览

  • 对于nginx 的话,核心的介绍是:

    • 轻量级的 web 服务器,反向代理服务器,以及并发能力十分强的工具吧(但是注意随着技术能力的发展,这些工具在开发中都是一次配置,一直使用了,核心自己需要掌握了解的就是:如何阅读nginx配置,测试nginx,以及使用nginx即可吧)

    • 利用 nginx 的成功案例应用代表

      • 国内很多企业级的web应用:百度网盘的h5页面,拼多多的h5活动页面,抖音电商的h5购物页,以及博主自己的博客吧

  • Nginx特点总结

    • 访问路由的分发 :随着企业业务类型的快速的迭代和升级,业务变得越来越复杂,让开发者越来越难受,但是用户体验得到了质的飞跃,nginx 可以根据用户请求的信息,作为中间代理层,实现访问路由的分发,从而实现资源的响应,Nginx 可以通过访问路径、URL 关键字、客户端 IP、灰度分流等多种手段实现访问路由分配。

    • 反向代理支持 : 就反向代理功能而言,Nginx 本身并不产生响应数据,只是应用自身的异步非阻塞事件驱动架构,高效、稳定地将请求反向代理给后端的目标应用服务器,并把响应数据返回给客户端。其不仅可以代理 HTTP 协议,还支持 HTTPS、HTTP/2、FastCGI、uWSGI、SCGI、gRPC 及 TCP/UDP 等目前大部分协议的反向代理

    • 负载均衡支持Nginx 在反向代理的基础上集合自身的上游(upstream)模块支持多种负载均衡算法,使后端服务器可以非常方便地进行横向扩展,从而有效提升应用的处理能力,使整体应用架构可轻松应对高并发的应用场景

    • 内容缓存支持动态处理与静态内容分离是应用架构优化的主要手段之一,Nginx 的内容缓存技术不仅可以实现预置静态文件的高速缓存,还可以对应用响应的动态结果实现缓存,为响应结果变化不大的应用提供更高速的响应能力。

生态拓展使用

  • 商业化版本的: Nginx Plus 功能更加强大吧

  • 分支版本: Tengine

  • 扩展版本: OpenResty

Nginx 核心知识理论总结

  • nginx 低资源消耗、高稳定、高性能的并发能力,核心的原因来源于其多进程模型,使自身拥有了低资源消耗的特性吧

  • nginx 的高性能并发处理能力,得益于其使用事件驱动异步非阻塞多进程请求处理模型,从而实现了每个任务的事件的处理实现机制吧

多进程模型

  • 进程是操作系统资源分配的最小单位。由于 CPU 资源有限,多个进程需通过 “时间片分配” 机制竞争 CPU 使用权。系统执行内核管理与进程调度时,需完成保存当前进程上下文、更新控制信息、切换就绪进程、恢复上下文等操作;而频繁的进程切换会显著消耗系统性能。

  • Nginx 采用固定数量的多进程架构,由一个主进程(Master Process)和与主机 CPU 核数相等的工作进程协同处理各类事件。其中,主进程负责工作进程的配置加载、启动与停止(功能类似 Node.js 的 cluster 模块);但需注意,Nginx 的主进程并不直接接受请求,而是由 fork 出的工作进程负责具体请求的处理策略执行。

  • 信号用于进程间的通信与控制,比如主进程通过信号管理工作进程的启动、停止、重启等操作

  • 频道(也就是通道的机制pipe)实现进程间的信息传递,保障不同进程间指令和数据的交互

  • 共享内存:让多个进程可以共享同一块内存区域,用于高效地共享数据,提升进程间数据交换的效率

  • 进程调度

    • 无调度模式:特定场景下的进程运行方式,不进行复杂的调度操作

    • 互斥锁模式:通过互斥锁保障进程对资源的独占访问,避免资源竞争冲突

    • 套接字分片(Socket Sharding):对套接字资源进行分片管理,优化网络连接的处理效率,提升并发能力

  • 事件驱动:Nginx 基于事件驱动模型,高效处理各类网络事件和系统事件,实现高并发、低延迟的服务能力,能够同时处理大量的客户端请求

处理策略类别

具体策略

说明

最佳实践

进程通信

信号

用于进程间的控制指令传递,如主进程对工作进程的启停、重载配置等操作

合理定义信号类型及处理逻辑,确保进程响应的原子性,例如利用SIGHUP平滑重载配置

频道(管道 / 消息队列类机制)

实现进程间的数据流交互,保障指令、数据的可靠传递

结合业务场景选择合适的通信频道类型,如对于简单指令传递可使用管道,复杂数据交互可考虑消息队列;同时注意频道的读写效率与资源占用

共享内存

多进程共享同一块内存区域,用于高效共享数据(如统计信息、缓存数据等)

做好内存的同步与互斥控制,采用互斥锁(如pthread_mutex)防止数据竞争;根据数据规模合理规划共享内存大小,避免内存溢出

进程调度

无调度模式

特定场景下进程按固定逻辑运行,不进行复杂调度操作

仅在业务逻辑简单、进程职责单一且无并发竞争的场景下使用,例如单一功能的监控进程

互斥锁模式

通过互斥锁保障进程对临界资源的独占访问,避免资源竞争冲突

确保锁的粒度适中,避免锁过大导致并发性能下降;同时要防止死锁,合理设计加锁、解锁逻辑,例如采用超时机制

套接字分片(Socket Sharding)

对套接字资源进行分片管理,让不同工作进程处理不同的套接字连接,提升网络并发处理能力

结合 CPU 核数和业务并发量规划套接字分片数量,确保各工作进程负载均衡;同时优化套接字的创建、销毁流程,减少资源消耗

事件处理

事件驱动

基于事件循环机制,高效处理网络事件、系统事件(如连接建立、数据可读可写等)

合理注册事件类型,采用边缘触发(Edge Triggered)模式提升事件处理效率;对事件处理函数进行性能优化,避免阻塞操作,确保事件循环的高吞吐

// NOdejs 中的信号量管理进程案例demo:分为两个部分:一个主进程调度文件,一个worker子进程处理文件
const fork = require("node::child_process");
const worker = fork("./worker.js")  // 实现注册子进程
// 主进程定期向子进程发送消息吧
setTimeout(() => {
   worker.kill('SIGHUP')
}, 3000);

process.on('SIGNUP', () => {
   console.log("接受到了主进程的重启信号")
   setTimeout(() => {
       console.log("重新启动了,哈哈")
   }, 1000)
})


/// 频道
const { fork } = require('child_process');
const worker = fork('./worker.js');

// 主进程向工作进程发送数据
worker.send({ type: 'task', data: '生成报表' });

// 工作进程接收并响应数据
// worker.js
process.on('message', (msg) => {
  if (msg.type === 'task') {
    console.log(`收到任务:${msg.data}`);
    // 模拟任务处理
    setTimeout(() => {
      process.send({ result: '报表生成完成' });
    }, 2000);
  }
});

// 主进程接收工作进程的响应
worker.on('message', (msg) => {
  console.log(`主进程收到结果:${msg.result}`);
});


/// 内存共享机制吧
const { Worker, isMainThread, parentPort, SharedArrayBuffer } = require('worker_threads');
if (isMainThread) {
  // 主进程创建共享内存
  const sab = new SharedArrayBuffer(4); // 4字节,存储一个32位整数
  const worker = new Worker(__filename, { workerData: sab });

  // 主进程修改共享内存数据
  const arr = new Int32Array(sab);
  arr[0] = 100;

  worker.on('message', () => {
    console.log(`主进程读取共享内存:${arr[0]}`); // 输出:主进程读取共享内存:200
  });
} else {
  // 工作线程读取并修改共享内存
  const { workerData } = require('worker_threads');
  const arr = new Int32Array(workerData);
  arr[0] = 200;
  parentPort.postMessage('工作线程已修改共享内存');
}


const AsyncLock = require('async-lock');
const lock = new AsyncLock();

// 模拟多个“进程”(这里用异步函数模拟)竞争临界资源
async function processA() {
  await lock.acquire('resource', async () => {
    console.log('进程A获取资源,开始处理...');
    await new Promise(res => setTimeout(res, 1000));
    console.log('进程A处理完成,释放资源');
  });
}

async function processB() {
  await lock.acquire('resource', async () => {
    console.log('进程B获取资源,开始处理...');
    await new Promise(res => setTimeout(res, 1500));
    console.log('进程B处理完成,释放资源');
  });
}

// 同时执行两个“进程”
processA();
processB();



const EventEmitter = require('events');
// 模拟工作进程的事件驱动处理器
class WorkerEventDriver extends EventEmitter {}
const workerEmitter = new WorkerEventDriver();

// 注册事件处理逻辑(事件驱动的核心:监听并响应事件)
workerEmitter.on('connection', (socket) => {
  console.log('收到新连接,开始处理请求...');
  // 模拟请求处理
  socket.on('data', (data) => {
    console.log(`收到数据:${data.toString()}`);
    socket.write('响应数据:处理完成');
  });
});

// 模拟触发事件(如客户端连接)
function simulateClientConnect() {
  const mockSocket = {
    on: (event, cb) => { if (event === 'data') cb(Buffer.from('测试数据')); },
    write: (data) => console.log(data)
  };
  workerEmitter.emit('connection', mockSocket);
}

simulateClientConnect();

Nginx 配置指南

菜鸟教程总结截图

Nginx 目录

  • 一般我们的 nginx 的配置,在服务器上的话是在 /etc/nginx 目录下的讷,目录结构如下

名称

类型

作用

conf.d

目录

用于存放 Nginx 的子配置文件,通常用于按功能或域名拆分配置(如不同站点的 server 配置),可通过 nginx.conf 中的 include conf.d/*.conf; 指令引入。

default.d

目录

一般用于存放默认的子配置片段,例如默认的 location 规则、通用的访问控制配置等,可按需通过 include 指令引入。

fastcgi.conf

fastcgi.conf.default

文件

用于配置 FastCGI 相关参数(如 PHP 等 FastCGI 应用的请求转发规则、环境变量传递等)。.default 是默认配置文件,可作为自定义 fastcgi.conf 的参考。

fastcgi_params

fastcgi_params.default

文件

定义 FastCGI 通信的参数集合(如 SCRIPT_FILENAMEQUERY_STRING 等环境变量),是 fastcgi.conf 的补充,.default 为默认参数模板。

koi-utf

koi-win

win-utf

文件

用于字符集转换,主要处理俄文等非英文字符的编码转换,在需要支持多语言字符集的场景下发挥作用。

mime.types

mime.types.default

文件

定义文件扩展名与 MIME 类型的映射关系(如 .html 对应 text/html),Nginx 会根据此文件判断响应头的 Content-Type.default 是默认映射模板,可基于此自定义扩展。

nginx.conf

nginx.conf.default

文件

Nginx 的主配置文件,包含全局配置、事件模块、HTTP 模块等核心配置逻辑(如 worker 进程数、端口监听、反向代理规则等)。.default 是默认配置模板,可作为自定义 nginx.conf 的参考。

scgi_params

scgi_params.default

文件

配置 SCGI(Simple Common Gateway Interface)相关参数,用于 SCGI 协议的请求转发与环境变量传递,.default 为默认参数模板。

uwsgi_params

uwsgi_params.default

文件

配置 uWSGI 相关参数,用于与 uWSGI 应用(如 Python Django/Flask 项目)的通信,定义请求转发的环境变量等,.default 为默认参数模板。

Nginx 最小配置

events {}   # define events context

http {
  server {
    listen 80; # 指定监听的端口,80端口,是 http 的默认监听端口吧
    server_name luhanxin.com;  # 指定服务器名字吧
    
    return 200 "hello";  # 返回响应状态码为 200,内容为 hello 吧
  }
}

root 配置

  • root 实现设置的是nginx 请求的时候的映射的根目录吧,允许nginx转入的请求映射到本地的系统文件吧

    • 当用户请求的路径是 luhanxin.com/index.html 的时候,此时返回的的资源映射到服务器上的文件系统就是 /home/luhanxin/blob.luhanxin.com/index.html

server {
  listen 80;
  server_name luhanxin.com;
  root /home/luhanxin/blog.luhanxin.com;  # 此时设置的根路径就是在改目录下,该目录下的资源就会进行返回吧
}

location 配置

  • 核心就是进行的是 uri 的匹配,实现返回不同的资源类型吧,核心还是正则表达式

    • URI(Uniform Resource Identifier,统一资源标识符):是用于标识互联网上资源的字符串,其作用是唯一地命名或定位资源。它有两种主要形式:

      • URL(Uniform Resource Locator,统一资源定位符):属于 URI 的子集,不仅标识资源,还明确了获取资源的位置和方式(如协议、域名、路径等)。

      • URN(Uniform Resource Name,统一资源名称):也是 URI 的子集,通过名称持久地标识资源,不依赖于其位置(目前实际应用较少)。

    • URL:可以理解为 “资源的地址”,例如 https://www.example.com/index.html,通过这个字符串能明确资源的访问协议(https)、服务器地址(www.example.com)和具体路径(index.html)。

  • 也就是通过动态获取得到 URI 统一资源标识符,另一个概念就是获取得到资源的定位符URL 进行对应的匹配实现,动态正则表达式的匹配,不同资源定位符返回对应的内容,以及每种类型的资源表现出不同的行为特性吧

server {  
  listen 80;  
  server_name luhanxin.com;  
  root /home/luhanxin/blog.luhanxin.com; 
  
  location / {  
    return 200 "root";  
  }  
  
  location /foo {  
    return 200 "foo";  
  }  
}  
location /match {  
  return 200 'Prefix match: will match everything that starting with /match';  
}  
  
location ~* /match[0-9] {  
  return 200 'Case insensitive regex match';  
}  
  
location ~ /MATCH[0-9] {  
  return 200 'Case sensitive regex match';  
}  
  
location ^~ /match0 {  
  return 200 'Preferential match';  
}  
  
location = /match {  
  return 200 'Exact match';  
} 

还有 try_files 的命令,但是我对这个的理解不是特别的深入,哈哈哈

Nginx 默认优化

Nginx 反向代理优化

负载平衡:反向代理服务器可以充当驻留在我们后端服务器前面的交通警察,并以提高速度和容量利用率的方式在一组服务器之间分配客户端请求,同时确保没有任何服务器过载。如果服务器未启动,则负载平衡器会将流量重定向到其余的在线服务器。

Web 加速: Nginx 反向代理用于压缩出站和入站数据,以及缓存常见请求的内容,这两者都加快了客户端和服务器之间的流量流动。

安全性和匿名性:我们可以拦截前往我们后端服务器的客户端的请求,通过这样做,反向代理服务器可以保护他们的身份并作为对安全攻击的额外防御。

同时服务器之间的数据交换也是可以进行避免安全性防线的,实现最终的避免跨域吧

对于当下的开发模式来说的话,我们的请求一般是前后端分离的架构进行开发,一般对于前端开发一般使用的是:SPA(single-page-application)的开发模式,打包后(pnpm run build) 后会出现对应的 index.html,加载SPA 的时候,首先会向服务器请求根目录地址 / 或者 /index.html ,然后webview或者浏览器会进行html文件的解析,执行 js scripts 脚本,进行对应的逻辑处理,在这个过程中,可能就会有 xhr fetch axios ajax 请求出现,此时就需要前端的静态服务器 nginx 将请求转发给后端服务器,实现资源的请求(当前前置部分做的是 DNS 的解析)

为了完成这样的代理实现,就需要只用我们的 proxy_pass 来实现吧

  • 1. 浏览器发起请求

    • 用户输入URL(https://example.com/user),浏览器解析协议、域名和路径,通过DNS获取服务器IP,建立TCP连接(HTTPS需额外完成TLS握手),最终发送针/user路径的GET请求。

  • 2. Nginx处理静态资源与SPA路由

    • Nginx接收请求后,通location /规则匹配处理。核心配置及解决的问题:

      • root配置:指定前端静态资源存放目录,解决“Nginx去哪里查找HTML、CSS、JS等静态文件”的问题,比如请app.js时,会到配置的目录下查找对应文件。

      • index配置:设置请求路径为目录时的默认返回文件,解决“访问网站根目录(/)时该返回什么内容”的问题,默认返index.html

      • try_files配置:解决SPA前端路由刷新404的问题,执行逻辑是先查找请求路径对应的静态文件,再查找对应目录,两者都不存在时,直接返index.html,让前端路由接管页面渲染。

  • 3. 浏览器解析与JS执行

    • 浏览器接index.html后,逐步解析构建DOM树,加载CSS资源构建CSSOM树,合并为渲染树。JS加载执行规则:普通脚本标签会阻塞HTML解析和CSS渲染;

    • async属性的脚本异步下载,完成后立即执行,可能打断HTML解析;defer属性的脚本异步下载,等待HTML解析完成后按顺序执行,适合依赖DOM的脚本。

    • JS执行时初始化前端路由,根据URL中/user路径渲染对应页面组件。

  • 4. 接口请求与代理转发

    • 前端需要动态数据时,发/api开头的接口请求(/api/user),Nginx通/api/相关配置处理:

      • proxy_pass配置:解决前后端跨域和接口转发问题,/api开头的请求转发到后端服务器,比如/api/user转发到后端服务地址对应/user路径。

      • proxy_set_header配置:解决后端获取客户端真实信息的问题,传递原始请求的域名和客户端真实IP,避免后端获取到的是Nginx服务器的信息。后端处理请求后返回数据,Nginx接收响应并转发给浏览器,浏览器根据数据完成页面动态渲染。

  • SPA应用的流程是:

    • 整个点到点的流程是

      • 浏览器 --> (发送网络请求,TCP连接)-->nginx服务器

        • nginx 服务器 --> 返回加载的 index.html 给我们的浏览器,浏览器进行解析即可

      • 浏览器解析 js 脚本遇到了 ajax 请求的时候 --> nginx 服务器 --> 代理到后端服务器获取资源

      • 后端服务器对nginx 请求代理做出相应 --> nginx 服务器接收到了数据进行一些处理(可能也没有处理)--> 响应给浏览器数据,执行 js 的脚本实现对应的渲染逻辑

  • MPA 应用的流程是:

    • 点到点的流程是

      • 浏览器 ---> (发送网络请求,TCP 连接) ---> nginx 服务器

      • nginx 服务器 ---> 匹配请求路径,返回对应页面的 home.html/about.html/profile.html 给浏览器,浏览器解析该页面

      • 浏览器解析当前页面的 js 脚本、css 资源、图片等,若遇到 ajax 请求 ---> nginx 服务器 ---> 代理到后端服务器获取资源

      • 后端服务器对 nginx 请求代理做出响应 ---> nginx 服务器接收数据后(可选处理) ---> 响应给浏览器数据,浏览器执行 js 脚本完成当前页面的渲染

      • 当用户跳转至其他页面(如从 home 到 about),浏览器会重新发起请求,重复上述 “请求 - 返回 - 解析 - 渲染” 流程

  • SSR + BFF

    • 浏览器 ---> (发送网络请求,TCP 连接) ---> nginx 服务器

    • nginx 服务器 ---> 匹配请求路径,将请求转发至 Next.js 服务端(负责 SSR 渲染)

    • Next.js 服务端 ---> 执行 SSR 逻辑:

      • 通过 getServerSideProps 对接Next.js 自身的 BFF 层(如 API Route 或自定义服务端逻辑);

      • BFF 层聚合 / 转换多个后端服务的数据,返回给 Next.js 服务端;

      • Next.js 服务端再渲染页面组件,生成包含完整内容的 HTML 并返回给 nginx 服务器

    • nginx 服务器 ---> 将 Next.js 返回的 HTML 响应给浏览器,浏览器解析该页面

    • 浏览器解析页面中的 JS 脚本、CSS 资源等,若遇到客户端侧的异步请求 ---> nginx 服务器 ---> 代理到 Next.js 的 BFF 层 获取资源

    • BFF 层对接后端业务服务器获取数据(可做聚合、转换)---> 响应给 nginx 服务器,再由 nginx 转发给浏览器

    • 浏览器执行 JS 脚本完成页面的动态交互或局部渲染

    • 当用户跳转至其他页面时,重复上述 “Next.js 服务端请求 BFF 层 - 渲染 - 返回 - 客户端交互” 流程

  • SSR(Next.js不作为bff开发)类型应用是:

    • 浏览器 ---> (发送网络请求,TCP 连接) ---> nginx 服务器

    • nginx 服务器 ---> 匹配请求路径,将请求转发至 Next.js 服务端(负责 SSR 渲染)

    • Next.js 服务端 ---> 执行 SSR 逻辑:

      • 通过 getServerSideProps 直接对接后端业务服务器获取数据;

      • 在服务端渲染页面组件,生成包含完整内容的 HTML;

      • 将渲染好的 HTML 返回给 nginx 服务器

    • nginx 服务器 ---> 将 Next.js 返回的 HTML 响应给浏览器,浏览器解析该页面

    • 浏览器解析页面中的 JS 脚本、CSS 资源等,若遇到客户端侧的异步请求(如用户交互触发的接口请求)---> nginx 服务器 ---> 代理到后端业务服务器获取资源

    • 后端业务服务器对请求做出响应 ---> nginx 服务器接收数据后(可选处理)---> 响应给浏览器数据,浏览器执行 JS 脚本完成页面的动态交互或局部渲染

    • 当用户跳转至其他页面时,若该页面仍需 SSR,浏览器重新发起请求,重复上述 “Next.js 服务端渲染 - 返回 - 客户端解析 - 交互” 流程

http {
    # 全局配置(可根据需求调整)
    gzip on;
    gzip_types text/plain text/css application/json application/javascript;

    server {
        listen 80;
        server_name your-domain.com; # 你的域名或服务器IP

        # 1. 前端静态资源服务
        location / {
            root /path/to/frontend/dist; # 前端打包后的静态资源目录
            index index.html;
            try_files $uri $uri/ /index.html; # SPA 路由兼容(解决刷新404问题)
        }

        # 2. 后端接口代理转发
        location /api/ {
            proxy_pass http://backend-server:8080/; # 后端服务的地址+端口
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 可选:静态资源缓存优化
        location ~* \.(js|css|png|jpg|jpeg|webp|svg)$ {
            root /path/to/frontend/dist;
            expires 7d; # 缓存7天
            add_header Cache-Control "public, max-age=604800";
        }
    }
}
http {
    # 全局配置
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/html;

    server {
        listen 80;
        server_name your-domain.com; # 域名或服务器IP

        # 1. MPA 页面及静态资源根目录
        # /path/to/frontend 下直接存放 home.html、about.html、profile.html 及静态资源
        root /path/to/frontend;

        # 2. 首页默认返回 home.html(访问根路径时)
        index home.html;

        # 3. 针对三个页面的路径匹配
        # 访问 /home 直接返回 home.html,避免手动输入 .html 后缀
        location /home {
            try_files $uri.html $uri /home.html;
        }
        location /about {
            try_files $uri.html $uri /about.html;
        }
        location /profile {
            try_files $uri.html $uri /profile.html;
        }

        # 4. 后端接口代理转发
        location /api/ {
            proxy_pass http://backend-server:8080/;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        # 5. 静态资源缓存优化
        location ~* \.(js|css|png|jpg|jpeg|webp|svg)$ {
            expires 7d;
            add_header Cache-Control "public, max-age=604800";
        }
    }
}
http {
    # 全局优化
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/html;

    server {
        listen 80;
        server_name your-domain.com;

        # 1. 前端静态资源与 SSR 页面入口
        # Next.js 构建后的静态资源和 SSR 页面由该 location 处理
        location / {
            # 假设 Next.js 服务运行在 localhost:3000
            proxy_pass http://localhost:3000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 2. BFF 接口代理
        # 若 Next.js 的 API Route 作为 BFF,可通过 /api 前缀统一代理
        location /api {
            proxy_pass http://localhost:3000/api; # 转发到 Next.js 的 API Route
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        # 3. 后端业务服务代理
        # 若 BFF 需调用外部后端服务,可通过该 location 转发
        location /backend-service {
            proxy_pass http://real-backend:8080; # 真实后端服务地址
            proxy_set_header Host $host;
        }

        # 4. 静态资源缓存优化
        location ~* \.(js|css|png|jpg|jpeg|webp|svg)$ {
            proxy_pass http://localhost:3000;
            expires 7d;
            add_header Cache-Control "public, max-age=604800";
        }
    }
}

Nginx 负载均衡优化

一、什么是负载均衡

负载均衡(Load Balancing)是分布式系统中的核心技术,通过特定算法将客户端海量请求均匀分发至后端多台服务器,避免单台服务器过载,同时实现故障自动隔离,最终提升系统并发承载能力、可用性与资源利用率。简单来说,它就像 “请求调度员”,让集群中的每台服务器都高效且稳定地工作,避免 “一台累倒、 others 闲置” 或 “一台故障、全系统瘫痪” 的问题。


二、负载均衡常用解决方案

2.1 硬件负载均衡
  • 特点:基于专用硬件设备(如 F5、A10),性能强、稳定性高,支持复杂协议(TCP/UDP/HTTP),自带冗余设计。

  • 适用场景:大型企业核心业务、高并发入口(如电商秒杀、金融交易),对性能和稳定性要求极高的场景。

  • 缺点:成本昂贵、配置复杂,灵活性较低,升级维护依赖厂商。

2.2 软件负载均衡
  • 特点:基于软件实现,部署灵活、成本低,支持自定义配置,适配中小规模场景及快速迭代业务。

  • 主流工具:

    • Nginx:轻量高效,支持 HTTP/TCP 协议,常用轮询、加权、IP 哈希等策略,适合 Web 应用入口;

    • HAProxy:专注于高可用,支持更多复杂策略(如 URL 哈希、cookie 绑定),适合数据库、中间件等非 Web 服务;

    • LVS:工作在 TCP/IP 底层,性能接近硬件,适合大规模集群负载分发。

2.3 云原生负载均衡
  • 特点:云厂商提供的托管服务(如阿里云 SLB、AWS ELB),按需扩容、免维护,与云资源(容器、虚拟机)无缝集成。

  • 适用场景:云环境部署的业务,无需关注底层硬件 / 软件运维,专注业务开发。


三、可吸收的核心架构思想

3.1 去中心化容错思想
  • 核心逻辑:摒弃单台服务器的 “单点依赖”,通过集群化部署 + 负载分发,让系统具备 “部分故障不影响整体可用” 的能力。

  • 实践启示:开发中避免核心功能依赖单一服务 / 组件(如数据库主从分离、缓存集群),通过 “多实例 + 自动切换” 提升容错性。

3.2 资源按需分配思想
  • 核心逻辑:根据服务器性能、实时负载动态调整请求分配(如加权策略适配高低配服务器,最小连接策略适配动态负载),避免资源浪费或过载。

  • 实践启示:设计系统时考虑 “资源异构性”,比如给计算密集型服务分配高配节点,给轻量服务分配低配节点,最大化资源利用率。

3.3 分层解耦思想
  • 核心逻辑:负载均衡层作为独立入口,隔离客户端请求与后端业务服务,后端服务器可自由扩容、缩容、升级,不影响前端访问。

  • 实践启示:开发中采用 “分层架构”(如网关层、业务层、数据层),每层独立迭代,通过接口解耦,提升系统灵活性(如网关层承接路由、认证,业务层专注逻辑实现)。

3.4 兜底熔断思想
  • 核心逻辑:负载均衡不仅要 “分发请求”,还要具备 “故障隔离” 能力(如健康检查、失败重试、熔断降级),避免故障扩散。

  • 实践启示:开发接口时加入熔断(如使用 Sentinel)、降级、超时控制,防止某一服务故障拖垮整个调用链。

四、Node.js 代码实现简易负载均衡(基于 HTTP 协议)

  • 以 “加权轮询算法” 为例,实现一个简单的负载均衡服务器,分发请求至后端多台服务节点:

const http = require('http');
const httpProxy = require('http-proxy'); // npm install http-proxy

const backendServers = [
  { host: 'localhost', port: 3001, weight: 3 }, // 权重3:承担3份请求
  { host: 'localhost', port: 3002, weight: 2 }, // 权重2:承担2份请求
  { host: 'localhost', port: 3003, weight: 1 }  // 权重1:承担1份请求
];

let currentIndex = -1; // 当前选中的服务器索引
let currentWeight = 0; // 当前权重计数器

function selectServer() {
  // 遍历所有服务器,找到权重最大且符合条件的节点
  while (true) {
    currentIndex = (currentIndex + 1) % backendServers.length;
    if (currentIndex === 0) {
      currentWeight -= getMaxWeight(); // 一轮结束,重置权重计数器
      if (currentWeight <= 0) {
        currentWeight = getMaxWeight(); // 重置为最大权重
        if (currentWeight === 0) return null; // 无可用服务器
      }
    }
    // 找到权重 >= 当前计数器的服务器
    if (backendServers[currentIndex].weight >= currentWeight) {
      return backendServers[currentIndex];
    }
  }
}

function getMaxWeight() {
  return Math.max(...backendServers.map(server => server.weight));
}

const proxy = httpProxy.createProxyServer();
const loadBalancerServer = http.createServer((req, res) => {
  const targetServer = selectServer();
  if (!targetServer) {
    res.writeHead(503, { 'Content-Type': 'text/plain' });
    return res.end('Service Unavailable');
  }

  // 转发请求到选中的后端服务器
  proxy.web(req, res, { target: `http://${targetServer.host}:${targetServer.port}` }, (err) => {
    // 兜底:转发失败时返回错误
    res.writeHead(500, { 'Content-Type': 'text/plain' });
    res.end(`Proxy Error: ${err.message}`);
  });
});

loadBalancerServer.listen(8080, () => {
  console.log('负载均衡服务器启动:http://localhost:8080');
});

[3001, 3002, 3003].forEach(port => {
  http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end(`后端服务响应:端口 ${port}`);
  }).listen(port, () => {
    console.log(`后端服务启动:http://localhost:${port}`);
  });
});

五、额外补充:生产环境优化建议

  1. 健康检查:定期检测后端服务状态,自动剔除故障节点(如 Node.js 中定时发送 HEAD 请求,失败次数超过阈值则标记为不可用);

  2. 熔断降级:当后端服务错误率过高时,暂时停止分发请求,避免故障扩散(可集成 opossum 等熔断库);

  3. 静态资源缓存:负载均衡层(如 Nginx)缓存静态资源(JS/CSS/ 图片),减少后端服务压力;

  4. 会话一致性:若需固定用户与服务器映射,可改用 “IP 哈希” 或 “Cookie 绑定” 算法(Node.js 中可通过 req.connection.remoteAddress 计算 IP 哈希)。

# 全局配置段:影响所有server和location
http {
    # 1. 基础优化配置
    charset utf-8;  # 统一字符集,避免乱码
    sendfile on;    # 启用零拷贝技术,加速文件传输
    tcp_nopush on;  # 配合sendfile使用,减少TCP包数量
    tcp_nodelay on; # 禁用Nagle算法,减少交互延迟(适合实时性要求高的场景)
    keepalive_timeout 65;  # 长连接超时时间,减少握手开销
    types_hash_max_size 2048;  # 类型哈希表大小,优化MIME类型查找

    # 2. 压缩配置:减少传输数据量
    gzip on;                  # 启用gzip压缩
    gzip_vary on;             # 增加Vary: Accept-Encoding响应头,兼容代理服务器
    gzip_proxied any;         # 对代理请求也启用压缩
    gzip_comp_level 5;        # 压缩级别(1-9,5为平衡值)
    gzip_buffers 16 8k;       # 压缩缓冲区大小
    gzip_http_version 1.1;    # 支持的HTTP版本
    gzip_types                # 需压缩的文件类型
      text/plain text/css application/json application/javascript
      text/xml application/xml application/xml+rss text/javascript
      image/svg+xml application/vnd.ms-fontobject application/x-font-ttf;

    # 3. 负载均衡核心配置:定义后端服务器集群
    # 集群名称:backend_cluster(可自定义,需与proxy_pass对应)
    upstream backend_cluster {
        # 负载均衡策略(按需启用一个,默认轮询)
        # least_conn;          # 最小连接数:优先分配给连接数少的服务器
        # ip_hash;             # IP哈希:同一客户端IP固定访问同一服务器(解决Session问题)
        # hash $request_uri;   # URL哈希:同一请求路径固定访问同一服务器(适合缓存场景)

        # 后端服务器列表(格式:server 地址:端口 [参数];)
        # 主服务器1:高配服务器,权重3(接收请求比例最高)
        server 192.168.1.101:8080 
            weight=3              # 权重(默认1,值越高接收请求越多)
            max_fails=2           # 最大失败次数:2次请求失败标记为不可用
            fail_timeout=30s;     # 失败超时:标记不可用后,30秒内不再分配请求

        # 主服务器2:中配服务器,权重2
        server 192.168.1.102:8080 
            weight=2 
            max_fails=2 
            fail_timeout=30s;

        # 主服务器3:低配服务器,权重1
        server 192.168.1.103:8080 
            weight=1 
            max_fails=2 
            fail_timeout=30s;

        # 备用服务器:仅当所有主服务器不可用时启用
        server 192.168.1.104:8080 
            backup                # 标记为备用节点
            max_fails=1 
            fail_timeout=10s;

        # 已下线服务器:临时维护时标记,不参与负载
        # server 192.168.1.105:8080 down;
    }

    # 4. 虚拟主机配置:接收客户端请求并转发
    server {
        listen 80;                 # 监听端口(HTTP默认80)
        server_name example.com;   # 绑定域名(可替换为服务器IP)

        # 5. 负载均衡转发配置:匹配所有请求
        location / {
            # 转发请求到后端集群
            proxy_pass http://backend_cluster;

            # 6. 代理请求头配置:传递客户端真实信息给后端
            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_set_header X-Forwarded-Proto $scheme;   # 传递协议(HTTP/HTTPS)

            # 7. 超时配置:避免后端故障导致请求长时间挂起
            proxy_connect_timeout 3s;    # 与后端服务器连接超时时间
            proxy_send_timeout 5s;       # 向后端发送请求超时时间
            proxy_read_timeout 10s;      # 从后端读取响应超时时间

            # 8. 失败重试机制:后端出错时自动转发到下一台服务器
            # 注意:非幂等请求(POST/PUT/DELETE)慎用,可能导致重复提交
            proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
            proxy_next_upstream_tries 2;  # 最多重试2台服务器

            # 9. 缓冲区配置:优化大响应处理
            proxy_buffering on;          # 启用缓冲区
            proxy_buffer_size 4k;        # 缓冲区大小
            proxy_buffers 4 32k;         # 缓冲区数量和每个大小
        }

        # 10. 静态资源单独处理:减轻后端压力
        location ~* \.(jpg|jpeg|png|gif|webp|css|js|svg|ico)$ {
            # 静态资源目录(若前端资源由Nginx直接提供)
            root /var/www/static;
            expires 7d;                  # 缓存7天
            add_header Cache-Control "public, max-age=604800";  # 缓存控制头
            try_files $uri @proxy_static;  # 本地找不到则转发到后端
        }

        # 静态资源 fallback:本地无资源时转发到后端
        location @proxy_static {
            proxy_pass http://backend_cluster;
            proxy_set_header Host $host;
        }

        # 11. 日志配置:记录访问和错误日志
        access_log /var/log/nginx/access.log;    # 访问日志路径
        error_log /var/log/nginx/error.log warn; # 错误日志路径(级别:warn)
    }
}

Nginx 内容缓存优化

Nginx 内容缓存的核心是通过前端服务器缓存频繁访问的资源,减少后端服务器请求压力、提升响应速度,本质是 “以空间换时间” 的优化方案

一、缓存核心概念与作用

  • 核心定义:利用资源访问的局部性原理,将后端返回的资源(如页面、图片、接口数据)存储在 Nginx 本地,后续相同请求直接从 Nginx 缓存返回,无需重复请求后端。

  • 核心价值:降低后端服务器 CPU / 带宽开销,缓解系统压力;减少用户等待时间,提升访问体验;降低网络传输损耗,优化整体系统吞吐量。


二、基础缓存配置(必配项)

2.1 全局缓存目录配置

需在http块中定义缓存存储路径及核心参数,是缓存功能的基础:

http {
    # 缓存核心配置:定义缓存存储规则
    proxy_cache_path /usr/local/nginx/cache  # 缓存文件本地存储路径
                    levels=1:2               # 二级目录结构(避免单目录文件过多,优化查询效率)
                    keys_zone=the_cache_zone:10m  # 共享内存区(名称the_cache_zone,大小10MB,存储缓存键和元数据)
                    inactive=1h              # 缓存文件1小时无访问则自动清除
                    max_size=512m            # 缓存最大占用磁盘空间(上限512MB,满时自动清理旧缓存)
                    use_temp_path=off;       # 禁用临时目录(避免磁盘I/O开销)
}
2.2 location 缓存启用配置

在需缓存的请求路径中启用缓存,并配置关键规则:

location / {
    proxy_pass http://www.example.com;  # 反向代理到后端服务
    proxy_cache the_cache_zone;         # 启用缓存,关联上述定义的共享内存区
    
    # 缓存键配置:区分不同资源的唯一标识(关键!决定缓存命中率)
    proxy_cache_key $scheme$proxy_host$request_uri;  # 组合协议+主机+请求URI作为缓存键,包含Query参数
    
    proxy_cache_min_uses 3;             # 缓存门槛:资源需被请求3次后才缓存(避免低频资源浪费缓存空间)
    add_header X-Cache-Status $upstream_cache_status;  # 响应头添加缓存状态(HIT命中/MISS未命中/BYPASS跳过,方便调试)
}

三、缓存有效期与新鲜度控制

3.1 核心指令说明
  • proxy_cache_valid:针对不同 HTTP 状态码设置缓存有效期(过期后需重新请求后端)。

  • proxy_ignore_headers:忽略后端返回的缓存控制头(如 Cache-Control、Expires),强制按 Nginx 本地规则缓存。

  • proxy_cache_revalidate:基于 Etag/Last-Modified 验证资源新鲜度,资源未变化时直接复用缓存(减少回源次数)。

location / {
    proxy_pass http://www.example.com;
    proxy_cache the_cache_zone;
    
    # 忽略后端缓存头,自定义有效期
    proxy_ignore_headers X-Accel-Expires Cache-Control Expires;
    proxy_cache_valid 200 30m;  # 200成功响应缓存30分钟
    proxy_cache_valid 301 1h;   # 301重定向响应缓存1小时
    proxy_cache_valid any 1m;   # 其他状态码响应缓存1分钟
    
    proxy_cache_revalidate on;  # 启用资源新鲜度验证
}

四、缓存风险规避(缓存雪崩 / 并发回源)

4.1 核心风险场景
  • 缓存雪崩:大量缓存同时过期,请求瞬间涌向后端导致服务压力暴增。

  • 并发回源:同一缓存未命中时,多个请求同时回源后端,造成局部过载。

4.2 解决方案配置
location / {
    proxy_pass http://www.example.com;
    proxy_cache the_cache_zone;
    
    # 并发回源控制:同一资源仅允许1个请求回源,其余请求阻塞等待
    proxy_cache_lock on;               # 启用加锁机制
    proxy_cache_lock_age 5s;           # 5秒内未完成回源则放行后续请求
    proxy_cache_lock_timeout 5s;       # 加锁超时后放行,且不缓存结果
    
    # 缓存雪崩缓解:后端故障/缓存更新时,返回过期缓存(保障可用性)
    proxy_cache_use_stale error timeout updating http_503;
    proxy_cache_background_update on;  # 返回过期缓存的同时,后台异步更新缓存(下次请求用新缓存)
}

五、手动清除缓存配置(扩展功能)

需通过ngx_cache_purge模块实现(需编译安装),用于手动清理指定缓存资源:

# 正常缓存配置
location / {
    proxy_pass http://www.example.com;
    proxy_cache the_cache_zone;
    proxy_cache_key $scheme$proxy_host$request_uri;  # 与清除缓存的key规则一致
}

# 缓存清除接口(仅允许本地访问,避免外部滥用)
location ~ /purge(/.*) {
    allow 127.0.0.1;  # 允许本地IP访问
    deny all;          # 拒绝所有外部IP
    # 清除对应资源缓存:缓存区+缓存键(与proxy_cache_key规则对齐)
    proxy_cache_purge the_cache_zone $scheme$proxy_host$1$is_args$args;
}

六、核心缓存状态说明(X-Cache-Status 值)

  • HIT:缓存命中,直接从 Nginx 缓存返回资源。

  • MISS:缓存未命中,请求转发至后端,返回资源并写入缓存。

  • BYPASS:符合proxy_cache_bypass规则,跳过缓存直接请求后端。

  • EXPIRED:缓存已过期,重新请求后端并更新缓存。

  • STALE:缓存已过期,但因proxy_cache_use_stale规则,返回过期缓存。

七、核心架构思想吸收

  1. 局部性优化思想:利用资源 “被频繁访问” 的特性,通过前端缓存减少后端重复计算 / 传输,是分布式系统中 “就近访问” 原则的典型应用。

  2. 容错兜底思想:通过proxy_cache_use_staleproxy_cache_background_update等配置,在缓存失效 / 后端故障时保障服务可用性,避免系统雪崩。

  3. 精细化控制思想:区分状态码设置缓存有效期、设置缓存门槛,避免无效缓存占用资源,平衡缓存收益与存储成本。

Nginx 压缩和解压

为什么需要进行资源的压缩讷?意义是什么讷?核心解决的是什么讷?这样做有什么意义吗?那些资源需要进行压缩讷?

  1. 为什么需要进行资源压缩?核心解决的问题资源压缩核心是为了解决 “网络传输效率低” 和 “资源成本高” 两大问题。在网络传输中,大体积资源会导致用户下载时间长(如一个未压缩的 1MB JS 文件,用户可能需要等待数秒),同时企业需为大量数据传输支付高额带宽费用。通过压缩可大幅减小资源体积,让数据更快传输、降低带宽开销。

  2. 资源压缩的意义与需压缩的资源类型意义在于提升用户体验(资源加载更快,页面打开更流畅)和降低运营成本(带宽成本、服务器存储成本减少)。需压缩的资源主要是文本类资源(如 HTML、CSS、JS、JSON 数据)和部分多媒体资源(如未做优化的图片、音频,可通过格式转换压缩体积,如 JPG 转 WebP、MP3 转 AAC)。而已经过压缩的资源(如 PNG 图片、MP4 视频)则无需重复压缩,避免徒增 CPU 开销。

常见的处理策略是怎样的讷?对于媒体资源的处理是怎样的讷?以及如何进行分析问题讷?以及一些专业性的名词是什么讷?

一、常见处理策略

  1. 文本资源(HTML、CSS、JS、JSON 等)

    • 启用压缩算法:如 Gzip、Brotli、Zstd,通过 Nginx 等服务端配置实现动态压缩,或提前生成预压缩文件(.gz、.br、.zst)。

    • 代码轻量化:移除多余空格、注释,合并冗余代码(如 CSS/JS 合并),使用代码混淆工具(如 Terser)压缩 JS。

  2. 媒体资源(图片、音频、视频)

    • 格式优化:图片转 WebP(比 JPG 体积小 30%+)、音频转 AAC(比 MP3 高效)、视频转 H.265(比 H.264 体积小 50%)。

    • 尺寸适配:根据设备分辨率返回不同尺寸资源(如手机端返回小尺寸图,PC 端返回大尺寸图),避免资源浪费。

  3. 综合策略

    • 缓存策略:静态资源设置长缓存(expires 30d),减少重复请求。

    • 按需加载:非首屏资源(如轮播图、详情页图片)延迟加载,降低初始传输量。

二、媒体资源的处理

  1. 图片资源

    • 压缩工具:TinyPNG(无损压缩 PNG)、Squoosh(多格式转换与压缩)。

    • 技术方案:采用 “WebP + 降级 JPG” 策略,现代浏览器加载 WebP(高压缩率),老旧浏览器 fallback 到 JPG。

  2. 音频资源

    • 格式选择:优先使用 AAC 或 Opus 格式,比 MP3 压缩效率更高,音质损失小。

    • 场景适配:短音频(如提示音)用低码率压缩,长音频(如 podcast)平衡码率与音质。

  3. 视频资源

    • 编码优化:采用 H.265 编码(移动端)或 H.264(兼容性场景),结合自适应码率(根据用户带宽自动切换清晰度)。

    • 存储分发:通过 CDN 分发,边缘节点缓存热门视频,降低源站带宽压力。

三、问题分析与专业名词

  1. 问题分析方法

    • 工具监测:使用 Chrome DevTools(Network 面板看资源体积、加载时间)、Lighthouse(检测资源优化建议)、Nginx 日志(分析资源请求频次与体积)。

    • 场景拆解:区分 “首屏资源” 与 “非首屏资源”、“静态资源” 与 “动态资源”,针对性优化。

  2. 专业性名词

    • 压缩率:压缩后体积与原体积的比值,比值越小压缩效果越好(如 Brotli 对 JS 的压缩率可达 70%)。

    • 有损压缩 / 无损压缩:有损压缩牺牲部分质量换取体积减小(如 JPG、H.264);无损压缩保留完整质量(如 PNG、FLAC)。

    • CDN(内容分发网络):将资源分发到全球边缘节点,用户从就近节点获取资源,降低源站带宽压力。

    • 缓存命中率:命中缓存的请求数占总请求数的比例,越高说明缓存策略越有效。

  • 首先对应现代的浏览器来说的话,支持的压缩算法实现就是:gzip 压缩,br压缩,zstd压缩算法

    • 但是对于 nginx 的话,默认支持的压缩有:gzip压缩和deflate 压缩,其他两个压缩是需要进行额外的配置才可以使用的讷

优先选 Brotli(br)的场景

  • 核心需求:极致压缩率,降低带宽成本(如大体积 JS/CSS 包、静态 HTML 页面)

  • 兼容要求:用户群体以现代浏览器为主(无 IE 用户)

  • 典型场景:官网静态资源、管理后台、移动端 H5(Chrome/Firefox 占比高)

优先选 Zstd 的场景

  • 核心需求:平衡压缩率与速度(不想牺牲太多性能,又要比 gzip 好)

  • 场景特点:动态资源多(如 API 接口 JSON 响应)、服务器 CPU 资源有限

  • 典型场景:高并发接口服务、短视频平台静态资源(需快速压缩响应)

保留 Gzip 的场景 / 作用

  • 兼容兜底:需支持 IE 浏览器或老旧客户端(gzip 是唯一通用选择)

  • 降级方案:配置 Vary Accept-Encoding,让不支持 br/zstd 的浏览器自动 fallback 到 gzip

  • 轻量场景:小体积资源(如小图片、短文本),gzip 足够用且开销更低

避坑提醒

  • 不要盲目追求高压缩级别(如 br:11、zstd:22):压缩率提升有限,但 CPU 开销会翻倍

  • 非文本资源不压缩:图片(JPG/PNG/WEBP)、视频(MP4)本身已压缩,再压缩无收益还耗 CPU

  • 动态资源压缩需谨慎:如 PHP/JSP 动态页面,需确保服务器 CPU 能承载压缩开销

http {
    # 启用所有压缩算法
    gzip on;
    brotli on;
    zstd on;

    # 统一配置压缩类型和级别(平衡设置)
    gzip_comp_level 5;
    brotli_comp_level 6;
    zstd_comp_level 10;
    gzip_types text/plain text/css application/json application/javascript;
    brotli_types $gzip_types;
    zstd_types $gzip_types;

    # 优先级控制:br > zstd > gzip
    brotli_static always;  # 优先使用预压缩的.br文件
    zstd_static always;    # 其次使用预压缩的.zst文件
    gzip_static always;    # 最后使用预压缩的.gz文件

    # 告知客户端支持的压缩格式,自动适配
    add_header Vary Accept-Encoding;
}

对比维度

Gzip

Brotli(br)

Zstd

压缩率

中等(基准)

高(比 gzip 高 20%-30%)

高(接近 br,略低 5%)

压缩速度

中等

较慢(压缩率越高越慢)

快(比 br 快 30%-50%)

解压速度

快(与 gzip 接近)

最快(比 gzip 快 20%)

兼容性

极佳(所有浏览器支持)

良好(Chrome/Firefox/Edge 支持,IE 不支持)

一般(新版浏览器支持,旧版需兼容)

CPU 开销

低 - 中

中 - 高(压缩时)

中(压缩解压均均衡)

适用资源

通用静态资源

大体积文本资源(JS/CSS/HTML)

大体积静态资源、API 响应

  • 需注意,Brotli(br)和 Zstd 压缩属于定点性能优化技术,依赖服务器端单独的环境支持(需编译安装对应 Nginx 扩展模块),否则无法启用。

  • 此外,压缩算法虽能有效实现资源体积缩减、降低网络传输耗时,但会对服务器 CPU 产生显著压力。需结合业务场景合理配置压缩级别、压缩触发条件(如资源大小阈值),才能在 “传输效率” 与 “服务器负载” 间达到最优平衡。

http {
    # ===================== 全局基础配置 =====================
    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;

    # ===================== 压缩核心配置 =====================
    # 1. Gzip 压缩(默认支持,兼容兜底)
    gzip on;
    gzip_comp_level 5;                # 压缩级别5(平衡速度与压缩率)
    gzip_min_length 1k;               # 小于1KB的资源不压缩(避免开销)
    gzip_buffers 16 8k;               # 压缩缓冲区配置
    gzip_http_version 1.1;            # 支持HTTP 1.1协议
    gzip_types                        # 需压缩的文本资源类型
        text/plain text/css application/json application/javascript
        text/xml application/xml application/xml+rss text/javascript
        application/vnd.ms-fontobject application/x-font-ttf image/svg+xml;
    gzip_vary on;                     # 告知代理服务器缓存不同压缩格式
    gzip_proxied any;                 # 对代理请求也启用压缩
    gzip_static always;               # 优先使用预压缩的.gz文件(无则动态压缩)

    # 2. Brotli(br)压缩(需安装ngx_brotli模块)
    brotli on;
    brotli_comp_level 6;              # 压缩级别6(比gzip:5压缩率高20%+)
    brotli_min_length 1k;             # 最小压缩资源大小
    brotli_buffers 16 8k;             # 压缩缓冲区
    brotli_types $gzip_types;         # 复用gzip的压缩类型配置
    brotli_vary on;                   # 兼容代理服务器缓存
    brotli_static always;             # 优先使用预压缩的.br文件

    # 3. Zstd 压缩(需安装ngx_zstd模块)
    zstd on;
    zstd_comp_level 10;               # 压缩级别10(平衡速度与压缩率,接近br:6)
    zstd_min_length 1k;               # 最小压缩资源大小
    zstd_buffers 16 8k;               # 压缩缓冲区
    zstd_types $gzip_types;           # 复用压缩类型配置
    zstd_vary on;                     # 兼容代理服务器缓存
    zstd_static always;               # 优先使用预压缩的.zst文件

    # ===================== 优先级与兼容控制 =====================
    # 告知浏览器支持的压缩格式,按 br > zstd > gzip 排序
    add_header Vary Accept-Encoding;
    add_header X-Compression-Algorithm $encoding;  # 响应头标记使用的压缩算法(方便调试)

    # ===================== 静态资源缓存+压缩联动 =====================
    location ~* \.(js|css|html|svg|json|ttf|woff2)$ {
        root /var/www/static;                # 静态资源目录
        expires 7d;                          # 缓存7天
        add_header Cache-Control "public, max-age=604800";

        # 强制对静态文本资源启用压缩(覆盖全局配置)
        gzip on;
        brotli on;
        zstd on;
    }

    # ===================== 后端代理+压缩配置 =====================
    location /api/ {
        proxy_pass http://backend-server:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # 动态API响应压缩(JSON数据为主)
        gzip on;
        brotli on;
        zstd on;
        gzip_comp_level 4;                  # 动态资源压缩级别降低,减少CPU开销
        brotli_comp_level 5;
        zstd_comp_level 8;
    }

    # ===================== 服务器监听配置 =====================
    server {
        listen 80;
        server_name your-domain.com;
        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log warn;
    }
}

Nginx 安全控制

http {
    # 1. 隐藏版本信息
    server_tokens off;

    # 2. 配置安全响应头
    add_header X-Frame-Options "SAMEORIGIN";  # 禁止跨域嵌入(防点击劫持)
    add_header X-XSS-Protection "1; mode=block";  # 启用 XSS 防护
    add_header X-Content-Type-Options "nosniff";  # 禁止 MIME 类型嗅探
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";  # HSTS 强制 HTTPS

    # 3. 限流配置(防刷量/爬虫)
    limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;  # 单 IP 每秒最多 10 个请求
    limit_conn_zone $binary_remote_addr zone=conn_limit:10m;  # 连接数限制存储区

    server {
        listen 80;
        server_name your-domain.com;
        return 301 https://$host$request_uri;  # HTTP 强制跳转 HTTPS
    }

    server {
        listen 443 ssl;
        server_name your-domain.com;

        # 4. HTTPS 安全配置(TLS 1.2+)
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";  # 禁用弱密码套件
        ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;  # 证书路径(Certbot 生成)
        ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;  # 私钥路径

        # 5. 应用限流与连接限制
        location / {
            limit_req zone=req_limit burst=20 nodelay;  # 突发请求上限 20 个
            limit_conn conn_limit 10;  # 单 IP 最大 10 个并发连接
            proxy_pass http://backend;
        }

        # 6. 管理页面 IP 白名单(如 /admin)
        location /admin {
            allow 192.168.1.0/24;  # 允许内网 IP 段
            deny all;  # 拒绝其他所有 IP
            proxy_pass http://backend/admin;
        }

        # 7. 禁止目录遍历
        location /static {
            root /var/www;
            autoindex off;  # 关闭目录列表
            try_files $uri $uri/ /404.html;  # 不存在的资源返回 404
        }
    }
}

风险类型

常见问题

解决方法

1. 未授权访问

直接暴露后端接口、管理页面无鉴权

- 配置 IP 白名单(仅允许指定 IP 访问)

- 启用 HTTP 基础认证(账号密码验证)

- 对接业务鉴权接口(如 JWT 令牌验证)

2. 恶意请求攻击

爬虫刷量、SQL 注入、XSS 跨站脚本

- 启用 Nginx 安全模块(ngx_http_limit_req_module 限流、ngx_http_geoip_module 地域拦截)

- 配置请求头过滤(禁止非法 Referer、Origin)

- 过滤危险请求参数(如 SQL 关键字、脚本标签)

3. 协议 / 版本漏洞

使用 HTTP 明文传输、TLS 低版本(如 TLS 1.0/1.1)

- 强制跳转 HTTPS(禁用 HTTP)

- 配置 TLS 1.2+ 加密协议

- 禁用弱密码套件(如 SHA1、RC4)

4. 敏感信息泄露

响应头暴露 Nginx 版本、服务器信息

- 隐藏 Nginx 版本号(server_tokens off)

- 清除敏感响应头(如 X-Powered-By、X-Frame-Options 配置)

- 禁止目录遍历(关闭 autoindex,配置 try_files)

Nginx 定点优化

Nginx 配置域名

dnf install -y epel-release  # 安装依赖源
dnf install -y certbot python3-certbot-nginx

# 自动申请证书并配置Nginx(替换为你的域名)
certbot --nginx -d your-domain.com -d www.your-domain.com   # 注意这里是生成域名的证书的讷

# 1. 测试续费命令(无报错则正常)
certbot renew --dry-run
# 2. 添加定时任务(每天凌晨2点自动检测续期)
crontab -e
# 在打开的文件中添加以下内容:
0 2 * * * /usr/bin/certbot renew --quiet --renew-hook "systemctl reload nginx"
  • 生成的域名证书存储位置在:/etc/letsencrypt/live/你的域名/

    • fullchain.pem:完整证书链(含服务器证书、中间证书);

    • privkey.pem:证书私钥;

    • cert.pem:服务器证书(可单独使用,但一般推荐用 fullchain.pem 保证链完整);

    • chain.pem:中间证书链。

ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

Nginx cross-platform 优化

维度

PC 端(桌面)

移动端(手机 / 平板)

网络环境

带宽充足(多为宽带)、稳定性高

带宽波动大(4G/5G/WiFi)、易断连

硬件性能

CPU / 内存资源充足,浏览器渲染能力强

硬件性能受限,部分老旧设备浏览器兼容性差

交互场景

操作精度高(鼠标),页面内容承载量大

操作精度低(触摸),注重轻量化、响应式

资源需求

可加载大体积资源(高清图片、复杂 JS)

对资源体积敏感,优先保障首屏加载速度

1. PC 端优化:追求极致体验与功能完整性

优点与场景
  • 优点:带宽和硬件支持复杂交互、高清资源,可打造沉浸式体验(如电商详情页、企业官网)。

  • 缺点:大资源加载耗时,若未优化会影响首屏速度。

优化方向
  • 资源压缩:启用 Brotli 高压缩率策略(brotli_comp_level 6),对大体积 JS/CSS 进行深度压缩。

  • 缓存策略:静态资源设置长缓存(expires 30d),但需配置版本号(如 app.1.0.0.js)保证更新及时性。

  • 内容适配:提供高清图片(如 2K/4K 分辨率),通过 srcset 结合 Nginx 按设备分辨率返回对应资源。

location /pc/ {
  proxy_pass http://pc-backend;
  brotli on;
  brotli_comp_level 6;
  expires 30d;
  add_header Cache-Control "public, max-age=2592000";
}

2. 移动端优化:轻量化与高兼容性优先

优点与场景
  • 优点:用户触达场景多(碎片时间),需快速响应(如新闻资讯、社交 APP H5)。

  • 缺点:网络和硬件限制多,老旧设备占比可能较高。

优化方向
  • 资源压缩:优先用 Zstd 平衡压缩率与速度(zstd_comp_level 8),对老旧设备 fallback 到 Gzip。

  • 媒体优化:图片强制转 WebP(体积小 30%+),视频用 H.265 编码并做自适应码率(根据带宽切换清晰度)。

  • 缓存与加载:首屏资源走强缓存(expires 1d),非首屏资源懒加载;配置 proxy_cache 缓存 API 响应。

location /mobile/ {
  proxy_pass http://mobile-backend;
  zstd on;
  zstd_comp_level 8;
  gzip on;  # 老旧设备兜底
  proxy_cache mobile_cache;
  proxy_cache_valid 200 1h;
  add_header Vary Accept-Encoding;
}
  1. CDN 分发:将静态资源(图片、JS、CSS)推送到 CDN 边缘节点,降低源站带宽压力,同时利用 CDN 自带的设备识别能力做资源适配。

  2. 动态资源缓存:对 API 响应配置 proxy_cache,结合 Cache-Control 头控制缓存时效,减少后端请求。

  3. 安全与兼容:所有设备强制 HTTPS,移动端额外配置 X-Content-Type-Options nosniff 防止 MIME 嗅探攻击。

http {
  # 压缩模块全局配置
  brotli on;
  brotli_comp_level 6;
  zstd on;
  zstd_comp_level 8;
  gzip on;
  gzip_comp_level 5;

  # 设备识别与压缩策略分发
  map $http_user_agent $encoding {
    ~*Mobile|Android|iPhone|iPad "br,zstd,gzip";  # 移动端优先 br/zstd
    default "br,gzip";                           # PC 端优先 br
  }

  server {
    listen 80;
    server_name your-domain.com;

    location / {
      proxy_pass http://backend;
      add_header Content-Encoding $encoding;
      add_header Vary Accept-Encoding;
    }
  }
}

完结撒花,nginx 还有很多的玩法,慢慢玩就行了,以及实际开发中可以用 nginx 做的优化还有很多很多,这些都是最常见的一些吧🌹🌹🌹