第三天笔记

课堂笔记 & 面试题(详细版)

课程:Web安全环境搭建(LNMP + DVWA)

系统环境:Windows + Ubuntu(VMware虚拟机)


一、课堂笔记(详细版)


第1部分:基础环境问题

1.1 PHPStudy启动问题
  • 现象:很多同学的PHPStudy无法正常启动

  • 根本原因 :之前安装过MongoDB等数据库导致参数冲突

  • 关键操作

    复制代码
    查看日志 → 发现系统反复报错某个参数问题 → 非真正的启动失败
  • 解决方案

    1. 查看PHPStudy日志定位具体报错参数
    2. 使用cloud环境规避本地配置冲突(推荐)
    3. 卸载冲突的数据库软件
  • 重点:这类问题常见于之前安装过其他数据库的电脑上,查看日志是准确定位的关键

1.2 Windows管理员权限
  • 核心原则 :Windows系统中以管理员身份运行程序至关重要
  • 具体场景
    • 普通cmd运行可能受限
    • 使用管理员权限的PowerShell 才能顺利执行像 open code 等命令
    • 因为这些命令可能需要修改注册表等关键系统参数
  • 实际案例 :有同学和Claude AI纠缠两个多月的问题,本质上就是权限问题
  • 延伸:PHPStudy中运行MySQL时,本质上也是通过管理员命令来启动的
1.3 MySQL服务启动失败
  • 主要病因参数格式错误

    • 配置文件出现多余参数(非标准的 "--参数" 格式)
    • 系统因无法识别而报错
    • 这种错误比端口冲突更隐蔽
  • 特别注意

    • 不要轻信某些免费AI工具的诊断结果(如把PHPStudy配置问题误判为模型问题)
    • 建议切换更可靠的模型来分析,比如使用GLM模型
  • 提问模板

    复制代码
    "分析我的phpstudy中MySQL服务异常启动的原因,是否由于以下问题..."
  • 关键点:参数规范性和诊断工具的选择

1.4 MySQL环境混乱
  • 现状:很多同学电脑上同时安装了多个版本的MySQL(5.7、8.0)甚至MongoDB
  • 后果:端口冲突 + 配置混乱
  • 建议:保留一个主要版本,其他冗余数据库软件卸载
1.5 DVWA访问问题
  • 问题 :直接用 http://dvwa 无法访问
  • 替代方案 :尝试 http://127.0.0.1:81
  • 原因:DVWA默认运行在81端口;火狐浏览器安全设置限制
  • 解决方案:调整火狐浏览器配置
1.6 AI工具推荐
  • 推荐工具
    • Kimi:可用于搜索技术问题解决方案
    • GLM:coding plan效果不错(但需要抢购;5.2版本开始收费)
  • 注意事项
    • 充值后可能很快就欠费下线
    • 有些工具可能给出需要付费的无关建议,可直接忽略
    • 个别同学遇到浏览器兼容性问题
1.7 问题描述规范
  • 核心原则:把问题描述得清晰完整

  • 示例 (火狐浏览器无法访问DVWA):

    复制代码
    1. 其他浏览器(如Edge)可以正常访问
    2. 通过 http://dvwa 域名无法访问
    3. 通过 127.0.0.1:81 本地地址可以访问
  • 好处:避免对方反复询问基础配置问题,直接锁定是浏览器与域名的兼容性问题

1.8 MD文档乱码
  • 原因:没装专业笔记软件
  • 推荐软件Typora(收费,可找替代/破解版)

第2部分:DVWA环境搭建与数据库

2.1 DVWA初始化操作
  • 关键操作路径

    复制代码
    浏览器访问 http://localhost/dvwa/login.php
    → 进入 setup.php 页面
    → 点击 "Create/Reset Database" 按钮进行初始化
2.2 DVWA报错分析
  • 误区:有同学认为报错是MySQL版本过低导致的
  • 事实:即使将MySQL升级到8.0.12高版本,同样的报错仍然存在
  • 根本原因 :DVWA官方推荐使用的是MongoDB数据库 而非MySQL
    • 报错本质是MongoDB的查询语法不兼容MySQL
    • 当遇到类似 "is not" 这样的语法报错时,说明语句不兼容
  • 常见错误类型is not 此类语法错误提示 → MongoDB语法用在MySQL里
2.3 配置文件修改原则
  • 不建议:让系统自动修改(可能有风险)

  • 建议 :手动查找问题文件,特别是根目录下的MySQL相关文件

    复制代码
    手动检查报错提示 → 定位到具体文件 → 修正语法问题
  • 核心原则:手动修改更安全,尤其涉及系统权限或关键配置时

  • 备选方案:把报错信息反馈给工具或社区


第3部分:Ubuntu系统基础

3.1 MySQL版本兼容性
  • 当前版本:8.0.12
  • 问题:不支持某些需要8.0.29及以上版本的功能
  • 解决方案
    1. 升级MySQL版本
    2. 修改对应的配置文件
3.2 Ubuntu登录方式
  • 重要区别:与红帽系统不同
  • 特点:Ubuntu安装时默认不会设置root密码
  • 常见错误:习惯性用红帽的操作方式来登录Ubuntu
  • 正确做法:使用安装时创建的普通用户先登录
3.3 root密码设置
  • 背景:默认安装时系统不会引导设置root密码

  • 操作步骤

    复制代码
    sudo passwd root
    • 需要通过终端用sudo提权才能修改
    • Ctrl+Shift 放大终端界面
  • 密码复杂度

    • "123456" 被拒(过于简单)
    • "openlab123" 才成功
  • 注意事项 :如果安装时跳过了root密码设置,后期只能通过 sudo passwd root 命令强制修改,但必须提权操作

  • 权限管理:系统会反复要求验证,说明权限管理很严格

3.4 远程连接工具
  • 场景:在虚拟机环境中直接操作不太方便

  • 推荐工具:Xshell、MobaXterm等

  • 关键步骤

    复制代码
    ① 新建一个主机连接
    ② 输入正确的IP地址(如 192.168.50.158)
    ③ 保持默认的SSH 22端口
    ④ 使用root用户名和对应密码登录
  • 原理:大多数远程连接工具操作逻辑相通


第4部分:SSH远程连接与排查

4.1 SSH连接失败排查步骤
  • 第一步:确认网络连通性

    复制代码
    ping 192.168.50.158    # 测试主机到虚拟机
    ping 192.168.50.1      # 测试虚拟机到主机(网关)
  • 第二步:检查sshd服务是否开启

    复制代码
    systemctl status sshd
  • 常见误区:以为是root用户权限问题

  • 事实 :服务未启动才是常见原因 比喻:你有了钥匙(账号密码),但门锁根本没安装(服务未开启)

  • 两个基础条件:网络通畅 + 服务运行

4.2 apt更新与权限
  • 普通用户 :执行 apt update 会遇到权限不足

  • 解决方案

    复制代码
    su root       # 先切换到root用户
    输入密码
    apt update    # 顺利更新软件包列表
  • 安装软件

    复制代码
    apt install <软件包名>
    • 注意软件包名称拼写,输入错误会提示"无法定位"
    • 可尝试安装其他已知软件包来测试网络连接是否正常
  • 对比:与yum的使用很相似(先更新再安装)

4.3 SSH安装与启动
  • 安装

    复制代码
    apt install ssh
  • 问题:默认sshd服务没有启动

  • 排查

    1. 可能是防火墙问题
    2. 可能是SELinux问题
    3. 端口被占用(22端口)
4.4 Ubuntu防火墙(ufw)
  • 服务名ufw.service

  • 关闭命令

    复制代码
    systemctl stop ufw      # 临时关闭
    systemctl disable ufw   # 永久关闭
  • 日志查看:发现有关于22端口的报错信息,"fail to start"

  • 对比

    • Ubuntu → ufw
    • 红帽系 → firewalld
  • 排查顺序:服务启动失败 → 防火墙 → SELinux → 端口占用

4.5 SELinux
  • 设置宽松模式

    复制代码
    setenforce 0
  • 注意事项:如果命令缺失,系统会提示安装命令,直接运行给出的安装命令即可

  • 验证SSH:检查SSH服务是否能正常启动

4.6 最小化安装问题
  • 特点:U盘库属于最小化安装,很多组件需要手动下载
  • 操作:刚才只是进行了更新,所以会报错
  • 粘贴问题:发现无法粘贴内容
  • 变通方案:改用OpenSSH,先确保能连上服务器
  • 关键点:最小化安装需手动补全组件

第5部分:SSH root登录配置

5.1 家目录区别
  • 普通用户 :家目录 /home/用户名
  • root用户 :家目录 /root
  • 重要:要先切换到root用户家目录再运行程序
  • 验证:SSH显示 "active running" 状态时服务已正常
5.2 SSH允许root登录
  • 配置文件/etc/ssh/sshd_config

  • 要修改的参数PermitRootLogin(注意P是大写)

  • 操作步骤

    复制代码
    ① vim /etc/ssh/sshd_config
    ② 找到 PermitRootLogin 这一行
    ③ 默认是 "no",改成 "yes"
    ④ :wq 保存退出
    ⑤ systemctl restart sshd    # 必须重启服务
  • 注意事项

    • 配置文件路径要找准
    • 改完必须重启服务(很多同学会忘记)
    • 默认不允许root远程登录是出于安全考虑
    • 生产环境要谨慎修改
5.3 源码安装 vs 包管理器安装
  • 源码安装:可自定义路径和参数,灵活但维护成本高
  • 包管理器(apt install):自动处理依赖但默认路径不直观
  • 适用场景:需要深度定制时选择源码安装
5.4 Vim操作小贴士
  • 保存退出::wq
  • 服务名太长时可以修改(如 "White House" 的例子)
  • 重启服务是配置生效的必要步骤

第6部分:文件传输与解压缩

6.1 文件传输方式
  • 方式一:U盘 → 直接拷贝到目标目录(如 /opt

  • 方式二:FTP工具(sftp)

    复制代码
    sftp root@192.168.50.158
  • 重点:文件存放路径要清晰,便于后续查找

6.2 tar解压缩
  • 常用命令

    bash 复制代码
    # 解压 gzip 格式
    tar -xzvf 文件名.tar.gz
    
    # 解压 bzip2 格式
    tar -xjvf 文件名.tar.bz2
    
    # 解压 zip 格式(需先安装 unzip)
    unzip 文件名.zip
6.3 参数详解
参数 作用 说明
-x extract(解压)
-z gzip格式 对应 .tar.gz
-j bzip2格式 对应 .tar.bz2
-v verbose(显示详情)
-f file(指定文件名) 必须是最后一个参数
-G(大写) gzip旧版本 注意大小写区别
-g(小写) 旧版格式 容易混淆
  • 建议:虽然系统有时能自动识别压缩格式,但最好显式指定参数,避免意外错误

第7部分:Nginx源码安装

7.1 准备工作
  • 解压安装包

    bash 复制代码
    tar -xvf nginx.tar.gz
    cd nginx-版本号/
  • 安装编译工具

    bash 复制代码
    apt install gcc make wget
    • gcc:C语言编译器
    • make:编译管理工具
    • wget:下载工具(可选但推荐)
7.2 configure(配置检查)
  • 作用:检查系统环境,确认依赖包是否齐全、环境是否匹配

  • 自定义安装目录

    bash 复制代码
    ./configure --prefix=/usr/local/nginx
  • 默认路径/usr/local/

  • 执行后:观察终端输出,出现类似列表的配置摘要信息时表示检测完成

7.3 依赖处理
  • 常见缺失 :pcre库

    bash 复制代码
    apt install pcre*
  • 原则:不确定具体缺哪个版本,可以直接安装通配版本

  • 快速方法:遇到不认识的报错信息,直接复制错误内容去搜索

7.4 编译与安装(核心三步)
bash 复制代码
./configure       # 第一步:配置检查
make              # 第二步:编译(把源码变成可执行文件)
make install      # 第三步:安装到指定目录
7.5 验证安装
bash 复制代码
cd /usr/local/nginx
ls                 # 查看是否有 sbin/ 等关键目录
cd sbin
./nginx            # 启动Nginx
curl 127.0.0.1     # 验证:看到"thank you for using nginx"即成功
7.6 启动与重载
  • 启动 :必须手动到安装目录启动(源码安装没有系统服务配置)

    bash 复制代码
    /usr/local/nginx/sbin/nginx
  • 重载配置

    bash 复制代码
    /usr/local/nginx/sbin/nginx -s reload
  • 比喻:验证环节像打电话,听到对方"喂"的回应就知道线路接通了


第8部分:PHP环境与PHP-FPM

8.1 PHP安装
  • 组件:PHP解析器 + php-fpm + php-pm等相关组件

  • 特别注意

    • 如果命令显示为多行,需要手动调整成一行才能正确执行
    • MySQL数据库其实更推荐使用MariaDB替代
  • sudo提权

    bash 复制代码
    sudo make install
    sudo apt install 包名
8.2 多版本PHP管理
  • 问题:安装php-fpm后发现实际运行版本是php8.5-fpm,但系统默认寻找php8.3

  • 解决方法 :用完整服务名指定版本

    bash 复制代码
    systemctl status php8.5-fpm
  • 比喻:同时拥有多个遥控器,必须拿对对应的设备

8.3 Nginx根目录
  • 默认:html文件夹(不是常见的www目录)
  • 验证:创建a.html并访问
  • 注意:文件编码要用UTF-8,否则出现乱码
8.4 Nginx与PHP-FPM协同
  • 核心原理 :Nginx默认不能解析PHP文件

    • 遇到.php请求时直接返回源码文件
    • 浏览器误以为要下载
  • 解决方案 :把PHP文件交给php-fpm处理

    复制代码
    Nginx → fastcgi_pass 127.0.0.1:9000 → php-fpm
  • 定位php-fpm :查看 www.conf 配置文件

    bash 复制代码
    find / -name "www.conf"
8.5 端口监听配置
  • 修改php-fpm配置文件

    复制代码
    listen = 127.0.0.1:9000
  • 关键细节

    • 端口号9000类似快递柜编号,准确定位php-fpm服务
    • 修改后必须 restart 生效
    • 注意配置格式(冒号必须是英文符号)
  • 注释符号 :该配置文件用 ; 分号注释,不能用 # 井号

  • 检查端口

    bash 复制代码
    ss -antulp | grep 9000
8.6 grep查找配置文件
  • 场景:知道文件内容但不确定路径

  • 命令

    bash 复制代码
    grep -r "fastcgi_pass" /etc/
  • 参数说明

    • -r:递归搜索
    • 搜索内容放在命令最后(易错点:很多人会把路径放在-r后面)
    • -n:显示匹配行号
  • 加速技巧 :缩小搜索范围到具体目录,如 /usr/local/

8.7 Vim批量操作
vim 复制代码
:set nu            " 显示行号,方便定位
:65,71s/#//g       " 批量删除65到71行的#号
  • s 表示替换
  • #// 表示把#替换为空
  • g 确保每行所有匹配项都被处理
8.8 FastCGI路径配置
  • 原配置:路径有误

  • 修正

    复制代码
    $document_root$fastcgi_script_name
  • 特别注意:源码安装重启nginx需要用sbin下的启动文件,不能用systemctl

8.9 验证PHP解析
bash 复制代码
# 检查9000端口
lsof -i :9000

# 创建测试文件 test.php
echo "<?php phpinfo(); ?>" > /usr/local/nginx/html/test.php

# 浏览器访问 test.php
# 正常:显示PHP执行结果
# 异常:出现下载提示(说明php-fpm和nginx未联通)

第9部分:MariaDB数据库

9.1 安装与启动
bash 复制代码
# 安装
apt install mariadb-server mariadb-client

# 检查状态
systemctl status mariadb
# 显示 "active" 说明数据库正在运行

# 进入数据库(初始root无密码)
mariadb
# 或
mysql -u root -p
9.2 设置root密码
sql 复制代码
-- 进入MySQL/MariaDB后
ALTER USER 'root'@'localhost' IDENTIFIED BY 'openweb123';
FLUSH PRIVILEGES;  -- 刷新配置(必须执行)
  • 注意:修改后必须刷新配置才能生效,不能只看系统提示"重置成功"
  • 比喻:改了手机密码后,需要重启手机才能确保新密码真正生效
9.3 root无密码特性
  • 现象:即使输入错误密码也能登录成功

  • 原因:这是MariaDB/MySQL超级用户的设计特性

  • 验证方法 (反向验证密码是否生效):

    复制代码
    ① 重启mariadb服务
    ② 退出到普通用户
    ③ 用错误密码尝试登录 mysql -u root -p
       - 被拒绝 → 密码设置成功
    ④ 用正确密码登录验证
  • 普通用户:必须正确输入密码才能访问数据库

9.4 数据库权限原则
  • root:最高权限,生产环境避免直接使用

  • 生产环境 :遵循最小权限原则,创建专用用户

    sql 复制代码
    CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'password';
    GRANT SELECT, INSERT, UPDATE ON dvwa.* TO 'webuser'@'localhost';
  • 操作 → 验证:Linux系统管理的典型闭环思路


第10部分:权限问题与DVWA部署

10.1 403错误排查
  • 原因一 :文件权限不足

    • 检查:ls -l login.php
    • 修复:chmod 755 login.php
  • 原因二 :文件所有者不匹配

    • nginx运行用户:nobody(通过 ps -aux | grep nginx 查看)

    • php运行用户:www-data

    • 修复:

      bash 复制代码
      chown www-data:www-data login.php
      chmod 777 login.php    # 临时测试用
  • 原因三:缺少索引文件

10.2 500错误
  • 含义:服务端配置问题
  • 常见原因:Nginx配置错误、PHP-FPM未运行、.htaccess语法错误
10.3 DVWA部署步骤
bash 复制代码
# 1. 将DVWA文件夹移动到html目录
mv DVWA-master /usr/local/nginx/html/dvwa

# 2. 复制配置文件
cd dvwa/config
cp config.inc.php.dist config.inc.php

# 3. 编辑配置文件
vim config.inc.php
# 修改数据库密码部分

# 4. 浏览器访问
# http://localhost/dvwa/setup.php
# 点击 Create/Reset Database
  • 特别注意:实际部署时不要用root账户连接数据库,权限过高很危险
  • 配置前备份cp config.inc.php.dist config.inc.php.bak
10.4 数据库不存在问题
  • 原因:代码里尝试连接名为"dvwa"的数据库,但这个数据库并不存在
  • 解决 :需要先运行 setup.php 文件进行初始化
  • 注意:DVWA系统推荐使用MongoDB,MySQL虽然能运行但需调整命令

第11部分:PHP版本与Docker

11.1 多PHP版本管理
  • 场景 :不同靶场对PHP版本要求不同

    • 有些需要高版本
    • 有些漏洞复现必须用低版本(如PHP5.6)
  • 旧版本安装 :需要手动添加特殊源

    • 常规源只提供新版本
    • 404报错说明当前源不可用
    • 需搜索解决方案(通过Ubuntu系统添加特定源)
  • update-alternatives

    bash 复制代码
    update-alternatives --config php
    # 交互式选择要使用的PHP版本
11.2 Docker容器技术
  • 核心价值:解决"在我机器上能跑,在你机器上就报错"的环境差异问题

  • 本质:打包好的环境"盒子",把所有依赖装在一起

  • 基础命令

    bash 复制代码
    docker pull 镜像名     # 拉取镜像
    docker images          # 查看本地镜像
    docker run 镜像名      # 运行容器
  • 比喻:像网购一样搜索想要的镜像,找到就直接pull使用

  • 适用场景:渗透测试不需要深入理解Docker底层原理,掌握基本命令即可

11.3 国内Docker使用
  • 障碍:访问外网受限

  • 解决方案一 :配置国内镜像加速器(阿里云、网易云等)

    bash 复制代码
    # 修改 /etc/docker/daemon.json
    {
      "registry-mirrors": ["https://你的加速器地址.mirror.aliyuncs.com"]
    }
  • 解决方案二 :设置VPN代理

    • 单独给Docker配置VPN
    • 或给整个Ubuntu系统设置永久VPN代理(修改 ~/.bashrc
11.4 源码编译Nginx与Systemd
  • 直接运行./nginx 就行,不一定需要Systemd管理
  • 如果需要systemctl控制 :需要准备对应的服务单元文件 .service
  • 操作建议:不要全盘照搬参考材料,有选择地参考

第12部分:网络配置与排错

12.1 NAT模式配置
  • 核心要求 :虚拟机IP必须和主机VMnet8在同一网段

    复制代码
    主机VMnet8: 192.168.x.x
    虚拟机: 192.168.x.x(同一网段)
  • 后果:不在同一网段则网络完全不通

12.2 DNS设置
  • 常见错误:设为 127.0.0.1(本地回环地址)

  • 后果:apt update失败(解析不了域名)

  • 正确做法

    bash 复制代码
    # 编辑 /etc/resolv.conf
    nameserver 8.8.8.8
    nameserver 114.114.114.114
12.3 桥接模式
  • 问题:桥接模式下使用手机热点上网需要特殊设置
  • 排查步骤
    1. 确认连接方式(桥接/NAT)
    2. 检查IP地址配置
    3. 检查DNS设置
12.4 系统快照
  • 重要性:操作前先建立快照,像给电脑拍个照片存档
  • 好处:万一后续操作出问题,可以快速恢复到之前正常工作的状态
  • 线上同学:也要遵循这个操作步骤
12.5 密码管理
  • 常见混淆:把数据库密码当成系统密码
  • 建议:不同系统的密码分开管理
  • root账户:初始是没有密码的,需要自己后续设置
12.6 sudo su root
  • 场景:普通用户登录后无法直接切换到root(因为root没密码)

  • 命令

    bash 复制代码
    sudo su root
    # 输入当前普通用户的密码
  • 前提:普通用户必须有sudo权限


二、面试题(详细版)


基础篇


Q1: Ubuntu系统安装后默认能直接用root登录吗?为什么?详细说明正确的登录流程。

A: 不能直接使用root登录。

原因

Ubuntu与红帽系Linux不同,安装时默认不会设置root密码,也没有引导用户设置root密码的环节。系统仅创建一个具有sudo权限的普通用户。

正确登录流程

复制代码
① 使用安装时创建的普通用户登录系统
② 打开终端,执行 sudo passwd root
③ 输入当前普通用户的密码(提权验证)
④ 设置root密码(需满足复杂度要求,如 openlab123)
⑤ 确认密码
⑥ 此后即可使用 su root 切换到root,或直接用root登录

注意事项

  • Ctrl+Shift 可以放大终端界面
  • 密码太简单(如 123456)会被系统拒绝
  • 如果安装时跳过了root密码设置,后期只能通过 sudo passwd root 强制修改

Q2: Ubuntu和红帽系Linux的防火墙管理命令有何不同?遇到服务启动失败时,应该按什么顺序排查?

A:

防火墙区别

项目 Ubuntu 红帽系(CentOS/RHEL)
管理工具 ufw firewalld
关闭命令 systemctl stop ufw systemctl stop firewalld
禁用命令 systemctl disable ufw systemctl disable firewalld

服务启动失败排查顺序(由外到内)

复制代码
① 服务状态检查 → systemctl status 服务名
② 日志查看 → journalctl -xe 或查看 /var/log/
③ 防火墙检查 → 是否拦截了服务端口
④ SELinux检查 → getenforce / setenforce 0
⑤ 端口占用检查 → ss -antulp | grep 端口号
⑥ 配置文件检查 → 参数格式、语法错误、注释符号

Q3: 如何修改SSH配置允许root远程登录?请写出完整的操作步骤和每个步骤的注意事项。

A:

操作步骤

bash 复制代码
# 步骤1:编辑SSH配置文件
vim /etc/ssh/sshd_config
  • 注意:P大写!是 PermitRootLogin 不是 Permitrootlogin

    步骤2:找到参数并修改

    默认内容:PermitRootLogin no

    修改为:PermitRootLogin yes

  • 在vim中可以用 :/PermitRootLogin 快速查找

    步骤3:保存退出

    :wq

  • 如果修改出错,用 :q! 强制不保存退出

bash 复制代码
# 步骤4:重启SSH服务使配置生效
systemctl restart sshd
  • 这是最关键也最容易遗漏的步骤!
bash 复制代码
# 步骤5:验证配置
systemctl status sshd
# 查看状态应为 active (running)

注意事项

  1. 默认不允许root远程登录是出于安全考虑
  2. 生产环境要谨慎修改此配置
  3. 如果修改后仍无法登录,检查防火墙是否放行了22端口
  4. 普通用户能远程连接不代表root用户也能连,需要单独测试

Q4: 请完整写出源码安装Nginx的全流程,包括验证步骤和常见问题的解决方法。

A:

完整流程(三步走)

bash 复制代码
# ---- 第一步:准备工作 ----
tar -xvf nginx-1.24.0.tar.gz     # 解压
cd nginx-1.24.0                  # 进入目录
apt install gcc make wget        # 安装编译工具

# ---- 第二步:配置(检查环境)----
./configure --prefix=/usr/local/nginx

执行后观察终端输出,出现配置摘要信息才表示检测完成。如果提示缺少pcre库:

bash 复制代码
apt install pcre* libpcre3 libpcre3-dev
apt install zlib1g-dev           # 可能还需要zlib

重新执行 ./configure 直到没有error。

bash 复制代码
# ---- 第三步:编译与安装 ----
make          # 编译(不报错即可继续)
make install  # 安装到指定目录

验证步骤

bash 复制代码
cd /usr/local/nginx/sbin
./nginx
curl 127.0.0.1

看到包含 "thank you for using nginx" 的HTML响应即成功。

常见问题

问题 原因 解决方法
configure报错 缺少依赖 apt install 对应库
make报错 环境问题或版本不兼容 检查gcc版本,清理重新编译
nginx启动失败 端口被占用 `ss -antulp
curl无响应 nginx未启动或防火墙拦截 检查nginx进程和防火墙状态

Q5: tar命令解压不同压缩格式时参数有何区别?请列举常用组合并说明参数含义。

A:

常用命令组合

bash 复制代码
tar -xzvf 文件名.tar.gz     # 解压 gzip 格式 (.tar.gz / .tgz)
tar -xjvf 文件名.tar.bz2   # 解压 bzip2 格式 (.tar.bz2)
tar -xJvf 文件名.tar.xz    # 解压 xz 格式 (.tar.xz)
tar -xvf  文件名.tar       # 解压普通 tar 包(无压缩)

参数含义

参数 含义 说明
-x extract 解压模式
-z gzip 处理 .gz 格式(对应gzip压缩)
-j bzip2 处理 .bz2 格式(对应bzip2压缩)
-J xz 处理 .xz 格式
-v verbose 显示解压过程
-f file 指定文件名(必须放在最后一个参数

创建压缩包

bash 复制代码
tar -czvf 归档名.tar.gz /要压缩的目录    # 创建gzip压缩
tar -cjvf 归档名.tar.bz2 /要压缩的目录   # 创建bzip2压缩

易混淆点

  • -G(大写)用于gzip旧版本,而不是普通的gzip解压
  • -g(小写)是处理旧版格式,完全不同
  • 虽然系统有时能自动识别,但显式指定参数更可靠

Q6: Nginx为何无法直接解析PHP文件?请详细说明LNMP架构下一次PHP请求的完整处理流程。

A:

原因

Nginx本身是一个Web服务器和反向代理服务器,它只擅长处理静态文件(HTML、CSS、JS、图片等)。它不包含PHP解析器 ,所以遇到 .php 文件时不知道如何执行,只能直接返回源码,导致浏览器误以为要下载文件。

完整处理流程

复制代码
① 用户在浏览器输入 http://服务器IP/index.php
② 请求到达Nginx
③ Nginx根据配置文件(nginx.conf)检查请求的文件类型
④ 发现是 .php 文件 → 根据 location ~ \.php$ 配置段进行处理
⑤ Nginx通过 fastcgi_pass 指令将请求转发给 php-fpm(默认 127.0.0.1:9000)
⑥ php-fpm 接收到请求,启动PHP解析器执行PHP代码
⑦ PHP代码中如果包含数据库操作,通过MySQL/MariaDB扩展连接数据库
⑧ PHP执行完成,将结果(HTML内容)返回给Nginx
⑨ Nginx将最终响应返回给客户端浏览器

配置要点(nginx.conf中):

nginx 复制代码
location ~ \.php$ {
    root           html;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

关键$document_root$fastcgi_script_name 路径配置必须正确,否则找不到PHP文件。


进阶篇


Q7: MariaDB中设置root密码后如何确认密码已生效?请详细说明"反向验证法"的原理和步骤。

A:

问题背景:MariaDB的root用户有特殊权限,即使输入错误密码有时也能登录,所以普通的"设置后立刻登录验证"不可靠。

反向验证法

复制代码
步骤1:重启MariaDB服务
  systemctl restart mariadb
  
步骤2:退出root用户,切换到普通用户
  exit  # 退出数据库
  su - 普通用户名

步骤3:用错误密码尝试登录
  mysql -u root -p
  输入错误密码(如 wrongpassword)
  
  结果分析:
  - 被拒绝(Access denied)→ ✅ 密码设置成功
  - 成功登录 → ❌ 密码未生效,需要重新设置

步骤4:用正确密码登录验证
  mysql -u root -p
  输入正确密码
  看到 MariaDB [(none)]> 提示符 → ✅ 一切正常

核心原理

  • root用户有绕过密码验证的设计特性
  • 重启服务可以刷新认证缓存
  • 普通用户没有绕过密码的特权
  • 用错误密码测试,如果被拒说明安全机制正常启用

注意事项

sql 复制代码
-- 正确的密码设置命令
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
FLUSH PRIVILEGES;  -- 必须执行刷新!

Q8: 当Linux系统中的一个服务无法启动时,请写出完整的系统性排查思路和对应的命令。

A:

系统性排查流程(从易到难)

bash 复制代码
# 第1步:查看服务状态
systemctl status 服务名
# 关注:active/exited/failed,以及最后几行日志

# 第2步:查看详细日志
journalctl -xe                    # 最近的系统日志
journalctl -u 服务名               # 该服务的所有日志
journalctl -u 服务名 --no-pager   # 不分页显示全部
tail -f /var/log/syslog           # 实时查看系统日志

# 第3步:检查网络端口
ss -antulp | grep 端口号           # 端口是否被占用
lsof -i :端口号                    # 哪个进程占用了端口

# 第4步:检查防火墙
# Ubuntu
systemctl status ufw
ufw status

# 红帽系
systemctl status firewalld
firewall-cmd --list-all

# 第5步:检查SELinux(红帽系)
getenforce                        # 查看SELinux状态
setenforce 0                      # 临时关闭(测试用)
# 查看SELinux是否阻止了服务
grep "SELinux" /var/log/messages
audit2why < /var/log/audit/audit.log

# 第6步:检查配置文件语法
nginx -t                          # 检查nginx配置
sshd -t                           # 检查ssh配置
php-fpm -t                        # 检查php-fpm配置

# 第7步:检查依赖和权限
ldd /usr/sbin/服务名               # 检查动态库依赖
ls -l /etc/服务名/配置文件         # 检查文件权限
ps -aux | grep 服务名              # 查看运行用户身份

经典案例

  • SSH启动失败 → 检查22端口是否被占用,防火墙是否拦截
  • Nginx启动失败 → nginx -t 检查配置语法
  • MySQL启动失败 → 检查 /var/log/mysql/error.log

Q9: 源码安装的Nginx和apt安装的Nginx在管理方式上有何不同?如何重载配置?为什么存在差异?

A:

管理方式对比

操作 源码安装 apt安装
启动 /usr/local/nginx/sbin/nginx systemctl start nginx
停止 /usr/local/nginx/sbin/nginx -s stop systemctl stop nginx
重载 /usr/local/nginx/sbin/nginx -s reload systemctl reload nginx
查看状态 `ps -aux grep nginx`
配置文件路径 /usr/local/nginx/conf/nginx.conf /etc/nginx/nginx.conf
网站根目录 /usr/local/nginx/html /var/www/html

为什么存在差异

  • 源码安装的本质是手动编译并复制文件到指定目录,不会注册到systemd
  • apt安装的包在安装时会自动创建 .service 单元文件到 /lib/systemd/system/
  • systemd管理的服务可以用 systemctl 统一控制
  • 源码安装更灵活但需要手动管理

给源码安装配置systemd服务(可选)

bash 复制代码
vim /etc/systemd/system/nginx.service

写入:

复制代码
[Unit]
Description=nginx service
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target
bash 复制代码
systemctl daemon-reload    # 重新加载systemd
systemctl enable nginx     # 设为开机自启

Q10: Nginx返回403 Forbidden错误的可能原因有哪些?请逐一说明排查方法和解决命令。

A:

可能原因 排查方法 解决命令
1. 文件权限不足 ls -l 文件路径 查看权限 chmod 755 文件路径
2. 目录权限不足 Nginx需要目录有执行权限 chmod 755 目录路径
3. 索引文件缺失 检查 nginx.conf 的 index 配置 index index.php index.html; 或创建文件
4. 用户身份不匹配 `ps -aux grep nginx` 看运行用户
5. SELinux限制 getenforce 查看状态 setenforce 0 或配置安全上下文
6. .htaccess限制 检查目录下是否有.htaccess 删除或修改.htaccess内容
7. 根目录配置错误 检查 nginx.conf 的 root 路径 修正 root 指向真实存在的目录

详细排查示例

bash 复制代码
# 查看nginx运行用户
ps -aux | grep nginx
# 输出类似: nobody   1234  ... nginx: worker process

# 检查文件属主
ls -l /usr/local/nginx/html/index.php
# 如果显示 -rw-r--r-- root root,而nginx用nobody运行 → 权限不匹配

# 修复
chown -R nobody:nobody /usr/local/nginx/html/
chmod -R 755 /usr/local/nginx/html/

# 测试配置
nginx -t
# 重载
./nginx -s reload

Q11: 在Vim编辑器中,如何批量删除多行注释符号?请写出完整的操作步骤并解释每个命令的含义。

A:

场景 :在nginx.conf或php-fpm配置文件中,有很多被 # 注释掉的行需要批量取消注释。

操作步骤

vim 复制代码
# 步骤1:显示行号,方便定位
:set number
" 或简写 :set nu
" 文件左侧会显示行号

# 步骤2:定位到需要操作的行
" 用 :65 跳转到第65行

# 步骤3:批量删除指定范围的注释
:65,71s/#//g

命令解析

复制代码
:           进入命令行模式
65,71       范围(从65行到71行)
s           替换命令(substitute)
/           分隔符
#           要查找的字符(#号)
/           分隔符
            替换为空(两个斜杠之间为空,即删除)
g           全局(global),一行中所有匹配都替换

更多Vim批量操作

vim 复制代码
# 删除整个文件的#号
:%s/#//g

# 删除每行开头的#号(只删第一个)
:%s/^#//

# 删除每行开头的#号和后面的空格
:%s/^#\s*//

# 在行首添加注释
:65,71s/^/#

# 批量替换端口号
:%s/9000/9001/g

注意事项

  • 有些配置文件(如php-fpm的www.conf)用 ; 分号注释,不是 #
  • 操作前最好先备份原文件::w 文件名.bak
  • 如果替换错误,用 u 撤销

Q12: 当你记得配置文件中包含某个关键词(如"9000"),但忘记了文件的具体路径时,应该如何快速定位?

A:

最佳方法:使用 grep 递归搜索

bash 复制代码
# 基础命令
grep -r "9000" /etc/

# 显示行号,便于查看上下文
grep -rn "9000" /etc/

# 显示匹配内容前后各2行
grep -r -B2 -A2 "9000" /etc/

# 只搜索 .conf 文件
grep -rn "9000" /etc/ --include="*.conf"

# 排除二进制文件
grep -rn "9000" /etc/ --exclude="*.log"

参数解释

参数 作用
-r 递归搜索子目录
-n 显示匹配行号
-B2 显示匹配行前2行(before)
-A2 显示匹配行后2行(after)
--include 只搜索指定类型文件
--exclude 排除指定类型文件

加速技巧

bash 复制代码
# 如果知道大概范围,缩小搜索目录
grep -rn "fastcgi_pass" /usr/local/

# 多关键词搜索
grep -rn "9000" /etc/ | grep -i php

# 结合find使用
find /etc/ -name "*.conf" -exec grep -l "9000" {} \;

常见易错点

  • 搜索内容必须在命令最后(容易犯的错误是把路径写在-r后面)
  • 用双引号包裹搜索内容,防止特殊字符被shell解释

Q13: PHPStudy中MySQL服务启动失败的可能原因有哪些?请逐一分析并提供排查方法。

A:

序号 原因 现象 排查与解决
1 参数格式错误 服务反复启停 检查配置文件中的参数是否为标准 "--参数名" 格式
2 多数据库冲突 启动报错参数冲突 之前是否装过MongoDB或其他版本MySQL?卸载冲突软件
3 端口被占用 提示端口已使用 `netstat -ano
4 配置文件语法错误 提示配置项不认识 检查my.ini/my.cnf是否有拼写错误
5 日志文件过大 启动失败日志满 清空或删除日志文件
6 权限不足 提示拒绝访问 以管理员身份运行PHPStudy
7 数据文件损坏 启动后立即崩溃 查看错误日志,修复或重建表

核心排查思路

复制代码
① 查看PHPStudy的错误日志(最关键!)
② 日志中会明确提示"参数问题"还是"端口问题"
③ 不要轻信免费AI工具的诊断(可能误判)
④ 推荐使用GLM等可靠工具,结构化提问

提问模板(使用AI工具时):

"分析我的PHPStudy中MySQL服务异常启动的原因,是否由于以下问题:......(描述你的具体情况)"


Q14: 用普通用户SSH登录Linux服务器后,为什么即使su切换到root也无法向/opt等目录上传文件?

A:

原因分析

SSH会话的文件传输权限取决于初始登录用户的身份,而不是当前切换到的用户。

复制代码
初始SSH登录:普通用户(如 ubuntu)
    ↓
执行 su root 切换到root(当前shell用户变了)
    ↓
尝试 sftp/scp 上传文件到 /opt
    ↓
失败!因为sftp/scp使用的是原始SSH连接的用户身份

本质原因

  • SSH服务(sshd)在建立连接时,会根据登录用户创建对应的sftp子系统
  • 即使当前shell切换到root,sftp传输通道仍然使用初始用户的权限
  • /opt 目录需要root权限才能写入,普通用户无权限

解决方案

bash 复制代码
# 方案1:直接用root远程登录(需要先配置ssh允许root登录)
ssh root@服务器IP

# 方案2:使用sftp配合正确的用户
sftp root@服务器IP

# 方案3:上传到有权限的目录,再通过sudo移动
scp 文件 ubuntu@服务器IP:/home/ubuntu/
ssh ubuntu@服务器IP
sudo mv /home/ubuntu/文件 /opt/

# 方案4:修改目标目录权限(不推荐)
sudo chmod 777 /opt

Q15: 在Ubuntu上安装旧版本PHP(如PHP 5.6)时通常会遇到什么问题?如何解决多PHP版本共存的问题?

A:

常见问题

  1. 404报错:默认软件源已移除旧版本,找不到对应包
  2. 依赖冲突:旧版本与已安装的新版本依赖库冲突
  3. 源配置错误:手动添加的特殊源不可用或地址已变更

解决方案

bash 复制代码
# 步骤1:添加旧版PHP的PPA源
apt install software-properties-common
add-apt-repository ppa:ondrej/php
apt update

# 步骤2:搜索可用版本
apt list | grep php5.6

# 步骤3:安装指定版本
apt install php5.6 php5.6-fpm php5.6-mysql

# 步骤4:使用update-alternatives切换版本
update-alternatives --config php
# 交互式选择默认使用的PHP版本

# 手动切换php-fpm
systemctl stop php8.1-fpm
systemctl start php5.6-fpm

多版本管理

bash 复制代码
# 查看已安装的PHP版本
ls /usr/bin/php*

# 查看当前PHP版本
php -v

# 为不同网站指定不同PHP版本(在nginx配置中)
fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
# 或
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;

注意事项

  • AI给出的源配置方法可能不准确,需要自己验证
  • 不同靶场对PHP版本要求可能截然相反
  • 安装旧版本前确认是否有安全风险

原理篇


Q16: 什么是源码安装?与包管理器安装相比各有何优缺点?请从灵活性、依赖性、管理难度三个维度对比。

A:

源码安装 :下载软件的源代码(通常是 .tar.gz 压缩包),在本地编译后安装的过程。

三维度对比

维度 源码安装 包管理器安装(apt/yum)
灵活性 ⭐⭐⭐⭐⭐ ⭐⭐⭐
可自定义安装路径(--prefix 安装路径固定
可选择开启/关闭特定模块 通常为默认模块集合
可指定编译参数优化性能 按发行版预设参数编译
依赖性 ⭐⭐ ⭐⭐⭐⭐⭐
手动解决每个依赖 自动下载并安装所有依赖
需了解底层依赖关系 依赖关系由包管理器维护
报错需自行排查 报错极少(仓库已验证)
管理难度 ⭐⭐ ⭐⭐⭐⭐⭐
无统一管理命令 apt update/install/remove 统一管理
需手动卸载、清理 一键卸载并清理配置
需要知道安装目录 文件分散在系统标准位置
升级需重新编译 apt upgrade 一键升级

适用场景

复制代码
源码安装 → 需要深度定制、优化性能、特殊路径
包管理器 → 常规使用、快速部署、新手友好

Q17: MariaDB/MySQL中,root用户作为最高权限管理员,为什么有时即使输入错误密码也能登录?如何确保生产环境的数据库安全?

A:

root密码验证绕过的原因

sql 复制代码
# MariaDB默认认证插件
SHOW VARIABLES LIKE 'default_authentication_plugin';
-- 可能输出 unix_socket 或 mysql_native_password

# 当使用 unix_socket 插件时:
-- root用户通过操作系统用户身份验证
-- 只要当前Linux用户是root,就可以直接登录
-- 不需要输入密码(或任意密码都可以)
bash 复制代码
# 演示
sudo mysql -u root   # 不需要 -p 参数就能登录

生产环境数据库安全配置

sql 复制代码
-- 1. 修改root认证方式为密码认证
ALTER USER 'root'@'localhost' 
IDENTIFIED WITH mysql_native_password BY '强密码';

-- 2. 创建专属应用用户(最小权限原则)
CREATE USER 'webapp'@'localhost' IDENTIFIED BY '应用密码';
GRANT SELECT, INSERT, UPDATE, DELETE ON 数据库名.* TO 'webapp'@'localhost';
FLUSH PRIVILEGES;

-- 3. 远程访问限制
-- 只允许本地连接,禁止root远程登录
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1');

-- 4. 删除默认数据库
DROP DATABASE IF EXISTS test;

-- 5. 设置密码策略
SET GLOBAL validate_password_length = 12;
SET GLOBAL validate_password_policy = STRONG;

安全原则总结

  1. root仅限本地管理使用
  2. 每个应用创建独立数据库用户
  3. 权限最小化(只给需要的权限)
  4. 定期更换密码
  5. 开启日志审计

Q18: Docker是如何解决"在我机器上能跑,在你机器上报错"这一经典问题的?请从镜像原理和隔离机制两个角度解释。

A:

问题本质:应用程序的运行依赖操作系统、运行环境、库文件、配置等,不同机器的环境差异(如操作系统版本不同、依赖库缺失、配置不一致)导致程序行为不同。

Docker的解决方案

一、镜像原理(打包一切)

复制代码
传统部署:
 源代码 + 依赖说明文档 → 部署人员手动配置环境 → ❌ 容易出错

Docker部署:
 源代码 + 所有依赖(库/配置文件/环境变量) → 打包成镜像 → 直接运行

Docker镜像是一个分层构建的只读模板

复制代码
┌─────────────────────────┐
│  应用层(你的PHP代码)       │  ← 可写层
├─────────────────────────┤
│  PHP 8.0 + 扩展          │  ← 基础镜像层
├─────────────────────────┤
│  Ubuntu 22.04           │  ← 操作系统层
├─────────────────────────┤
│  Linux Kernel(宿主机)    │  ← 共享宿主内核
└─────────────────────────┘

二、隔离机制(互不干扰)

Docker使用Linux内核的命名空间(Namespace)技术实现隔离:

复制代码
进程隔离:PID Namespace → 容器内看不到宿主机其他进程
网络隔离:Network Namespace → 容器有独立IP和端口空间
文件隔离:Mount Namespace → 容器有独立文件系统
用户隔离:User Namespace → 容器内root ≠ 宿主机root

核心优势

bash 复制代码
# 在任何机器上,只需三步
docker pull nginx:1.24       # 拉取镜像
docker run -d -p 80:80 nginx  # 运行容器
# 环境完全一致,不会报错

# 查看本地镜像
docker images

对比传统VM

特性 Docker 虚拟机
启动速度 秒级 分钟级
资源占用 小(共享内核) 大(完整OS)
镜像大小 MB级 GB级
环境一致性 高(镜像不可变) 中(可修改)

Q19: 在国内使用Docker拉取镜像时常遇到什么问题?请给出所有可行的解决方案并比较优劣。

A:

核心问题 :Docker Hub官方仓库位于国外,国内网络访问受限,导致 docker pull 超时或极慢。

解决方案对比

方案 操作难度 稳定性 速度 适用场景
① 配置镜像加速器 ⭐ 低 ⭐⭐⭐⭐ ⭐⭐⭐⭐ 推荐首选
② 设置VPN代理 ⭐⭐⭐ 中 ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ 长期使用
③ 手动导出导入 ⭐⭐⭐⭐ 高 ⭐⭐⭐⭐⭐ 取决于传输 离线环境
④ 使用替代仓库 ⭐⭐ 中 ⭐⭐⭐ ⭐⭐⭐ 特定镜像

方案一:配置镜像加速器(推荐)

bash 复制代码
# 编辑 /etc/docker/daemon.json
{
  "registry-mirrors": [
    "https://registry.docker-cn.com",
    "https://mirror.ccs.tencentyun.com",
    "https://你的阿里云加速器地址.mirror.aliyuncs.com"
  ]
}

# 重启Docker
systemctl daemon-reload
systemctl restart docker

# 验证
docker info | grep Mirrors

方案二:设置VPN代理

bash 复制代码
# 方法A:Docker客户端代理(仅影响docker pull)
mkdir -p ~/.docker
vim ~/.docker/config.json
{
  "proxies": {
    "default": {
      "httpProxy": "http://代理IP:端口",
      "httpsProxy": "http://代理IP:端口",
      "noProxy": "localhost,127.0.0.1"
    }
  }
}

# 方法B:系统级代理(全局生效)
vim ~/.bashrc
export http_proxy="http://代理IP:端口"
export https_proxy="http://代理IP:端口"
source ~/.bashrc

方案三:离线传输

bash 复制代码
# 在有网络的机器上
docker pull nginx
docker save nginx -o nginx.tar

# 传输到目标机器
scp nginx.tar root@目标IP:/root/

# 在目标机器上
docker load -i nginx.tar

Q20: 请详细描述LNMP架构中,从用户在浏览器输入URL到页面完全加载的完整请求处理流程,要求说明每个环节的作用和涉及的协议/组件。

A:

架构总览

复制代码
用户浏览器 ←→ Nginx(Web服务器)←→ PHP-FPM(PHP解析器)←→ MariaDB/MySQL(数据库)

完整流程(7个环节)

复制代码
第1步:DNS解析
用户输入 http://example.com/index.php
  → 浏览器向DNS服务器查询域名对应的IP地址
  → DNS返回服务器IP(如 192.168.50.158)
  → 协议:DNS(UDP/53)

第2步:建立TCP连接
  → 浏览器与服务器IP:80 建立TCP三次握手
  → 协议:TCP/IP
  → 如果使用HTTPS,还需要TLS握手

第3步:发送HTTP请求
  → 浏览器发送HTTP GET请求
  → 请求头包含:Host、User-Agent、Accept等
  → 协议:HTTP/1.1 或 HTTP/2

第4步:Nginx接收请求
  → Nginx监听80端口,接收HTTP请求
  → 根据server_name匹配虚拟主机
  → 根据请求URI匹配location规则
  → 发现是 .php 文件,进入 PHP 处理流程

第5步:Nginx转发给PHP-FPM
  → Nginx通过 fastcgi_pass 将请求转发到 127.0.0.1:9000
  → 传递参数:SCRIPT_FILENAME、QUERY_STRING等
  → 协议:FastCGI(基于TCP或Unix Socket)

第6步:PHP-FPM执行PHP代码
  → PHP-FPM的worker进程接收FastCGI请求
  → 加载PHP文件并执行
  → 如果代码中有数据库操作:
    a. PHP通过mysqli/pdo_mysql扩展连接MariaDB (127.0.0.1:3306)
    b. 发送SQL查询语句
    c. MariaDB执行查询并返回结果集
    d. PHP处理结果并生成HTML
  → PHP执行完毕,将生成的HTML返回给Nginx

第7步:Nginx返回响应
  → Nginx接收PHP-FPM返回的HTML内容
  → 加上HTTP响应头(Content-Type、Content-Length等)
  → 通过TCP连接返回给浏览器
  → 浏览器解析HTML,加载CSS/JS/图片等资源
  → 页面渲染完成

流程图解

复制代码
┌──────┐    HTTP    ┌────────┐  FastCGI  ┌─────────┐  SQL  ┌─────────┐
│ 用户  │ ←───────→ │ Nginx  │ ←───────→ │ PHP-FPM │ ←───→ │ MariaDB │
│ 浏览器 │           │ :80    │           │ :9000   │       │ :3306   │
└──────┘           └────────┘           └─────────┘       └─────────┘
                        ↓
                 静态文件(HTML/CSS/JS)
                 直接返回,不经PHP

性能优化关键点

  1. Nginx开启FastCGI缓存,减少PHP请求
  2. PHP-FPM调整进程数(pm.max_children)
  3. MariaDB开启查询缓存
  4. 静态文件使用CDN或浏览器缓存
相关推荐
迷途呀18 小时前
CSDN Markdown 编辑器完全指南:从快捷键到高级图表
笔记·其他
栀栀栀栀栀栀19 小时前
刷刷刷 2026/7/16
笔记
β添砖java20 小时前
黑马Linux笔记
linux·运维·笔记
一只小菜鸡..20 小时前
Stanford CS144 学习笔记 (七):跨越虚实的边界——物理层、链路层与无线网络
网络·笔记·学习
大大的大大20 小时前
拼多多电商运营-马扁标题2
笔记·产品运营
玖玥拾1 天前
Unity 3D 笔记(八)ScrollRect 滚动视图、NavMesh 自动寻路系统
笔记·3d·unity
sugar__salt1 天前
Vue3 基础知识点整理 —— 从入门到响应式核心完全指南
vue.js·笔记·vue·vue3
凉、介1 天前
Virtio(三):Virtqueue 建立与 Buffer 提交
笔记·学习·嵌入式·arm·虚拟化·virtio
AOwhisky1 天前
Linux(CentOS)系统管理入门笔记(第九期)——文件权限进阶:SUIDSGIDSticky、ACL 与 chattr
linux·运维·笔记·centos·云计算·文件权限管理