引言:高性能Web服务的核心
一、深探Linux IO模型:为何Nginx独爱Epoll?
1.Linux 系统中常见 I/O 模型详细对比
(1)阻塞 IO
工作流程:
-
应用进程发起系统调用(如
recvfrom)。 -
内核开始等待数据。此时,应用进程会被挂起(阻塞),什么也不做,直到数据准备好。
-
数据准备好后,内核将数据从内核空间拷贝到用户空间。
-
拷贝完成,系统调用返回成功,应用进程解除阻塞,开始处理数据
优点:编程模型非常简单,易于理解和实现。
缺点:性能极差。每个进程/线程只能处理一个I/O操作。要处理大量并发连接,就需要创建同样数量的进程/线程,系统资源无法承受。
(2)非阻塞 IO
工作流程:
-
应用进程发起系统调用,并设置socket为非阻塞。
-
如果内核中没有数据就绪,系统调用立即返回一个错误(如EWOULDBLOCK),而不是阻塞进程。
-
应用进程需要不断地轮询(循环调用)内核,询问数据是否准备好。
-
当某次轮询发现数据已就绪,内核执行数据拷贝,系统调用返回成功
优点:应用进程在等待数据期间不会被阻塞,可以在轮询间隔执行其他任务。
缺点:轮询会产生大量的系统调用,CPU占用率极高,因为大部分调用都是无效的,资源浪费严重。
(3)IO 多路复用
工作流程:
-
应用进程首先告诉内核(通过
select,poll, 或epoll系统调用)它关心哪些文件描述符(连接)及其事件(如可读)。 -
然后应用进程阻塞在
select/poll/epoll_wait这个系统调用上,而不是阻塞在真正的I/O操作上。 -
内核监视 所有被注册的文件描述符。当其中任何一个或多个数据就绪时,
select/poll/epoll_wait返回,通知应用进程"某些连接已经就绪了"。 -
应用进程再对就绪的连接发起真正的I/O操作(如
recvfrom),此时因为数据已就绪,这个操作会立即完成(数据拷贝)。
优点 :一个进程/线程可以同时处理大量连接。无需为每个连接创建一个线程,大大减少了系统开销。
核心 :"值班"机制 。有一个专门的"值班员"(select/poll/epoll)负责监视所有连接,谁有情况就通知谁。
二、Nginx 为何选择 IO 多路复用模型(以 epoll 为例)
Nginx 的设计目标是高性能、高并发、低内存占用 。IO多路复用模型,特别是Linux下的 epoll实现,完美契合了这一目标。
(1)资源效率极高:
传统的阻塞模型(如Apache的prefork模式)是"一个连接一个进程/线程"。当并发连接数达到数万时,创建数万个进程/线程本身就会耗尽系统资源,大量的上下文切换也会吃掉大量CPU。
Nginx使用单线程(或少量工作进程)+ epoll 的模式。一个工作进程 通过 epoll就可以轻松管理数万个连接。这极大地减少了进程数量、上下文切换次数和内存占用,从根本上解决了C10K问题。
(2)事件驱动架构:
Nginx 是纯粹的事件驱动架构。它的工作进程不会因为某个连接的数据未就绪而阻塞,它只会在 epoll_wait上等待事件发生。
当 epoll_wait返回后,它会得到一个"已就绪的事件列表",然后只对这些就绪的连接进行处理。 CPU时间被完全用在刀刃上,只处理真正有数据的连接,避免了轮询(非阻塞I/O)和空等(阻塞I/O)带来的资源浪费。
(3)epoll的卓越性能:
epoll在处理大量并发连接时,其效率不会随着连接数的线性增加而下降。因为它采用回调机制和就绪列表,只需要遍历那些活跃的连接,而不是全部连接。
这对于Web服务器场景至关重要,因为通常数万并发连接中,同一时刻只有一小部分是活跃的(epoll的优势正在于此)。而 select/poll需要遍历所有连接,在连接数多时性能会急剧下降。
三、对 Nginx 高并发特性的支撑作用
Nginx 选择 epoll这样的IO多路复用模型,是其实现高并发的基石,具体支撑体现在:
(1)连接处理的"量变"到"质变":
从"一个进程处理一个连接"变为"一个进程处理数万个连接",这是一种架构上的质变。使得用有限的硬件资源支撑海量用户访问成为可能。
(2)极低的延迟和快速响应:
事件驱动模式保证了Nginx能够极快地响应I/O事件 。一旦网络数据包到达网卡,内核通过中断处理、协议栈处理,最终通过 epoll的回调机制通知到Nginx工作进程,整个过程非常高效,延迟极低。
(3)CPU资源的极致利用:
工作进程的CPU时间几乎完全用于处理业务逻辑(执行配置指令、转发请求等),而不是浪费在等待、轮询或进程切换上。这使得CPU利用率非常高且有效。
(4)为反向代理和负载均衡赋能:
Nginx 作为反向代理,需要同时维持与客户端(Downstream)和上游服务器(Upstream,如Tomcat、PHP-FPM)的大量连接。epoll模型使得Nginx可以轻松地同时管理这两方面的数万条连接,高效地在它们之间转发数据,这是其成为优秀网关和负载均衡器的根本原因。
二、解构Nginx配置:模块化设计与平滑升级
(一)、Nginx 配置文件核心结构
Nginx的配置文件(通常为 nginx.conf)采用一种 分层的、模块化的树形结构,由多个指令块(Context)组成。每个块都拥有特定的作用域,可以包含自己的指令和其他嵌套的块。
这些模块具有优先级关系:从外到内,从上到下**。** 外层块的配置会被内层块继承,但内层块可以覆盖外层的同名指令。同时,对于同一层次的配置,后出现的指令会覆盖先出现的指令。
(1)Main 块 (全局块)
位置与作用 :配置文件的最顶层,不属于任何其他块。它用于设置 影响Nginx整体运行的全局指令
常见指令:
user nginx nginx:设置运行Nginx工作进程的用户和组。
worker_processes auto:定义工作进程的数量,通常设置为CPU核心数或auto。
error_log /var/log/nginx/error.log warn:配置错误日志的路径和级别。
pid /run/nginx.pid:指定存储主进程PID的文件位置。
worker_rlimit_nofile 65535:设置一个工作进程能打开的最大文件描述符数量。
优先级:它是所有其他块的祖先,其指令具有全局效应,但可以被更局部的块中的指令所覆盖(如果该指令允许)。
(2)Events 块
位置与作用 :位于 main块内。用于设置Nginx工作进程连接处理的性能参数,特别是与网络IO模型相关的配置。
常见指令:
worker_connections 1024;:每个工作进程能够同时处理的最大连接数。
use epoll;:指定高效的事件模型(如epoll用于Linux)。
multi_accept on;:允许一个工作进程同时接受多个新连接。
优先级 :它提供了http块中连接处理的底层基础。
(3)Http 块
位置与作用 :位于 events块之后。这是配置HTTP服务器相关功能的 核心部分。几乎所有与WEB服务相关的配置都在这里进行。
常用指令:
include mime.types;:引入MIME类型映射文件。
default_type application/octet-stream;:默认的MIME类型。
access_log /var/log/nginx/access.log main;:定义访问日志的格式和路径。
sendfile on;:开启高效文件传输模式。
keepalive_timeout 65;:客户端长连接超时时间。
gzip on;:开启GZIP压缩。
嵌套块 :http块内部可以包含多个 server块。
优先级 :它内部的配置会被所有 server块继承,是server块的默认配置。
(4)Server 块
位置与作用 :位于 http块内部。每个 server块相当于一个 虚拟主机(Virtual Host),用于配置一个独立的网站或服务。一台Nginx服务器可以同时托管多个基于不同域名或端口的网站。
常见指令与嵌套块:
常用指令:
listen 80;:监听端口。
server_name example.com www.example.com;:绑定的域名,是区分不同虚拟主机的关键。
root /usr/share/nginx/html;:该虚拟主机的默认网站根目录。
index index.html index.htm;:默认索引文件。
嵌套块 :server块内部可以包含多个 location块。
优先级 :继承http块的配置,并可以被内部的location块覆盖。
(5)Location 块
位置与作用 :位于 server块内部。这是最内层、最具体的配置块,用于根据请求的URI(路径)来匹配并指定不同的处理规则。它是Nginx配置中非常强大和灵活的部分。
匹配语法:
location / { ... }: 前缀匹配,匹配所有以 /开头的URI。
location = /exact { ... }: 精确匹配 ,只匹配 /exact这个URI。
location ~ \.php$ { ... }: 正则表达式匹配 (区分大小写),匹配所有以.php结尾的URI。
location ~* \.(jpg|png)$ { ... }: 正则表达式匹配(不区分大小写),匹配所有.jpg或.png结尾的URI。
常见指令:
proxy_pass http://backend;:将请求反向代理到后端服务器组。
root /path/to/files;:指定该location的根目录。
try_files $uri $uri/ /index.html;:尝试按顺序寻找文件。
优先级 :"越精确的匹配,优先级越高" 。优先级顺序通常是:精确匹配 (=) > 正则匹配 (~, ~*) > 前缀最长匹配
模块关系示意图

(二)、Nginx 平滑升级
平滑升级(Graceful Upgrade)是Nginx的一个重要特性,允许在不停止服务、不中断现有连接和请求的情况下,将Nginx升级到新版本
具体实验步骤:
查看当前环境版本

改善进程环境,确保nginx至少有两个进程在运行,便于测试
vim /etc/nginx/nginx.conf

获取最新软件

解压软件

进行编译前配置文件的准备

进行编译


检查新旧环境

新旧执行文件

开始进行平滑升级
当前依旧是旧版本运行

备份旧版本文件(改名,以防升级失败和版本回退)
mv /usr/sbin/nginx /usr/sbin/nginx-1.24

使用新的版本文件

目前的示意图

当前环境依旧不变

当前运行环境的进程仍为旧版本

拉起新进程(此时仍是旧进程工作)

为了演示版本回退,此时可以对虚拟机拍摄一个快照

可以再开一个终端进行限速下载,更加直观的演示平滑升级

接下来进行平滑升级
对服务端进行信号传递,关闭旧worker进程 已经干掉一个闲置进程,工作进程依旧存活

下载无影响

此时接受请求已经更换

只有请求接受后,旧版本才会完全消除,接下来手动结束进程(可以看到老的工作进程已经完全消失)

消除旧的主进程

平滑升级已经演示完成,接下来进行演示版本回退
首先恢复到刚才拍摄的快照


准备工作做好后,进行版本回退
拿回改名后的执行文件

工作进程依旧是新版本

拉起旧进程

优雅退出新进程,旧版本开始工作

为何平滑升级过程中不会中断现有用户请求?
(1)Nginx 采用 Master-Worker 多进程模型:
Master 进程(主进程):负责管理 Worker 进程(如启动、停止、重载配置)。
Worker 进程(工作进程):实际处理用户请求的进程,彼此独立。
(2)这种架构允许新旧进程同时共存:
升级时,新版本的 Master 进程和 Worker 进程会被启动,而旧进程仍保持运行。
新旧 Worker 进程同时监听相同的端口(通过 SO_REUSEPORT套接字选项),确保请求不会丢失。
三、Nginx负载均衡策略与IP透传实战指南
(一) Nginx 常用的负载均衡调度算法
1. 轮询
工作原理 :这是 默认 的调度算法。Nginx 将收到的请求 按顺序、逐一地 分发到配置在 upstream块中的每一台服务器。循环完列表中的所有服务器后,又回到第一台开始新一轮循环。
适用场景:
后端所有服务器 硬件配置、性能、负载几乎完全相同。
处理的请求是 无状态的,或者通过其他方式(如共享Session)保证了状态。
适用于最简单的负载均衡需求,配置简单,无需过多考虑服务器差异。
特点:绝对公平,但不考虑服务器实际负载和能力差异。
2. 加权轮询
工作原理 :轮询算法的增强版。管理员可以给每台服务器分配一个 权重(weight)。权重越高的服务器,被分配到的请求比例就越高。
例如,权重为 3:2:1的三台服务器,在大量请求下,它们接收的请求数比例也大致是 3:2:1。
适用场景:
后端服务器 硬件配置不一致,性能有差异。这是 最常用的场景。
希望让性能更强的新服务器处理更多流量,或者让性能较弱的旧服务器处理更少流量,逐步下线。
3. IP 哈希
工作原理:根据客户端的 IP 地址 通过哈希算法计算出一个值,用这个值来决定将请求分配给哪台服务器。
关键特性 : 同一个客户端的 IP 将会始终映射到同一台后端服务器 (只要 upstream组中的服务器列表不变)。
适用场景:
需要 会话保持的应用。这是其最主要的目的。
如果应用程序本身 不支持分布式 Session ,且 Session 数据只存储在单台服务器的内存中,则必须使用 ip_hash来确保用户的所有请求都落在同一台服务器上,否则会出现登录状态丢失等问题。
需要保证来自同一来源的请求有序地被处理。
4. 最少连接
工作原理 :将新的请求 动态地 分发到当前活跃连接数最少的那台后端服务器上。它考虑的是服务器的实时负载,而不是机械地轮询或依赖客户端IP。
适用场景:
后端服务器处理请求所需的 时间长短不一,差异较大。
例如,有些请求是短连接、快速响应的,而有些则是长连接、耗时较长的。
在这种场景下,轮询或加权轮询可能不均衡,因为某台服务器可能刚好分配了几个耗时长的请求,负载瞬间升高。而"最少连接"算法能更好地实现 负载的实时均衡,避免服务器过载。
(二)IP透传
定义
IP 透传,通常指的是在负载均衡架构中,将客户端的真实 IP 地址一路传递到最终处理请求的后端服务器上。默认情况下,当用户访问一个由 Nginx(或其他负载均衡器)代理的服务时,后端服务器看到的网络连接是来自负载均衡器本身的 IP 地址,而不是用户的真实 IP。IP 透传的目的就是为了打破这种"伪装",让后端服务器像直接面对用户一样,能够准确地获取到用户的真实 IP 地址
IP 透传的原理
IP透传有两种:HTTP头部传递,TCP代理协议
1.HTTP 头部传递
这种方法主要适用于 HTTP/HTTPS 协议。
原理:负载均衡器在将客户端请求转发给后端服务器之前,会在 HTTP 请求头中添加一个特殊的字段,并将客户端的真实 IP 地址放入这个字段中。
工作流程:
-
用户(IP: 10.0.0.12)请求负载均衡器(IP:
192.168.1.100)。 -
负载均衡器接收到请求。
-
负载均衡器将请求转发给后端 Web 服务器(IP:
10.0.0.10),并在转发前修改请求头: -
后端 Web 服务器(如 Nginx, Apache, 或应用程序)就可以从
X-Forwarded-For或X-Real-IP头中获取用户的真实 IP,而不是负载均衡器的 IP (192.168.1.100)。
2. TCP 代理协议
这种方法适用于 四层(TCP/UDP) 负载均衡,也可以用于七层。它比 HTTP 头部传递更底层、更通用。
原理:负载均衡器在与后端服务器建立 TCP 连接后,在发送应用数据(如 HTTP 请求)之前,先插入一行特殊的、文本格式的协议头。这行头信息包含了客户端的真实 IP 和端口。
工作流程:
-
用户请求负载均衡器。
-
负载均衡器与后端服务器建立 TCP 连接。
-
连接建立后,负载均衡器首先发送一行 PROXY 信息,包含PROXY 协议版本 客户端IP 负载均衡器IP 客户端端口 目标端口
-
发送完这行协议头后,再开始正常转发客户端的原始数据(如 HTTP 请求)。
-
后端服务器必须被配置为能理解 PROXY 协议,它会先解析这行头,获取真实客户端 IP,然后再处理后续的应用数据。
三、为何需要在负载均衡场景中实现 IP 透传?
-
访问日志记录与审计失准
-
问题:如果后端服务器记录的是负载均衡器的 IP,那么所有访问日志的"客户端IP"都是同一个(负载均衡器的IP)。这使得日志分析、流量统计、安全审计变得毫无意义,无法追踪真实用户的行为。
-
需求 :业务运营、数据分析、故障排查都需要真实的用户访问信息。
-
-
安全防护与访问控制失效
-
问题:许多安全措施依赖于客户端 IP。例如:
-
限速:限制单个 IP 的请求频率。如果所有请求都来自负载均衡器 IP,限速功能要么对所有用户整体生效,要么完全失效。
-
IP 黑/白名单:无法阻止恶意 IP 的访问,也无法允许可信 IP 的访问。
-
安全扫描与威胁情报:无法根据恶意 IP 库来拦截特定攻击者。
-
-
-
应用程序逻辑错误
-
问题:应用程序本身可能有一些直接读取客户端 IP 的逻辑,例如:记录操作者 IP、在页面中显示用户 IP 等。如果获取到的是负载均衡器的 IP,会导致功能错误。
-
需求 :保证应用程序功能的正确性。
-
四、负载均衡实验实践
首先进行环境准备

需要四台主机,一个服务端(10.0.0.12)一个代理主机(10.0.0.13),两个后端主机(10.0.0.14,10.0.0.16)
首先对10.0.0.13代理服务器进行设置
配完成后重启服务:systemctl restart nginx

然后对Real Server - 1 10.0.0.16的主机配置定制

然后重启,重启过程中可能会有一个报错

sudo rm /etc/nginx/sites-enabled/default 删除一下就好了
然后对Real Server - 2 10.0.0.14的主机配置定制

然后重启服务
测试负载均衡服务

可以看到只有一个服务器响应,这种情况大概率是另一台服务器的防火墙进行了拦截,关闭即可

再次测试,达到了负载均衡的效果

接下来对负载均衡进行一下加权,主要是在代理服务器上进行配置

效果如图

实现IP透传
修改代理服务器,增加透传配置

修改后端服务器


重新测试,透传成功

四、HTTPS安全传输原理及Nginx会话管理策略对比
一、HTTPS 工作流程 (SSL/TLS 握手)
过程可分为两大阶段:TLS 握手 和 加密数据传输。
TLS 握手阶段 (以 RSA 密钥交换为例)
目标 :在不安全的网络上,安全地协商出一个只有客户端和服务器知道的对称会话密钥,用于后续加密数据。使用非对称加密来交换这个对称密钥。
-
客户端向服务端Hello
-
客户端向服务器发起加密通信请求,并发送信息:
-
支持的 TLS 协议版本(如 TLS 1.2, TLS 1.3)。
-
客户端生成的随机数 。
-
支持的密码套件列表。
-
支持的压缩方法。
-
-
-
服务端回应客户端Hello
-
服务器回应客户端,确认后续通信参数:
-
确认使用的 TLS 版本。
-
服务器生成的随机数 。
-
从客户端列表中选择一个密码套件。
-
服务器的数字证书。
-
-
-
证书验证
-
客户端验证服务器证书的有效性:
-
是否由可信的证书颁发机构(CA)签发?
-
证书是否在有效期内?
-
证书中声明的域名是否与正在访问的域名一致?
-
-
如果验证失败,浏览器会发出严重警告。
-
-
随机数的生成与加密
-
客户端生成另一个随机数。
-
客户端用 从服务器证书中获取的公钥加密这个 随机数,发送给服务器。
-
-
密钥生成
-
服务器 :用自己的 私钥解密收到的 随机数。
-
客户端和服务器 :双方现在都拥有 客户端随机数、服务器随机数和 密钥。它们使用相同的算法,根据这三个随机数生成 相同的对称会话密钥
-
-
握手完成
-
客户端和服务器互相发送一条消息,通知对方后续消息将使用刚刚协商的会话密钥进行加密通信。
-
至此,安全通道建立完成。
-
加密数据传输阶段
之后的所有 HTTP 请求和响应数据,都使用协商出的对称会话密钥进行加密和解密。
二、Nginx 配置 HTTPS
-
服务器私钥
-
通常以
.key为后缀(如example.com.key)。 -
作用 :一个高度机密的文件,用于解密客户端发送的加密文件。必须严格保密。
-
生成方式 :
openssl genrsa -out example.com.key 2048
-
-
数字证书
-
通常以
.crt或.pem为后缀(如example.com.crt)。 -
作用:包含服务器公钥、域名、签发机构等信息,向客户端证明身份。
-
来源:从证书颁发机构(CA)(如 Let's Encrypt, DigiCert)购买或申请免费证书。也包含中间证书。
-

三、"会话绑定" vs "会话复制"
会话绑定
原理:
负载均衡器通过一定策略将同一个用户的所有请求始终路由到同一台后端服务器上。
用户的 Session 数据只存储在他第一次访问的那台服务器内存中。
工作方式:
用户首次访问,负载均衡器通过算法将其请求转发到服务器 A,并在响应中种下一个包含服务器标识的 Cookie。
用户下次请求时,负载均衡器查看 Cookie 或 IP,继续将其请求发给服务器 A。
优点:
实现简单,无需对后端应用做任何修改。
无性能开销,服务器之间不需要同步数据。
缺点:
缺乏容错性:如果服务器 A 宕机,其上所有用户的 Session 将全部丢失,用户需要重新登录。
可能导致负载不均:某些服务器可能因为绑定了大量活跃用户而负载过高。
适用场景:
对 简单性要求高、会话数据不重要或会话时间很短的应用。
中小型集群,服务器宕机风险可控。
开发测试环境。
会话复制
原理:
集群中的每一台服务器都保存所有用户的 Session 数据副本。
当任何一台服务器上的 Session 发生变化时(如用户登录、修改数据),它会将这个变化 广播或组播到集群中的所有其他服务器,保持所有副本的数据一致性。
工作方式:
用户请求到达任意服务器(如服务器 B)。
服务器 B 本地就有该用户的 Session 数据,可以直接处理。
如果用户在服务器 B 上更新了 Session,服务器 B 会将该更新操作通知给服务器 A、C、D...
优点:
高可用性和容错性:任何一台服务器宕机都无关紧要,用户的下一请求可以被路由到任何存活的服务器上并无缝继续,体验无损。
缺点:
性能开销大:网络带宽和服务器 CPU 资源被大量用于同步 Session 数据,服务器规模越大,同步开销越大。
实现复杂:通常需要 Web 容器本身的支持或借助第三方库。
适用场景:
对高可用性要求极高的应用如银行,不能接受任何因服务器宕机导致的服务中断。
集群规模不是特别大。
会话数据量较小,且更新不频繁。
五、Tomcat核心架构解析与Nginx反向代理实战及502排查
各核心组件详解
1. Connector (连接器)
作用 :Tomcat 的网络门户。负责监听网络端口,接受客户端(如浏览器、Nginx)的连接请求,并将收到的网络字节流转换成 Servlet 请求 ,同时将 Servlet 响应转换回网络字节流发送出去。
2. Engine (引擎)
作用 :一个 Service 的请求处理核心 。它接收来自一个或多个 Connector的请求,并根据请求中的主机名将其路由到正确的虚拟主机。
3. Host (虚拟主机)
作用 :实现基于域名的虚拟主机 。一个 Host代表一个虚拟主机,它允许你在同一台服务器、同一个 Tomcat 实例上部署多个独立的网站,并通过不同的域名进行访问。
4. Context (应用上下文)
作用 :代表一个独立的 Web 应用程序 。这是 Tomcat 中真正运行你的 WAR 包或项目文件的地方。每个 Context对应一个 Web 应用,并有一个唯一的路径。
Nginx反向代理Tomcat,及错误分析
我们需要三台主机扮演四个角色

用户访问 Nginx 服务器(10.0.0.12),由 Nginx 根据负载均衡策略,将请求转发到后端的任意一台 Tomcat 服务器上。
我们首先要对后端以及代理服务器的界面进行配置,修改首页内容,使网站更加直观
对于10.0.0.12

页面显示

对于10.0.013

页面显示

对于10.0.0.14

页面显示

我们的页面都做好了以后
对于代理服务器进行代理转发的配置
vim /etc/nginx/conf.d/tomcat-proxy.conf

检查语法是否正确
然后重新加载
如果一切正常我们的反向代理就做好了,反复刷新访问代理网站,会轮流出现不同网页



502 Bad Gateway
但是在配置过程中极其容易出现502错误
情况一:SELinux权限问题
错误特征 :(13: Permission denied) while connecting to upstream
解决方案 :
sudo setsebool -P httpd_can_network_connect 1
sudo setenforce 0
情况二:防火墙阻止
解决方案 :# 开放后端端口(以8080为例)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
情况三:Nginx配置错误
检查配置语法 :sudo nginx -t
情况四:端口监听是否正确
检查监听的端口:netstat -tlnp | grep 端口
倘如没有ipv4端口可以
vim /etc/tomcat10/tomcat.conf
最后一行添加
强制使用 IPv4
CATALINA_OPTS="-Djava.net.preferIPv4Stack=true"
六、Nginx知识体系结构化总结(思维导图)
https://gitmind.cn/app/docs/m0l5w681

七、项目实战:LNMP架构部署与典型问题解决方案
业务场景与核心需求
业务场景: 一个企业官网或内容管理系统(CMS),例如 WordPress、DedeCMS 等。需要展示公司信息、发布新闻、提供产品展示和联系方式。
核心需求:
-
高并发处理: 网站需要能够承受一定量的用户同时访问,尤其是在发布新产品或有推广活动时,流量会短时激增。要求架构能快速响应大量 HTTP 请求。
-
高可用性: 网站需要保持 7x24 小时稳定运行,避免长时间宕机,确保用户随时可以访问。
-
数据安全与一致性: 用户提交的数据(如留言、订单)需要被可靠地存储,不能丢失。
-
快速开发与部署: 使用成熟的 LNMP 技术栈,便于开发和后期维护。
结构图

各组件角色与通信方式
| 组件 | 角色说明 | 通信方式 |
|---|---|---|
| Linux | 操作系统层。为所有上层组件提供稳定、高效、安全的运行环境。 | |
| Nginx | Web 服务器和反向代理。 1. 处理静态请求:直接返回用户请求的图片、CSS、JavaScript 等文件,效率极高。 2. 反向代理:接收所有用户请求,如果是 PHP 动态请求,则通过 FastCGI 协议转发给 PHP-FPM 处理。 | 与用户:HTTP/HTTPS (80/443端口) 与 PHP-FPM:FastCGI (通常为 9000 端口) |
| PHP-FPM | PHP 进程管理器。负责解析和执行 Nginx 转发过来的 PHP 脚本。它管理着一个 PHP 进程池,处理动态内容(如从数据库取数据、生成页面)。 | 与 Nginx:FastCGI (9000端口) 与 MySQL:MySQL Protocol (3306端口) |
| MySQL | 关系型数据库。负责存储网站的所有动态数据,如文章内容、用户信息、配置设置等。 | 与 PHP-FPM:MySQL |
部署步骤
1.更新系统,配置防火墙,确保网络畅通
下载基础命令

配置防火墙

2.安装各个组件
安装nginx,并设置为开机自启动

安装并配置数据库软件

启动软件

运行安全配置脚本

按照提示进行以下安全设置:
输入 root 密码(务必记住这个密码)。
移除匿名用户?Y
禁止 root 远程登录?Y(对于本地实验,允许远程登录更简单,可以选 n)。
移除测试数据库?Y
立即重载权限表?Y
测试登录 MySQL

安装 PHP 与 PHP-FPM

启动sudo systemctl enable --now php-fpm

3.配置组件协同工作
配置 Nginx 处理 PHP 请求
备份原始默认配置
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
编辑 Nginx 主配置文件
vim /etc/nginx/nginx.conf


然后进行重载配置:sudo systemctl reload nginx
创建测试文件,验证 LNMP 联动
创建 PHP 信息测试页
echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/html/info.php


基础环境已经搭建成功
登录 MySQL,创建测试数据库和表
mysql -u root -p

创建 PHP 页面连接数据库
vim /usr/share/nginx/html/dbtest.php


LNMP试验成功!
部署过程中遇到的典型问题及解决方案
问题一:Nginx 返回 "502 Bad Gateway" 错误
现象 : 访问 .php 页面时,浏览器显示 502 错误
排查思路:
检查 PHP-FPM 服务状态 : systemctl status php-fpm。发现服务是 inactive (dead) 状态。
启动 PHP-FPM : systemctl start php-fpm。再次访问,问题可能解决。
如果启动失败,查看 PHP-FPM 日志 : 日志通常在 /var/log/php-fpm/error.log。可能会发现配置错误,例如监听地址/端口冲突。
问题二:PHP 页面无法连接 MySQL 数据库
现象: 网站程序在安装时,或在访问需要数据库的页面时,提示 "Can't connect to MySQL server" 或 "Access denied for user"。
排查思路:
在服务器上命令行测试 MySQL 连接 : mysql -u root -p,输入密码看能否登录。这可以排除 MySQL 服务本身的问题。
检查数据库用户权限 : 确保你的程序使用的数据库用户允许从 localhost(因为 PHP 和 MySQL 在同一台机器)连接,并且有对应数据库的权限。
CREATE DATABASE myapp_db;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
检查 PHP 程序配置文件 : 确保 WordPress 的 wp-config.php 或其他程序的数据库配置文件中,主机名(host)、用户名、密码、数据库名完全正确。
根本原因与解决方案:
原因1: 数据库、用户或权限没有正确创建。
解决: 严格按照上述步骤创建并授权。
原因2: MySQL 的 root 用户默认只允许本地 socket 连接,而不是 TCP/IP 连接(127.0.0.1)。
解决 : 确保 PHP 程序配置中使用 localhost(会优先使用 socket 连接)或者正确配置了 PHP-FPM 使用 TCP/IP 方式连接。对于本地连接,使用 localhost 通常更可靠。