本文作者:莫潇羽 | 无忆研习社站长
原创声明:本文由无忆研习社独家原创发布,全文超过10000字,凝聚了多年运维实战经验。未经授权禁止转载,转载请联系作者获取授权并注明出处。如果你正在寻找高质量的源码资源和技术教程,欢迎访问无忆研习社。
写在前面
大家好,我是无忆研习社的站长莫潇羽。
做网站这些年,我见过太多站长朋友抱怨:"我的服务器配置不差啊,为什么网站还是慢得像蜗牛?"说实话,早些年我也踩过同样的坑——花大价钱买了高配服务器,结果网站访问量稍微一上来就卡成PPT。
后来我花了大量时间研究性能优化,踩了无数的坑,才总算摸索出了一套行之有效的优化方案。今天这篇文章,就是我这些年经验的大汇总,从最基础的概念讲起,手把手教你把网站性能提升数倍甚至数十倍。
说真的,网站性能这件事,不是砸钱堆配置就能解决的。很多时候,一台2核4G的服务器,经过精心优化后,性能反而比未优化的8核16G服务器还要好。这就是优化的魅力所在。
这篇文章会很长,建议你先收藏,然后泡杯茶,跟着我一步步来。相信看完之后,你对网站性能优化会有一个全新的认识。
第一章:为什么你的网站这么慢?
在动手优化之前,我们首先要搞清楚一个问题:网站性能的瓶颈到底在哪里?
1.1 网站访问的完整链路
当用户在浏览器输入你的网址并按下回车,到最终看到页面内容,中间经历了这么几个步骤:
- DNS解析(把域名翻译成IP地址)
- 建立TCP连接(三次握手)
- 发送HTTP请求
- 服务器处理请求
- 服务器返回响应
- 浏览器渲染页面
其中第4步"服务器处理请求",又可以细分为:
- Web服务器(Nginx/Apache)接收请求
- 如果是动态页面,转发给PHP处理
- PHP执行代码,查询数据库
- 组装HTML内容
- 返回给Web服务器
你看,这个链路上任何一个环节出了问题,都会让网站变慢。但根据我的经验,对于大多数使用宝塔面板的站长来说,瓶颈主要集中在以下几个地方:
- Web服务器的选择和配置
- PHP版本和配置
- 数据库性能
- 缺少有效的缓存机制
接下来,我会逐一讲解如何优化这些环节。
1.2 认识性能测试工具ApacheBench
俗话说得好:"没有度量就没有优化"。在开始优化之前,我们需要一个工具来测量当前的性能水平,这样才能知道优化的效果如何。
ApacheBench(简称ab)是Apache HTTP服务器项目提供的压力测试工具,虽然名字里带Apache,但它可以测试任何Web服务器。这个工具最大的优点就是简单易用,几乎是运维人员人手必备的神器。
在CentOS/RHEL系统上安装:
yum install httpd-tools -y
在Ubuntu/Debian系统上安装:
apt-get update
apt-get install apache2-utils -y
安装完成后,输入 ab -V 验证是否安装成功,如果显示版本号就说明没问题。
基本使用方法:
ab -n 1000 -c 100 http://你的网站地址/
这里解释一下参数:
-n 1000:表示总共发送1000个请求-c 100:表示同时有100个并发连接- URL末尾的斜杠不能省略,否则会报错
跑完测试后,你会看到一大堆输出,其中最重要的几个指标是:
|
指标 |
英文名称 |
含义 |
|
每秒请求数 |
Requests per second |
服务器每秒能处理多少个请求,数值越大越好 |
|
平均响应时间 |
Time per request |
每个请求平均需要多长时间完成,数值越小越好 |
|
失败请求数 |
Failed requests |
请求失败的数量,正常情况下应该是0 |
建议你在优化前先跑一次测试,记录下这几个数值,等优化完成后再跑一次对比,这样才能直观地看到效果。
第二章:Nginx vs Apache——选对Web服务器,性能直接提升10倍
如果你现在用的是Apache,那我强烈建议你换成Nginx。这不是我个人偏好,而是实打实的性能差距。
2.1 实测数据对比
为了让大家有一个直观的认识,我专门做了一组对比测试。测试环境:
- 服务器:4核CPU、4GB内存、SSD硬盘
- 系统:CentOS 7
- 测试内容:纯静态页面(排除PHP的影响)
- 测试命令:
ab -n 10000 -c 100 http://服务器IP/
测试结果:
|
Web服务器 |
每秒请求数 |
对比 |
|
Nginx 1.28 |
约12000-13000 |
基准值 |
|
Apache 2.4 |
约900-1000 |
约为Nginx的8% |
你没看错,Nginx处理静态文件的性能大约是Apache的10-12倍。这个差距是相当惊人的。
2.2 为什么差距这么大?
这要从两者的架构设计说起。
Apache的工作模式:
Apache采用的是传统的进程/线程模型。打个比方,Apache就像是一家传统餐厅,每来一个客人就要安排一个服务员全程服务。客人点菜的时候,服务员在旁边站着等;客人吃饭的时候,服务员还在旁边站着等。这种模式在客人少的时候没问题,但当客人多起来后,服务员根本不够用,大家就只能排队干等着。
技术上讲,Apache的每个连接都需要占用一个进程或线程,在高并发场景下,进程/线程频繁切换会带来巨大的性能开销。
Nginx的工作模式:
Nginx采用的是事件驱动的异步非阻塞架构。还是用餐厅来打比方,Nginx更像是一个高效的自助餐厅——服务员只需要在前台负责引导,客人自己取餐、自己吃。一个服务员可以同时照顾很多桌客人。
技术上讲,Nginx使用少量的worker进程,每个worker可以处理数千甚至数万个并发连接,而且不需要为每个连接创建新的进程或线程。
这就是为什么在相同的服务器配置下,Nginx能支撑更高的并发量。
2.3 什么情况下还需要Apache?
虽然性能上Nginx完胜,但Apache也不是一无是处。在以下几种情况下,你可能还是需要Apache:
- 需要使用.htaccess文件:Apache的.htaccess文件允许在目录级别进行配置,对于共享主机环境非常方便。而Nginx不支持这个特性,所有配置都需要写在主配置文件中。
- 使用了特定的Apache模块:有些老旧的应用程序依赖Apache特有的模块,这种情况下迁移到Nginx可能需要额外的工作。
- 团队对Apache更熟悉:如果你们团队一直在用Apache,对它的配置非常熟悉,而迁移到Nginx需要重新学习,那么在权衡人力成本后,也许继续用Apache是更务实的选择。
不过,如果你是用宝塔面板管理服务器,那切换到Nginx简直太简单了——宝塔会帮你自动生成配置文件,伪静态规则也能一键转换。所以对于大多数站长来说,我的建议是:能用Nginx就用Nginx。
2.4 在宝塔面板中切换到Nginx
如果你的宝塔面板当前安装的是Apache,想切换到Nginx,步骤如下:
- 登录宝塔面板
- 进入"软件商店"
- 找到Nginx,点击"安装"
- 选择最新的稳定版本(目前推荐1.28.x)
- 安装完成后,进入"网站"管理
- 修改每个网站的配置,将Web服务器改为Nginx
- 确认无误后,卸载Apache
需要注意的是,切换过程中要检查伪静态规则是否正常工作。好在宝塔面板内置了常见程序(WordPress、Discuz、织梦等)的伪静态规则模板,直接选用即可。
第三章:Nginx版本选择——为什么我推荐用最新版
有些站长可能会问:"Nginx版本那么多,我该选哪个?是不是越新越好?"
答案是:对的,通常情况下越新越好。
3.1 版本对比测试
我测试过几个不同版本的Nginx,结果如下:
|
Nginx版本 |
每秒请求数 |
备注 |
|
Nginx 1.12 |
约11000-12000 |
较老版本 |
|
Nginx 1.16 |
约8000-10000 |
中间版本,性能反而下降 |
|
Nginx 1.19 |
约12000-13000 |
当时的新版 |
|
Nginx 1.28 |
约12000-14000 |
当前稳定版(截至2025年) |
|
Nginx 1.29 |
约12000-14000 |
当前主线版(截至2025年) |
从测试结果可以看出几个规律:
- 最新版本通常性能最好,因为包含了最新的优化
- 某些中间版本可能因为新增功能而性能略有下降
- 版本差异带来的性能差距大约在10%-30%左右
3.2 Nginx的版本策略
根据Nginx官方的版本策略(可以在 nginx.org 查看),Nginx分为两个分支:
- mainline(主线版本):版本号第二位是奇数(如1.27、1.29),包含最新功能和bug修复,更新频繁
- stable(稳定版本):版本号第二位是偶数(如1.26、1.28),在mainline的基础上稳定下来,只接收严重bug的修复
截至2025年1月,Nginx的最新稳定版是1.28.x,主线版是1.29.x。
我的选择建议:
- 生产环境优先选择最新的稳定版(当前为1.28.x)
- 如果你喜欢尝鲜或者需要最新特性,可以选择主线版
- 除非有特殊的兼容性需求,否则不建议使用老版本
3.3 关于第三方Nginx版本
除了官方Nginx,还有一些第三方修改版,比如阿里巴巴开源的Tengine、CloudFlare的OpenResty等。这些修改版通常会加入一些实用功能,但也有一个问题:它们往往基于较老的Nginx版本开发,更新速度跟不上官方。
我曾经测试过Tengine:
|
版本 |
每秒请求数 |
备注 |
|
Nginx官方1.28 |
约12000-14000 |
最佳性能 |
|
Tengine 2.x |
约8000-10000 |
基于较老版本 |
所以,除非你确实需要Tengine的某个特定功能(比如动态模块加载),否则我建议直接使用官方版本。
3.4 升级Nginx版本会影响网站吗?
很多新手站长担心:我的网站是用Nginx 1.18配的,升级到1.28会不会出问题?
答案是:99%的情况下不会有问题。
Nginx的配置文件语法在不同版本之间高度兼容。你的伪静态规则、反向代理配置、SSL证书配置等,通常都可以原封不动地用在新版本上。
而且,Nginx只是一个Web服务器,它的作用是接收HTTP请求并返回响应。你的网站代码是由PHP解释器执行的,跟Nginx版本没有直接关系。
在宝塔面板中升级Nginx版本非常简单:
- 进入"软件商店"
- 找到Nginx,点击"设置"
- 选择"版本切换"
- 选择你要安装的新版本
- 等待安装完成即可
宝塔会自动帮你处理配置文件的迁移,基本上是无缝切换。
第四章:PHP版本——性能差距最大的地方
如果说Nginx版本的选择能带来10%-30%的性能提升,那PHP版本的选择则能带来数倍甚至十倍以上的性能差距。这是整个优化过程中最值得关注的地方。
4.1 PHP的历史性飞跃:PHP 5到PHP 7
2015年,PHP 7正式发布,这是PHP历史上的一次革命性升级。PHP 7带来的性能提升主要来自于:
- 全新的Zend引擎:PHP 7使用了重新设计的Zend引擎3.0,执行效率大幅提升
- 优化的内存管理:新的内存分配机制大幅减少内存占用
- 改进的数据结构:更高效的哈希表实现
- AST编译:引入抽象语法树,编译过程更加优化
4.2 实测数据说话
我用一个Discuz论坛做测试,测试命令:ab -n 1000 -c 100 http://论坛地址/
|
PHP版本 |
每秒请求数 |
相比PHP 5.6的提升 |
|
PHP 5.6 |
约100-200 |
基准值 |
|
PHP 7.0 |
约600-700 |
3-4倍 |
|
PHP 7.2 |
约700-800 |
4-5倍 |
|
PHP 7.4 |
约900-1000 |
5-6倍 |
|
PHP 8.0 |
约1000-1200 |
6-7倍 |
|
PHP 8.4 |
约1100-1300 |
7-8倍 |
从PHP 5.6升级到PHP 7.x,性能提升达5-6倍,这是质的飞跃!
而PHP 7.x的各个小版本之间,性能差距相对较小,基本可以忽略。PHP 8.x相比PHP 7.x又有一定提升,主要得益于JIT编译器的引入。
4.3 PHP版本选择建议
根据我的经验,给出以下建议:
1. 优先使用你的程序支持的最高版本
- 如果你的程序(WordPress、Discuz、织梦等)支持PHP 8.x,就用8.x
- 如果最高只支持PHP 7.4,就用7.4
- 不要勉强使用不兼容的版本,否则可能出现各种奇怪的问题
2. 至少使用PHP 7.1以上版本
- PHP 5.6已于2018年12月停止安全更新
- PHP 7.0已于2019年1月停止安全更新
- 继续使用这些版本存在严重的安全风险
截至2025年1月,PHP官方仍在维护的版本包括:
- PHP 8.2(安全支持至2026年12月)
- PHP 8.3(活跃支持至2025年12月)
- PHP 8.4(活跃支持至2026年12月)
- PHP 8.5(2025年11月发布,活跃支持至2027年)
详细的版本支持时间表可以在 PHP官网 查看。
3. 关于兼容性问题
如果你担心升级PHP版本后网站出问题,可以这样做:
- 先在测试环境验证,确认没问题后再应用到生产环境
- 查看程序官方的兼容性说明
- 升级前备份网站和数据库
大多数现代PHP程序都已经支持PHP 8.x了。如果你用的是比较老的程序,可能需要做一些代码调整才能兼容新版本。
4.4 在宝塔面板中切换PHP版本
宝塔面板支持同时安装多个PHP版本,并且可以为不同的网站指定不同的PHP版本,非常灵活。
安装新版本PHP:
- 登录宝塔面板
- 进入"软件商店"
- 找到PHP,点击"安装"
- 选择你要安装的版本(推荐8.3或8.4)
- 等待安装完成
为网站切换PHP版本:
- 进入"网站"管理
- 点击网站名称进入设置
- 找到"PHP版本"选项
- 选择新的PHP版本
- 保存即可
切换后记得测试一下网站的各项功能是否正常。
4.5 为什么有些人用PHP 5.6也感觉不慢?
这个问题我被问过很多次。解释起来很简单:
- 访问量低:当访问量很小时,性能瓶颈不明显,PHP版本的差距也体现不出来
- 有其他缓存:可能启用了页面缓存或其他缓存机制,绕过了PHP执行
- 数据库是瓶颈:如果数据库才是真正的瓶颈,PHP再快也没用
但是,一旦访问量上升,PHP版本的差距会被急剧放大。等到那时候再升级,可能就要面对更大的迁移成本了。所以我的建议是:未雨绸缪,趁早升级。
第五章:OPcache——PHP优化的必备神器
如果让我只推荐一项PHP优化措施,那一定是启用OPcache。这是官方提供的、几乎零成本的性能提升方案。
5.1 OPcache是什么?
OPcache(Opcode Cache)是PHP官方提供的字节码缓存扩展。要理解它的作用,首先需要了解PHP的执行流程。
没有OPcache时,PHP执行流程是这样的:
PHP源代码 → 词法分析 → 语法分析 → 编译成字节码(Opcode) → 执行
↑_________________________________________________|
每次请求都要重复这个过程
也就是说,每次有人访问你的网站,PHP都要把代码重新编译一遍,哪怕代码根本没有改变。这是非常浪费的。
启用OPcache后,流程变成了:
第一次请求:PHP源代码 → 编译 → 字节码 → 存入共享内存
后续请求:直接从共享内存读取字节码 → 执行
OPcache把编译后的字节码缓存在内存中,后续请求直接使用缓存的字节码,省去了重复编译的开销。
5.2 OPcache能带来多大的性能提升?
还是用Discuz论坛做测试:
|
配置状态 |
每秒请求数 |
提升幅度 |
|
未启用OPcache |
约100-200 |
基准值 |
|
启用OPcache |
约700-1000 |
5-7倍 |
**启用OPcache后,性能可以提升5-7倍!**而且这是在不改动任何代码的情况下获得的提升,可以说是"免费的午餐"。
5.3 如何启用和配置OPcache
从PHP 5.5版本开始,OPcache就已经内置在PHP中了。在宝塔面板中启用OPcache非常简单:
- 进入"软件商店"
- 找到你正在使用的PHP版本,点击"设置"
- 进入"安装扩展"选项卡
- 找到"opcache",点击"安装"
安装完成后,还需要对OPcache进行一些配置优化。在宝塔面板中:
- 进入PHP设置
- 点击"配置文件"
- 找到
[opcache]部分,修改或添加以下配置
[opcache]
; 启用OPcache
opcache.enable=1
; CLI模式下是否启用(一般不需要)
opcache.enable_cli=0
; 分配给OPcache的内存大小(MB)
opcache.memory_consumption=128
; 字符串驻留缓冲区大小(MB)
opcache.interned_strings_buffer=16
; 可缓存的最大文件数
opcache.max_accelerated_files=10000
; 多久检查一次文件更新(秒)
opcache.revalidate_freq=1
; 是否验证时间戳(生产环境建议设为1)
opcache.validate_timestamps=1
; 快速关闭(PHP 7.2以下版本有效)
opcache.fast_shutdown=1
修改后保存,然后重启PHP服务生效。
5.4 关键配置项详解
opcache.memory_consumption
这个参数决定了分配给OPcache的内存大小,单位是MB。
- 小型网站(几个简单的PHP页面):64MB足够
- 中型网站(使用了框架,如Laravel、ThinkPHP):128MB
- 大型网站(大量PHP文件):256MB或更高
你可以通过以下命令统计项目中的PHP文件数量,据此估算需要的内存:
find /www/wwwroot/你的网站目录 -type f -name "*.php" | wc -l
opcache.max_accelerated_files
这个参数决定了最多可以缓存多少个PHP文件。默认值可能较小,建议设置为比实际文件数稍大的值。
可选的值是PHP预设的一些素数:223、463、983、1979、3907、7963、16229、32531、65407、130987。
opcache.revalidate_freq(重要!)
这个参数决定了OPcache多久检查一次PHP文件是否有更新。
|
值 |
说明 |
适用场景 |
|
0 |
每次请求都检查 |
开发环境 |
|
1-3 |
1-3秒检查一次 |
生产环境(推荐) |
|
60 |
60秒检查一次 |
默认值,不推荐 |
为什么不建议用默认的60秒?
如果你修改了PHP代码,可能需要等60秒才能看到效果。这在调试问题时会非常困扰——你会怀疑"是不是服务器出问题了"、"我的修改到底有没有生效"。建议将这个值设为1-3秒,既能保证及时更新,又不会对性能产生明显影响。
5.5 OPcache常见问题处理
问题1:修改PHP文件后不生效
这是最常见的问题,原因是OPcache缓存了旧的字节码。
解决方法:
- 等待
revalidate_freq设定的时间 - 在宝塔面板中重启PHP服务
- 或者使用代码清除缓存:
opcache_reset();
问题2:内存不足警告
如果在PHP错误日志中看到OPcache内存不足的警告,说明memory_consumption设置太小了。
解决方法:增加opcache.memory_consumption的值。
问题3:缓存的文件数达到上限
如果PHP文件很多,可能会达到max_accelerated_files的上限。
解决方法:增加这个值,注意要使用PHP预设的素数值。
第六章:缓存策略——让动态页面变"静态"
前面讲的OPcache是代码层面的缓存,现在我们来讲讲数据层面的缓存。对于动态网站来说,合理的缓存策略可以极大地提升性能。
6.1 Memcached vs Redis:如何选择?
说到PHP的缓存,最常用的就是Memcached和Redis两种。它们的对比如下:
|
对比项 |
Memcached |
Redis |
|
数据类型 |
仅支持字符串 |
支持多种数据类型(字符串、列表、哈希等) |
|
数据持久化 |
不支持 |
支持 |
|
内存效率 |
更高 |
略低 |
|
安全性 |
无内置认证 |
支持密码认证 |
|
功能复杂度 |
简单 |
功能更强大 |
我的选择建议:
- 单服务器、简单缓存需求:优先选择Memcached
- 配置简单
- 内存效率高
- 性能与Redis相当
- 多服务器、分布式环境:考虑Redis
- 支持主从复制
- 数据可持久化
- 功能更丰富
- 安全考虑:
- Redis近年来爆出过不少安全漏洞
- 如果Redis暴露在公网上,很容易被攻击
- 很多服务器被入侵挖矿都是因为Redis配置不当
- 如果不是必须用Redis,Memcached会更安全一些
6.2 在宝塔面板中安装和配置Memcached
安装Memcached服务:
- 进入宝塔"软件商店"
- 搜索"memcached"
- 安装Memcached服务(不是PHP扩展)
- 安装完成后启动服务
安装PHP的Memcached扩展:
- 进入你正在使用的PHP版本的设置
- 点击"安装扩展"
- 找到"memcached"(注意不是memcache,带d的是新版)
- 点击安装
在程序中启用Memcached缓存:
以Discuz为例,编辑配置文件config/config_global.php:
$_config['memory']['prefix'] = 'discuz_';
$_config['memory']['memcache']['server'] = '127.0.0.1';
$_config['memory']['memcache']['port'] = 11211;
然后在Discuz后台 → 全局 → 性能优化 → 内存优化中启用Memcached缓存。
其他程序(如WordPress)也有类似的缓存插件,安装配置方法大同小异。
6.3 页面缓存——终极加速方案
前面讲的缓存(OPcache、Memcached)都是在服务器内部做优化,而页面缓存则是把整个HTML页面缓存起来,实现"一次生成,多次复用"。
页面缓存的工作原理:
第一次访问(匿名用户):
请求 → Nginx → PHP → 数据库 → 生成HTML → 缓存到内存 → 返回
后续访问(匿名用户):
请求 → Nginx → 直接从内存读取缓存 → 返回(完全绕过PHP和数据库)
关键点:页面缓存通常只适用于匿名用户(未登录用户)!
因为登录用户的页面包含个性化内容(用户名、消息通知等),这些内容不能被缓存,否则你看到的可能是别人的页面。
6.4 页面缓存的性能提升
还是用Discuz做测试:
|
状态 |
响应时间 |
每秒请求数 |
|
无页面缓存 |
约7-35ms |
约700-1000 |
|
启用页面缓存 |
约2-4ms |
约8000-9000 |
启用页面缓存后,性能可以提升10倍左右!
而且这个提升是实实在在的——因为大部分请求直接返回缓存的HTML,根本不需要执行PHP代码,也不需要查询数据库。
6.5 哪些网站适合用页面缓存?
页面缓存的效果取决于你网站的匿名用户占比:
|
网站类型 |
匿名用户占比 |
缓存效果 |
|
博客 |
95%+ |
极佳 |
|
新闻/资讯站 |
90%+ |
极佳 |
|
电影/小说站 |
95%+ |
极佳 |
|
论坛 |
60-80% |
较好 |
|
社交网站 |
20-40% |
一般 |
|
后台管理系统 |
0% |
无效 |
不适合使用页面缓存的场景:
- 微信小程序/公众号后端(所有请求都需要登录验证)
- 纯API服务(返回个性化数据)
- 实时性要求高的应用(如股票行情)
- 需要频繁更新的页面
6.6 如何在宝塔面板中启用页面缓存
宝塔面板的"Nginx防火墙"插件(专业版功能)包含了页面缓存功能。如果你用的是免费版,也可以手动配置Nginx的fastcgi_cache来实现。
对于WordPress用户,还有更简单的方法——使用缓存插件,如:
- WP Super Cache
- W3 Total Cache
- LiteSpeed Cache(如果用的是LiteSpeed服务器)
这些插件可以