ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

WAMP环境下Apache并发性能优化实战:从定位到配置调优

WAMP环境下Apache并发性能优化实战:从定位到配置调优 1. 先搞清楚卡在哪一环——并发访问慢的定位思路WAMP 下的 Apache 人一多就卡这个问题我前后帮人排查过不少回现象基本都长一个样本地单机访问飞快一放到局域网或者正式服务器上几十个人同时点一下页面马上就变成“点击之后转圈三秒、五秒”严重的时候直接超时连不上。很多人第一反应是“服务器配置太低”“带宽不够”但实际查下来绝大多数情况都是 Apache 的并发模型和 WAMP 默认参数压根没有为多人访问做过优化属于典型的“能用但不扛压”。先说一个我总结多年的结论WAMP 这类集成环境默认配置是为单机开发场景设计的追求的是“装上就能跑、配置简单”而不是“高并发下稳定”。所以你在本地开几个标签页觉得飞快一上真实访问压力就露馅这是必然的。要解决必须先定位瓶颈在哪再针对性调参数而不是盲目在网上抄一堆配置贴进去那样反而容易把环境搞挂。这篇文章我会按照实际排查顺序从定位、原理、配置、验证四个维度把这个事彻底讲透。1.1 并发变慢的四种表现对应四个排查方向“卡”不是一种卡法。同样是“人多了变慢”背后可能有完全不同的瓶颈。我习惯把并发访问变慢分成四种典型表现每一种指向不同的排查方向表现特征最可能的瓶颈优先排查项CPU 持续接近 100%页面很慢但能打开Apache 处理能力不够或 PHP 执行时间长线程数、PHP 代码效率、MySQL 慢查询内存占用飙高机器开始读硬盘Apache 线程/进程堆积过多每个连接占内存ThreadsPerChild、KeepAlive 参数图片、JS、CSS 加载特别慢点一下半天不出图带宽/静态资源反复传输压缩、缓存、静态资源分流数据库报“连接数过多”或 SQL 执行特别慢MySQL 连接数满、慢查询、缺索引max_connections、慢查询日志、索引优化这里要特别说一句表面上现象都是“Apache 很卡”但真正拖后腿的往往是 PHP 脚本或 SQL 查询。Apache 只是服务员人一多它就跑不过来可如果每个客人都点了一堆需要现炒的菜慢查询、无缓存那再多的服务员也白搭。所以定位阶段一定要把“Apache 并发能力不足”和“业务代码执行太慢”这两件事分开看否则容易调了半天 Apache反而没解决实际问题。1.2 动手前先“看现场”两条命令加一个状态页不排查就直接改配置等于闭着眼睛开车。我每次接到这类问题第一件事不是打开配置文件而是先收集现场信息。WAMP 环境里三样东西能帮你快速定位Apache 自带的命令行工具、状态页面、错误日志。首先用命令行确认当前 Apache 的编译信息和加载的模块。在 WAMP 的 Apache bin 目录下打开命令行依次执行httpd -V httpd -M httpd -thttpd -V会显示 Server MPM 是什么Windows 下一般显示为 WinNT这决定了你后面改的是线程参数而不是进程参数httpd -M列出所有已加载模块方便你检查哪些模块是多余的httpd -t用来检查配置语法这个每次改完配置都必须跑一遍可以有效避免改错导致 Apache 起不来。然后开启 Apache 的 server-status 页面实时观察并发连接状态。在 httpd.conf 中找到LoadModule status_module modules/mod_status.so确认没被注释再找到或者新增一段配置Location /server-status SetHandler server-status Require local /LocationRequire local表示只能本机访问如果你需要从局域网另一台机器看可以改成Require ip 192.168.1.0/24但注意生产环境不要直接Require all granted这个页面会暴露当前请求明细公网开放很危险。改完重启 Apache浏览器访问http://localhost/server-status就能看到当前一共有多少工作线程、多少空闲线程、正在处理哪些请求。还有一条非常重要的指令那就是看 Apache 的 error.log。并发打满时日志里通常会留下明确的报错字样比如server reached MaxRequestWorkers一旦看到这句基本就可以断定是线程池满了新请求进不来表现就是访问极其缓慢甚至拒绝连接。这个日志文件在 WAMP 的 Apache logs 目录下Windows 机器上路径一般是C:\wamp64\bin\apache\apache2.4.x\logs\error.log。最后建议用 Apache 自带的 ab 工具做一次简单的压力测试确认“卡”的量化指标。比如对首页做 1000 个请求、50 个并发ab -n 1000 -c 50 http://localhost/输出结果里重点看三个地方Requests per second每秒处理请求数、Failed requests失败请求数、Time per request平均每个请求耗时。改配置前后各跑一次对比数据才能判断你的调整是否真的有效。2. 默认配置为什么扛不住——并发模型里的三个坑定位完现场下一步要理解 WAMP 的 Apache 为什么天生不擅长高并发。很多人以为“卡就是配置低”加内存换 CPU 就完事了但不对。Apache 在 Windows 下的并发模型、默认的连接保持策略、以及 WAMP 默认加载的模块这三个因素叠加在一起才是真正的根因。2.1 Windows 下 Apache 是“一连接一线程”线程池是有上限的Apache 在 Windows 上默认使用 mpm_winnt 多线程模型核心逻辑是每个 TCP 连接到达时Apache 会从线程池里分配一个线程去处理这个连接处理期间这个线程就被独占直到连接关闭才释放。Windows 下 Apache 不会一个进程开多个子进程这是 Linux 上 prefork 模型的做法而是单进程 多线程所有线程共享一个进程的内存空间。WAMP 默认配置里ThreadsPerChild一般是 150意思是这个 Apache 进程最多同时开 150 个线程同时只能服务 150 个连接。一旦并发连接数超过这个值多余的请求就会在队列里排队等待表现就是用户点击后页面转圈、迟迟不加载。这里有个生活化的类比你开了一家理发店店里一共 150 把理发椅每来一个客人就占一把椅子理完发才空出来。如果同时来了 200 个人后 50 个只能坐在门口等。问题在于理发椅坐满之后哪怕只是等待配钥匙的客人比如一个长连接、一个慢请求也占着椅子不走后面真正想理发的客人就一直进不来。更要命的是Windows 上每个 Apache 线程会占用一定内存实际比例大约每个线程 1~3MB 的虚拟内存再加上 PHP 脚本执行时的内存开销如果你把线程数盲目调高到 300 甚至 500内存直接吃满机器开始疯狂读硬盘那比排队更严重整个系统都可能卡死。2.2 KeepAlive 是隐藏最深的“椅子占位者”很多人调了半天线程数发现还是卡其实问题出在 KeepAlive 上。KeepAlive 原本是个好机制它允许同一个 TCP 连接上发送多个 HTTP 请求减少重复握手开销。Apache 默认是开启的KeepAliveTimeout默认 5 秒意思是请求处理完之后这个连接还会再保持 5 秒等待同一个客户端继续发请求。本地单机调试时KeepAlive 作用不明显因为只有一个用户在访问。但人一多情况就完全不同了假设 100 个用户同时访问每个人打开你的页面后浏览器发起 HTML、CSS、JS、图片等多个请求这些请求都走同一个 KeepAlive 连接可请求间隙 Apache 要维持这个连接 5 秒不释放。在并发高峰期150 个线程里有很大一部分其实处于“连接保持但啥事没干”的状态真正能处理新请求的线程所剩无几。我见过最夸张的一个案例对方 Windows 服务器上 150 个线程全被 KeepAlive 空闲连接占满error.log 里疯狂刷server reached MaxRequestWorkers但 CPU 和内存都非常低因为线程都闲着。这种“看似资源充足实际无线程可用”的假象非常迷惑人不熟的人很容易往内存、CPU 方向排查浪费时间。既然 KeepAlive 有占用线程的缺点那是不是直接关掉最好也不一定。关掉 KeepAlive 会让每个 HTTP 请求都重新走一次 TCP 三次握手短连接开销明显尤其页面里有大量静态资源时反而更慢。正确做法是开启 KeepAlive但把 KeepAliveTimeout 压短、把 MaxKeepAliveRequests 适当调大让连接只在“确实还需要复用”时保持而不是无脑占位 5 秒。具体调法在下一章详细说。2.3 模块冗余和 PHP 执行方式把问题进一步放大第三个坑是 WAMP 默认加载了一堆你用不到的模块。Apache 是多模块架构每次请求进来各模块都会参与处理哪怕只是做个检查。默认配置里像mod_autoindex目录列表、mod_info、mod_status如果生产环境不打算用可以先关掉、mod_negotiation内容协商、mod_userdir这类模块在很多业务场景里根本用不上但每个请求都会被它们“过一遍”白白消耗 CPU。更关键的是 PHP 的执行方式。WAMP 默认通过 Apache 的 mod_php 方式加载 PHP也就是 PHP 解释器直接嵌在 Apache 进程里。这种方式单机开发很方便不需要单独启动 PHP 进程但副作用是如果一个 PHP 脚本执行得慢比如死循环、复杂的正则、没加缓存的接口它会一直占着 Apache 的一个工作线程别的请求就得等。再加上 Windows 上很多 WAMP 环境默认没有正确开启 OpcachePHP 字节码缓存每个 PHP 文件每次请求都要重新解析编译一遍性能开销非常大。这一环套一环Apache 的线程池本身就不宽裕PHP 执行又慢连接还被 KeepAlive 占着三重叠加人一多当然卡。3. Apache 配置调整实操——把并发指标调到健康值理解了原理接下来就是动手改配置。这一章我给出可以直接抄作业的参数组合同时会解释每个参数为什么要这么设避免你只是机械地复制粘贴。所有修改都基于一个原则让 Apache 在有足够线程处理请求的同时不让内存和连接占用失控。3.1 动手前先备份、弄清配置文件结构改配置之前务必先备份。WAMP 的 Apache 配置文件一般在C:\wamp64\bin\apache\apache2.4.x\conf\httpd.conf还有一个重要的附加文件是conf\extra\httpd-mpm.conf多线程相关参数通常放在那里但默认可能在 httpd.conf 里被注释掉了 Include。我建议先执行一次httpd -M确认当前加载的 MPM 模块是mpm_winnt_module然后在 httpd.conf 里搜索mpm_winnt_module找到类似这样的段落IfModule mpm_winnt_module ThreadsPerChild 150 MaxConnectionsPerChild 0 /IfModule这是线程参数的“主战场”。如果 httpd.conf 里没有这一段就去httpd-mpm.conf里找并检查 httpd.conf 尾部是否包含Include conf/extra/httpd-mpm.conf没有就取消注释。改之前把原文件复制一份命名为httpd.conf.bak改完用httpd -t验证语法确认无误再重启。3.2 核心参数线程数、超时时间、KeepAlive 的正确调法以一台 8GB 内存的 Windows 机器为例我给出一个经过验证、比较稳的配置组合IfModule mpm_winnt_module ThreadsPerChild 128 MaxConnectionsPerChild 10000 /IfModule KeepAlive On MaxKeepAliveRequests 200 KeepAliveTimeout 2 Timeout 30一个个解释。ThreadsPerChild 128意思是 Apache 最多同时开 128 个工作线程。为什么不是默认的 150也不是更大的 256因为 Windows 下线程数不是越大越好每个线程都会占内存8GB 机器如果跑 PHP 业务128 是兼顾并发能力和稳定性的平衡点。如果你机器只有 4GB 内存可以降到 64如果内存 16GB 以上日常业务都是简单接口可以调到 150 甚至 200。MaxConnectionsPerChild 10000是让每个线程在处理完 10000 个连接后自动退出重建。Windows 上长期运行的内存碎片问题很常见设置这个值可以让 Apache 定期“换血”避免内存泄漏累积到把系统拖垮。如果你发现 Apache 的内存占用随运行时间一直往上涨这个参数就是最大的救星。KeepAliveTimeout 2是我反复强调的重点。默认 5 秒在并发高的时候太长改成 2 秒意味着一个请求处理完后连接最多再为空闲等待 2 秒超过就释放线程。配合MaxKeepAliveRequests 200对同一客户端的连续请求依然有效但不会让线程长时间占着不动。Timeout 30是单个请求的最大处理时间超过 30 秒直接断开防止某个慢请求把线程拖死。不同内存档位的参考配置我也整理了一张表物理内存ThreadsPerChild 建议适合场景4GB64静态页为主或简单 PHP 页面8GB128动态 PHP 业务访问量中小型16GB150~200并发较多业务稍复杂注意这个表是经验值不是绝对标准。调整完一定要观察任务管理器里 httpd.exe 的实际内存如果进程内存持续飙升至接近物理内存上限就说明线程开多了需要降下来。线程数不是追求大而是追求“够用且不爆内存”。3.3 顺手做的几个小优化模块裁剪、日志、压缩与缓存核心参数调完还有几个成本极低但收益明显的优化项我每次都会一起做。第一是裁模块。打开 httpd.conf搜索LoadModule把用不到的行注释掉。以常见业务为例mod_autoindex如果不提供目录下载服务、mod_info信息泄露风险、mod_negotiation、mod_userdir这几项通常可以关。但注意mod_deflate、mod_expires、mod_headers、mod_rewrite这些常用功能千万别关关了反而影响业务。第二是关闭反向 DNS 解析。搜索HostnameLookups改成HostnameLookups Off默认就是 Off但如果之前被改成了 On每个请求都会做一次域名反查那是非常拖慢速度的操作务必确认。第三是开启 gzip 压缩。编辑 httpd.conf 确认LoadModule deflate_module modules/mod_deflate.so已加载然后加一段AddOutputFilterByType DEFLATE text/html text/plain text/css application/javascript application/json image/svgxmlHTML、CSS、JS 这类文本资源压缩后能省掉大量传输流量尤其对带宽紧张的网络环境效果显著。图片不要压缩jpg/png 本身已经压缩过强行压缩只会增加 CPU 负担。第四是开启静态资源缓存。加载mod_expires后加一段ExpiresActive On ExpiresByType image/jpeg access plus 7 days ExpiresByType image/png access plus 7 days ExpiresByType text/css access plus 7 days ExpiresByType application/javascript access plus 7 days这样浏览器访问过一次后JS/CSS/图片就会在本地缓存下次访问不再向服务器发起请求能明显减轻 Apache 的压力。如果你对缓存更新有顾虑可以在文件名上加版本号来强制刷新。最后提一下访问日志。Windows 环境下的磁盘 I/O 本身不如 Linux如果每来一个请求都往 access.log 里写一行高并发时磁盘写入会成为瓶颈。如果业务不需要详细访问日志做分析可以注释掉CustomLog那行或者保留但改写到非系统盘。这个优化在并发提升后的效果非常明显我实测过把日志关掉后同样压力下响应时间能缩短将近四分之一。4. 配套优化PHP、MySQL 与静态资源一个都不能少Apache 配置调完之后如果还卡那问题大概率不在 Apache而在它背后跑的 PHP 和 MySQL。这一章讲的是和 Apache 优化配套的“组合拳”也是我反复强调的“别让 Apache 单独背锅”的关键环节。4.1 PHP 层开启 Opcache 是最快最省的提速方式WAMP 的 PHP 配置文件是C:\wamp64\bin\php\php版本\php.ini。很多 WAMP 环境虽然带了 Opcache 扩展但默认并没有正确启用导致每次请求都要重新编译 PHP 脚本CPU 白白烧掉一大半。检查并开启的方式很简单用文本编辑器打开 php.ini搜索opcache确保以下几个配置生效[opcache] zend_extensionphp_opcache.dll opcache.enable1 opcache.memory_consumption128 opcache.max_accelerated_files4000 opcache.revalidate_freq60opcache.memory_consumption128表示给字节码缓存分配 128MB 内存一般项目够用opcache.revalidate_freq60是每 60 秒检查一次 PHP 文件是否变动开发环境可以改成 0但生产环境建议设成 60 以上能减少文件检查开销。开启 Opcache 的效果我可以直接告诉你同样的 PHP 页面开启前后压测数据经常是翻倍的差距。原理很简单PHP 是解释型语言每次请求都要把源码读出来、解析、编译成字节码再执行Opcache 就是把编译好的字节码缓存起来下次直接执行省掉了前面一大段重复劳动。类比就是你每天上班不用重新学习怎么做表格直接打开模板就能干活。除了 OpcachePHP 代码层面的习惯也很重要。最常见的两个坑一是在循环里反复查数据库比如查一个列表每条记录又执行一次 SELECT几百条数据就是几百次数据库请求直接把 MySQL 连接数打满二是没加任何缓存地执行复杂计算或正则匹配一个请求耗掉好几秒。这类问题不是调 Apache 能解决的必须回到代码层面优化比如把循环里的查询改成一次 JOIN 查出来。4.2 MySQL 层连接数、慢查询、索引三板斧人一多就卡另一个高频瓶颈是 MySQL。WAMP 自带的 MySQL 配置文件在C:\wamp64\bin\mysql\mysql版本\my.ini但默认的max_connections并不高一旦 Apache 的并发线程都来查数据库连接数瞬间就被占满。先执行一条 SQL 看看当前数据库的压力情况SHOW STATUS LIKE Threads_connected; SHOW VARIABLES LIKE max_connections;如果Threads_connected经常接近max_connections说明连接数不够可以在 my.ini 的[mysqld]段调大max_connections256注意不要盲目调得太大每个 MySQL 连接都会占用内存256 在大多数中小型项目里已经足够。调完后重启 MySQL 服务。然后是慢查询日志。很多人以为数据库卡是机器慢其实八成是 SQL 没索引。在 my.ini 里开启慢查询日志slow_query_logON slow_query_log_fileC:/wamp64/logs/mysql-slow.log long_query_time2执行超过 2 秒的 SQL 都会被记录下来。过一段时间打开这个日志你会发现活跃的慢查询往往集中在几个表原因基本都是一个WHERE 条件里的字段没建索引。解决方式很简单EXPLAIN SELECT * FROM orders WHERE order_no xxx; ALTER TABLE orders ADD INDEX idx_order_no (order_no);EXPLAIN会告诉你这个查询走了全表扫描还是索引查找如果 type 列是ALL就说明全表扫了数据量大时自然慢。加个索引通常能把查询时间从几百毫秒降到几毫秒效果立竿见影。这个三板斧——连接数、慢查询日志、索引优化——能解决绝大多数 MySQL 层面的并发卡顿。4.3 静态资源与整体架构的“疏导”思路最后是静态资源。Apache 本身处理静态文件并不差但架不住页面里图片一堆、每次刷新都重新下载。除了前面提到的 Expires 缓存还有几招值得做。如果项目允许把图片、CSS、JS 放到独立域名或者子目录下通过 Nginx、CDN 或对象存储来分发本机 Apache 只处理动态请求。这样 Apache 的线程池几乎全部留给 PHP 接口并发能力直接翻倍。即便是局域网环境也可以用一台专门的静态资源服务器来分流。如果暂时不想引入新的服务器至少要做到图片使用现代格式WebP、体积压缩页面减少不必要的请求数量。一个页面 60 个请求和 20 个请求对并发的影响差异巨大相当于 60 个人同时挤门 和 20 个人同时挤门的区别。这一章的核心思路是Apache 优化只是“把接待能力提升”但要真正快起来得让每个请求执行时间变短——PHP 缓存缩短计算时间MySQL 索引缩短查询时间静态缓存缩短传输时间。三管齐下人多了才不卡。5. 改完怎么验证——压测、日志与常见问题实录改配置不是终点验证才算是真正做完。很多人改完觉得“好像快了”但没有数据支撑也不知道是不是某个参数起的作用。这一章教你如何用最简单的方式验证效果同时把我遇到过的典型问题整理成速查表。5.1 用 ab 做一次“前后对比压测”Apache 自带的 ab 工具是验证并发性能最方便的工具不用额外安装。改配置前我已经让你跑过一次基线数据改完配置、重启 Apache 之后再跑一次完全相同的命令ab -n 1000 -c 50 http://localhost/前后对比时注意保持条件一致同一个 URL、同一个并发数、同一台机器、尽量在同一时段。如果改完配置后Requests per second提升明显、Failed requests归零、Time per request下降说明调整有效。如果数据反而变差回头检查是不是某个参数设得太激进比如线程数开太高导致频繁上下文切换或者 KeepAliveTimeout 设太长占用了线程。我做过一次比较典型的优化一台 8GB 内存的 Windows 服务器WAMP 跑一个中小型 PHP 项目50 并发压首页优化前 Requests per second 只有 38响应时间平均 1.3 秒优化后同样压力下 Requests per second 到了 115平均响应时间降到 0.43 秒。差距在哪里主要就是 OPCache 开启 KeepAliveTimeout 从 5 降到 2 模块裁剪。如果 ab 的并发模拟还不够细腻可以装 Apache JMeter创建一个线程组模拟几百个并发用户跑一段时间看聚合报告里的吞吐量、响应时间、错误率。JMeter 配置稍微复杂一些但对“模拟真实用户操作”的场景更准确。5.2 从日志和状态页抓“铁证”验证之后日常运行中还要持续监控。Apache 的 error.log 和 server-status 页面是判断并发是否健康最直接的窗口。打开http://localhost/server-status重点看几个数字BusyWorkers忙碌线程数、IdleWorkers空闲线程数。如果BusyWorkers长期接近你配置的ThreadsPerChild数值说明服务器压力很大已经接近瓶颈如果大部分时间IdleWorkers比较多说明还有余量。结合 error.log 里有没有server reached MaxRequestWorkers的报错能准确判断是不是线程池不够用。另外access.log 里的状态码也能看出端倪。如果大量请求返回 503说明 Apache 在拒绝请求通常就是线程池满了如果 500 多那就是 PHP 代码报错需要看 PHP 错误日志。这两类问题处理方向完全不同别混为一谈。5.3 常见问题速查表最后把我在处理 WAMP 并发卡顿过程中遇到的高频问题整理成一张速查表方便你按图索骥现象可能原因排查与解决改完 httpd.conf 后 Apache 起不来语法错误或端口被占用执行httpd -t检查语法netstat -ano打开 server-status 页面 403访问控制过严将Require local改为Require ip 192.168.1.0/24仅限内网访问浏览器访问出现 Apache Server at port 443 提示地址栏自动走了 https而 Apache 没配 SSL改用http://访问如需 https 再配置证书访问 phpMyAdmin 打不开MySQL 没启动或 80 端口被其他程序占用确认 wampmanager 菜单里 MySQL 服务已启动检查端口冲突调完参数后压测反而更慢线程数开太高/KeepAliveTimeout 不合理适当降低 ThreadsPerChildKeepAliveTimeout 压到 2~3 秒内存持续上涨过几天 Apache 变卡内存泄漏或碎片累积设置MaxConnectionsPerChild为 10000定期重建线程这里有一个极易忽略的坑修改 php.ini 或 my.ini 之后很多人只重启了 Apache没有重启对应的 PHP 或 MySQL 服务。WAMP 的图形控制面板里左键点托盘图标可以分别重启 Apache、MySQL、PHP 服务改哪个配置就重启哪个服务这个细节卡住过不少人。5.4 改完配置一定要“验证重启生效”再补充一个实操细节WAMP 里有 “重启所有服务” 的按钮但有时候因为它自带的缓存机制改完配置后不会立刻生效。稳妥的做法是手动在命令行里重启net stop wampapache64 net start wampapache64实际服务名可能因 WAMP 版本不同略有差异可以在命令行执行net start | findstr -i wamp查看。重启后用httpd -V或直接访问一个页面确认配置已生效再开始压测。否则你改了配置但服务跑的还是旧参数压测结果自然没有参考价值。6. 关于这套配置我踩过的坑和后续建议6.1 踩了几个版本才明白的取舍这个方案我帮不同团队落地过很多次也踩过不少坑。最大的一个教训是不要一次性把所有参数都改掉。每改一个参数跑一次压测确认没有副作用再改下一个。否则一旦性能变差你根本不知道是哪个参数引起的回滚时也无从下手。我自己的操作顺序是先开 OPCache收益最大、风险最低再调 KeepAliveTimeout 和 MaxKeepAliveRequests最后根据压测结果微调 ThreadsPerChild。另一个深刻体会是Windows 下的 Apache 并发能力上限就在那里。线程模型 mod_php 的架构决定了它适合中小规模访问硬要往 500、1000 并发调内存会先撑不住。一个 8GB 内存的 Windows 机器Apache PHP MySQL 三个服务全跑稳定支撑 100 左右的并发连接已经是比较理想的成绩。如果你的业务确实需要更高并发那就不要想着靠调参数硬撑换架构才是正道。6.2 如果项目流量再往上涨怎么过渡当并发压力持续增大我的建议是逐步分离服务。最简单的一步是把数据库单独放到一台机器让 Apache 所在的服务器专注处理 Web 请求MySQL 不再抢占内存。再进一步把静态资源迁移到 CDN 或对象存储让 Apache 只处理动态接口。到了这一步Apache 的并发压力已经降下来了。如果流量还是不够扛那就需要考虑把 WAMP 替换成更专业的组合比如 Linux Nginx 或 Apache event MPM PHP-FPM Redis。PHP-FPM 相比 mod_php最大的优势是 PHP 进程和 Web 进程分离单个慢脚本不会拖垮所有请求并发能力和稳定性都上一个台阶。但这是后话在项目真正成长到那个阶段之前把 WAMP 这套环境按照本文的方法调优到位应对中小型项目的日常访问是绰绰有余的。最后再分享一个小技巧每次调整完配置记得把改动记录写在一个文本文件里标清楚日期、改了哪项、压测数据是什么。别嫌麻烦这不仅是你的知识沉淀下次再遇到卡顿问题时这份记录能让你在五分钟内判断出“上次优化已经做到什么程度、这次瓶颈可能出在哪”。我在实际操作中的体会是绝大多数“诡异的卡顿”最后翻出来都是某次改动没记录、后来忘了才导致的。所以这次把每一步都记下来比调好参数本身更有价值。
返回列表