WordPress 服务器性能测试优化方案 & 迁移记录

WordPress 服务器性能测试优化方案 & 迁移记录

文章目录
文章目录
  1. 1. Web 服务器性能测试
  2. 2. WordPress 服务器环境搭建
  3. 3. WordPress 服务器性能优化
  4. 4. WordPress 网站迁移记录
  5. 5. 其他应用安装

前段时间,我抢了一台腾讯的轻量云服务器,本来都已经把本站迁移过去了,但结果发现那台机器的性能实在太差了,动不动就卡爆,只好回退到阿里云这边了。通过这次迁移,我倒是把整个过程走了一遍,积累了一些经验。同时,也让我重新考虑换服务器的事。这仔细一琢磨啊,现用的阿里云确实有点贵啊!

于是,最近我一直在留意合适的 VPS,还试过一些小厂商的机器,但性能测试和实际使用下来都不太行,虚标的情况挺严重。前两天看到群里有人推百度云 BCC 的大促活动,价格特别便宜。4C4G40G3MB 配置能带 Windows Server 的版本,首年只要¥36...这价格买不了上当买不了吃亏,顺手下了一台。

接着几天,我有空就对这台 BCC 做测试,最后发现竟然堪用,于是决定把阿里云上所有的业务,包括数个网站、Docker 等应用都迁移过去。这当然涉及到很多工作…包括域名备案、环境搭建等等,但本文只着重记录我是如何进行性能测试和优化 WordPress 服务器的,如有更好的办法,先行感谢分享不吝赐教了...🙏🙏🙏

1. Web 服务器性能测试

网上有各种各样的服务器性能测试方法和脚本,对于 Web 服务器来说,常用的工具无非就是 sysbench、iostat、fio 等等。我琢磨了一下,利用 AI 写了个脚本,能够直观地输出数据,方便进行对比。

当然,这个测试并不严谨,但我主要是为了自用,而且测试的对象是 Web 服务器。所以,把这些数据拿来做横向对比,尤其是和现有服务器相比,能够很清楚地看出差异。你只需要将以下命令行保存为可执行的 .sh 文件,比如 server_bench.sh,然后运行,就能得到截图所示的结果。

#!/bin/bash
# 综合服务器性能测试脚本(by shephe.com)

# 颜色定义
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
NC='\033[0m'

# 工具检查
check_tools() {
    local tools=("sysbench" "iostat" "curl" "fio" "dd" "ping" "mysql")
    local missing_tools=()
    for tool in "${tools[@]}"; do
        command -v "$tool" >/dev/null 2>&1 || missing_tools+=("$tool")
    done
    if [ ${#missing_tools[@]} -ne 0 ]; then
        echo -e "${RED}[错误] 缺少必要工具:${missing_tools[*]},请先安装。${NC}"
        exit 1
    fi
}

# 清理临时文件
cleanup() {
    rm -f test_io test_fio 2>/dev/null
}

trap cleanup EXIT
check_tools

echo -e "\n${BLUE}=== 🖥️ 系统概况 ===${NC}"
echo -e "主机名: $(hostname)"
echo -e "系统: $(lsb_release -d 2>/dev/null | awk -F'\t' '{print $2}' || uname -srmo)"
echo -e "CPU: $(lscpu | grep 'Model name' | awk -F':' '{print $2}' | sed 's/^[ \t]*//')"
echo -e "CPU 核数: $(nproc)"
echo -e "内存: $(free -h | awk '/Mem:/ {print $2 " (可用: " $7 ")"}')"
echo -e "磁盘:"
lsblk -d -o NAME,SIZE | grep -v 'NAME' | awk '{print "  - " $1 ": " $2}'
echo -e "内核版本: $(uname -r)"
echo -e "当前负载:$(uptime | awk -F'load average:' '{print $2}' | sed 's/,//g')"
echo

echo -e "${BLUE}=== ⚙️ CPU 测试(10 秒) ===${NC}"
echo -e "单线程性能:"
sysbench cpu --threads=1 --time=10 run | grep "events per second" | awk -F':' '{print "  事件/秒: " $2}'
echo -e "多线程性能(共 $(nproc) 核):"
sysbench cpu --threads=$(nproc) --time=10 run | grep "events per second" | awk -F':' '{print "  事件/秒: " $2}'


echo -e "${BLUE}=== 🧠 内存测试(读写各 1GB) ===${NC}"
echo -e "内存读取:"
sysbench memory --memory-total-size=1G --memory-oper=read run | grep "transferred" | awk '{print "  " $0}'
echo -e "内存写入:"
sysbench memory --memory-total-size=1G --memory-oper=write run | grep "transferred" | awk '{print "  " $0}'
echo

echo -e "${BLUE}=== 💽 磁盘 IO 测试(顺序+随机) ===${NC}"
echo -e "顺序写入:"
dd if=/dev/zero of=test_io bs=4M count=128 conv=fdatasync 2>&1 | grep copied | awk '{print "  " $0}'
echo -e "顺序读取:"
dd if=test_io of=/dev/null bs=4M 2>&1 | grep copied | awk '{print "  " $0}'
cleanup
echo -e "随机读写(fio):"
fio --name=randrw --rw=randrw --bs=4k --size=256M --numjobs=1 --runtime=10 --time_based --group_reporting \
    --filename=test_fio --ioengine=libaio --iodepth=4 | grep -E 'read: IOPS|write: IOPS' \
    | awk '{print "  " $1" IOPS="$3, "BW="$5}'
cleanup
echo

echo -e "${BLUE}=== 🌐 网络性能测试 ===${NC}"
echo -e "下载速度:"
download_bytes=$(curl -o /dev/null -s -w "%{speed_download}" https://download.z.weixin.qq.com/app/win/wetype_installer_official_p_48.exe)
if [[ "$download_bytes" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
    download_mib=$(awk "BEGIN {printf \"%.2f\", $download_bytes / 1024 / 1024}")
    echo -e "  速度: ${download_mib} MiB/s"
else
    echo -e "  下载失败或 curl 输出异常"
fi

echo -e "Ping 测试(到 223.5.5.5):"
ping -c 4 223.5.5.5 | grep 'rtt' | awk -F'/' '{print "  平均延迟: "$5" ms"}'
echo

echo -e "${BLUE}=== 🗄️ 数据库性能测试(MySQL) ===${NC}"

MAX_RETRY=3
MYSQL_USER="root"
MYSQL_DB="sysbench_test"
MYSQL_PASS=""

for ((i=1; i<=MAX_RETRY; i++)); do
    read -s -p "请输入数据库 root 密码(回车跳过): " MYSQL_PASS
    echo
    if [[ -z "$MYSQL_PASS" ]]; then
        echo -e "跳过数据库测试。"
        break
    fi
    echo -e "尝试连接数据库..."

    if mysql -u$MYSQL_USER -p$MYSQL_PASS -e ";" 2>/dev/null; then
        echo -e "✅ 连接成功,准备执行测试..."

        mysql -u$MYSQL_USER -p$MYSQL_PASS -e "CREATE DATABASE IF NOT EXISTS $MYSQL_DB;" 2>/dev/null

        echo -e "准备测试数据..."
        sysbench oltp_read_write --table-size=100000 --db-driver=mysql \
          --mysql-user=$MYSQL_USER --mysql-password=$MYSQL_PASS \
          --mysql-host=localhost --mysql-db=$MYSQL_DB prepare >/dev/null

        echo -e "执行数据库基准测试(10 秒):"
        sysbench oltp_read_write --table-size=100000 --db-driver=mysql \
          --mysql-user=$MYSQL_USER --mysql-password=$MYSQL_PASS \
          --mysql-host=localhost --mysql-db=$MYSQL_DB --time=10 --threads=4 run \
          | grep -E 'transactions:.*per sec|queries:.*per sec' \
          | awk '{print "  " $1" "$2" "$3}'

        echo -e "清理测试数据..."
        sysbench oltp_read_write --table-size=100000 --db-driver=mysql \
          --mysql-user=$MYSQL_USER --mysql-password=$MYSQL_PASS \
          --mysql-host=localhost --mysql-db=$MYSQL_DB cleanup >/dev/null
        mysql -u$MYSQL_USER -p$MYSQL_PASS -e "DROP DATABASE IF EXISTS $MYSQL_DB;" >/dev/null

        break
    else
        echo -e "${RED}密码错误,第 $i 次尝试失败。${NC}"
        if [[ $i -eq $MAX_RETRY ]]; then
            echo -e "${RED}已达到最大重试次数,跳过数据库测试。${NC}"
        fi
    fi
done

echo -e "\n${GREEN}🎉 所有测试完成:$(date '+%Y-%m-%d %H:%M:%S')${NC}"

以上 .sh 命令行会检查并调用 sysbench iostat fio 等工具,因此如果你没装过的话,先执行以下命令行安装(仅适用于 Debian / Ubuntu 服务器,其他发行版适当改改就行):

sudo apt-get install sysbench sysstat fio -y

从上面的测试结果来看,BCC 的纸面数据明显优于我当前使用的 Aliyun ECS。无论是单线程还是多线程,BCC 的处理能力都更强,更适合高负载、高并发的应用。同时,BCC 在 内存性能 上也占有优势,读取和写入速度都高于 Aliyun。在 磁盘 I/O 性能 上,BCC 的顺序读取速度大幅领先,达到了 13.5 GB/s,而 Aliyun 仅为 4.9 GB/s。虽然 Aliyun 在顺序写入方面与 BCC 相近,但整体磁盘性能依然较弱。

不过,这个测试结果虽然有参考价值,但也不完全准确。我在 Aliyun 的后台管理面板查到,系统盘被分配了 3000 IOPS,而 BCC 的系统盘为 2120 IOPS,数据差异让这个测试结果显得有些模糊。

在实际建站测试中,三者的差距则更加明显。为了确保公平,我尽量保持了系统环境的一致性(如 LNMP 版本和 PHP 扩展配置),测试站除域名外其他完全一样。Aliyun 的页面生成时间比 BCC 快了约 1/5,比 Racknerd 快了约 2/3。这里提到的页面生成时间是指 PHP 渲染页面的时间,可以通过函数 timer_stop(0) 或安装 Query Monitor 来查看。我试了很多方法,但无论如何调整,BCC 都表现得稍慢一些。关于如何调整的详细内容,请参考本文第三章。

你可能要说数据库查询时间对页面生成时间的影响…这么说吧,Aliyun 的数据库查询时间最长,但它的页面生成最快!所以这是怎么回事儿呢?有没有大牛提点一下…按我现在的测试,只能把原因归结到环境和性能差异了。

2. WordPress 服务器环境搭建

不管怎样,这台百度智能云服务器的性能还是不错的。在实际使用中,我通过果果日记(登录管理员)整站测试,首页页面生成时间为 0.32 秒。相比阿里云的 0.28 秒,略慢一些,但完全可以接受。

而且,非管理员用户将启用 FastCGI 缓存,这会大大提升性能。因此,我决定将阿里云上的业务整体迁移到百度云。在此之前,我已经在 BCC 上搭建了完整的环境,并做了一些基础的系统优化。相关优化内容请参见下表:

  1. 系统环境:宝塔面板、LNMP、Docker
  2. 增强扩展:Memcached、Opcache、fileinfo
  3. 应用软件:phpMyAdmin、宝塔网站监控报表、Nginx 防火墙、日志清理工具、Xray

除了 Xray,其余都是非常常见的扩展和软件,没有什么特别之处。近期,GFW 的封锁越来越严格,而且免费的 Docker 镜像源也越来越难找,GitHub 的速度也慢得令人抓狂。因此,我直接一步到位安装了代理(服务端为 V2Ray,运行在 Racknerd 上),并修改了 Docker 的环境变量来实现全局代理。

同时,我还写了一个小脚本,并给脚本添加了别名。这样,在 git、shell 或 apt 中需要使用代理时,只需要通过 proxy_on/off/status 命令来切换,非常方便。/root/proxy_toggle.sh脚本如下:

#!/bin/bash
# 代理一键开关:当前 shell + git + apt
# 用法:source /root/proxy_toggle.sh on|off|status
# 关闭时不破坏原有网络与配置(自动备份并恢复)

PROXY_URL="${PROXY_URL:-http://127.0.0.1:7890}"

# 状态与备份文件
STATE_DIR="${HOME}/.config/proxy_toggle"
STATE_FILE="${STATE_DIR}/state.env"
mkdir -p "$STATE_DIR"

# apt 代理文件(我们只动这一个)
APT_PROXY_CONF="/etc/apt/apt.conf.d/80proxy-toggle"

# 判断是否 source 执行
is_sourced() { [[ "${BASH_SOURCE[0]}" != "${0}" ]]; }

# 需要 root 权限时决定是否用 sudo
need_root_cmd() {
  if [[ $EUID -eq 0 ]]; then
    "$@"
  else
    if command -v sudo >/dev/null 2>&1; then
      sudo "$@"
    else
      echo "⚠️ 需要 root 权限执行:$*  (未安装/配置 sudo)" >&2
      return 1
    fi
  fi
}

# 读取旧状态(若存在)
load_state() {
  if [[ -f "$STATE_FILE" ]]; then
    # shellcheck source=/dev/null
    source "$STATE_FILE"
  fi
}

# 保存当前状态
save_state() {
  cat > "$STATE_FILE" <<EOF
ACTIVE="${ACTIVE:-0}"
PREV_HTTP_PROXY="$(printf %s "${PREV_HTTP_PROXY}")"
PREV_HTTPS_PROXY="$(printf %s "${PREV_HTTPS_PROXY}")"
PREV_GIT_HTTP_PROXY="$(printf %s "${PREV_GIT_HTTP_PROXY}")"
PREV_GIT_HTTPS_PROXY="$(printf %s "${PREV_GIT_HTTPS_PROXY}")"
EOF
}

# ---------- shell 环境 ----------
enable_shell_env() {
  # 备份仅在第一次启用时记录
  if [[ "${ACTIVE:-0}" != "1" ]]; then
    PREV_HTTP_PROXY="${http_proxy}"
    PREV_HTTPS_PROXY="${https_proxy}"
  fi
  export http_proxy="$PROXY_URL"
  export https_proxy="$PROXY_URL"
}

disable_shell_env() {
  # 恢复:若原来有值则还原,没有就 unset
  if [[ -n "${PREV_HTTP_PROXY}" ]]; then
    export http_proxy="${PREV_HTTP_PROXY}"
  else
    unset http_proxy
  fi
  if [[ -n "${PREV_HTTPS_PROXY}" ]]; then
    export https_proxy="${PREV_HTTPS_PROXY}"
  else
    unset https_proxy
  fi
}

# ---------- git 代理 ----------
enable_git_proxy() {
  if [[ "${ACTIVE:-0}" != "1" ]]; then
    PREV_GIT_HTTP_PROXY="$(git config --global --get http.proxy 2>/dev/null || true)"
    PREV_GIT_HTTPS_PROXY="$(git config --global --get https.proxy 2>/dev/null || true)"
  fi
  git config --global http.proxy  "$PROXY_URL"  2>/dev/null || true
  git config --global https.proxy "$PROXY_URL"  2>/dev/null || true
}

disable_git_proxy() {
  if [[ -n "${PREV_GIT_HTTP_PROXY}" ]]; then
    git config --global http.proxy "${PREV_GIT_HTTP_PROXY}" 2>/dev/null || true
  else
    git config --global --unset http.proxy 2>/dev/null || true
  fi
  if [[ -n "${PREV_GIT_HTTPS_PROXY}" ]]; then
    git config --global https.proxy "${PREV_GIT_HTTPS_PROXY}" 2>/dev/null || true
  else
    git config --global --unset https.proxy 2>/dev/null || true
  fi
}

# ---------- apt 代理(独立文件,不覆盖你的原配置) ----------
enable_apt_proxy() {
  need_root_cmd bash -c "cat > '$APT_PROXY_CONF' <<EOF
Acquire::http::Proxy  \"$PROXY_URL\";
Acquire::https::Proxy \"$PROXY_URL\";
EOF" || return 1
}

disable_apt_proxy() {
  need_root_cmd rm -f "$APT_PROXY_CONF" || return 1
}

# ---------- 显示状态 ----------
show_status() {
  echo "=== Shell ==="
  echo "http_proxy=${http_proxy:-<empty>}"
  echo "https_proxy=${https_proxy:-<empty>}"
  echo
  echo "=== git (global) ==="
  git config --global -l 2>/dev/null | grep -E '^(http|https)\.proxy=' || echo "git 无代理配置"
  echo
  echo "=== apt ==="
  if [[ -f "$APT_PROXY_CONF" ]]; then
    echo "(已启用) $APT_PROXY_CONF 内容:"
    need_root_cmd cat "$APT_PROXY_CONF" 2>/dev/null || true
  else
    echo "apt 无代理配置(我们的 80proxy-toggle 未启用)"
  fi
  echo
  echo "PROXY_URL=${PROXY_URL}"
  echo "提示:若 Shell 变量为空,请使用:source $0 on"
}

# ---------- 主逻辑 ----------
load_state

case "$1" in
  on)
    # 必须 source 才能让当前 shell 变量生效
    if ! is_sourced; then
      echo "💡 请使用:source $0 on"
      exit 1
    fi
    enable_shell_env
    enable_git_proxy
    if enable_apt_proxy; then
      ACTIVE="1"
      save_state
      echo "✅ 代理已开启(shell + git + apt) -> $PROXY_URL"
    else
      echo "⚠️ apt 代理未能写入(可能缺少 root/sudo),但 shell+git 已启用"
    fi
    ;;

  off)
    if ! is_sourced; then
      echo "💡 请使用:source $0 off"
      exit 1
    fi
    # 先恢复/清理
    disable_shell_env
    disable_git_proxy
    if disable_apt_proxy; then
      :
    else
      echo "⚠️ 未能删除 apt 代理文件(可能缺少 root/sudo),请手动处理:$APT_PROXY_CONF"
    fi
    ACTIVE="0"
    save_state
    echo "❌ 代理已关闭(已恢复原有 shell/git,删除我们创建的 apt 代理文件)"
    ;;

  status|*)
    show_status
    ;;
esac

设置别名的脚本如下:

alias proxy_on='source /root/proxy_toggle.sh on'
alias proxy_off='source /root/proxy_toggle.sh off'
alias proxy_status='source /root/proxy_toggle.sh status'

看看实际的运行效果:

WordPress 服务器性能测试优化方案 & 迁移记录
实际测试,江苏这台 BCC 的网络还是不错的

3. WordPress 服务器性能优化

注意审题,这里只对 WordPress 服务器的性能进行优化,确切的讲,我只优化“页面生成时间”这一个指标,因此不涉及 CDN、数据库缓存什么的。上文提到,我“做了很多测试”,才把这个指标干到 0.32s,实际上一开始它接近 2s!

我主要安装了 PHP opcache 扩展,它的作用是把 PHP 脚本编译后的 Opcode(操作码) 缓存在内存中。这样同一个脚本在后续请求时就不需要再次解析和编译,直接执行缓存的字节码,从而显著提升 PHP 应用的性能、降低 CPU 消耗。

对于像 WordPress 这类高频访问的站点,开启 OPcache 能够明显缩短页面生成时间,是必备的优化手段之一。对于我上面 Aliyun 和 BCC 这样配置的服务器来说,经过我数次的测试,我总结 PHP 配置和 FPM 配置这样写比较快:

[Zend Opcache]
zend_extension=/www/server/php/82/lib/php/extensions/no-debug-non-zts-20220829/opcache.so
opcache.enable = 1
opcache.memory_consumption=256
opcache.interned_strings_buffer=32
opcache.max_accelerated_files=100000
opcache.revalidate_freq=60
opcache.validate_timestamps=1
opcache.fast_shutdown=1
opcache.enable_cli=0
opcache.file_update_protection=0
opcache.save_comments=1
opcache.jit_buffer_size=256m
opcache.jit=1255
[global]
pid = /www/server/php/82/var/run/php-fpm.pid
error_log = /www/server/php/82/var/log/php-fpm.log
log_level = notice

[www]
listen = /tmp/php-cgi-82.sock
listen.backlog = 8192
listen.allowed_clients = 127.0.0.1
listen.owner = www
listen.group = www
listen.mode = 0600
user = www
group = www
pm = dynamic
pm.status_path = /phpfpm_82_status
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
request_terminate_timeout = 100
request_slowlog_timeout = 30
slowlog = var/log/slow.log
WordPress 服务器性能测试优化方案 & 迁移记录

当然,这个配置还跟 PHP 版本也有关系,作为外行,我是凭浏览器刷新页面,查看函数和插件反馈的时间慢慢调的,单次刷新当然不准,后来我搞了个 PHP 脚本,可以获取到平均刷新几十次的数据,就准一些了了。

这是一个在 LNMP 环境下进行 PHP 页面生成时间基准测试 的小工具。它的用途主要是:在真实服务器环境中,批量请求指定的 URL,并统计后端执行耗时,用于对比不同服务器(例如 BCC vs 阿里云)在相同代码和数据下的性能差异。测试结果会输出 min / p50 / p90 / max / avg 等关键指标,便于分析性能稳定性和尾延迟,脚本下载 ⏬

4. WordPress 网站迁移记录

4.1 WordPress 站点迁移

网站迁移没啥可说的,无非就是备份数据库、打包文件、上传下载啥的,当然也可以宝塔的整站迁移…不过效率都差不多,我在「服务器迁移记录」这篇日志里略有提及。

另外,国内主流服务器厂商,域名备案信息要跟着迁移,至少百度这边特别敏感…我解析了几分钟不到,就收到短信给我把域名停掉了,提示了必须迁移备案。上次搞腾讯好像没这么严格,只要是备案了不管你备案在哪儿,都能先用着…不晓得长期用会不会要求迁移,没试过。

4.2 Docker 应用迁移

当前服务器上有 Certimate、AwesomeTTRSS、Memos、Twikoo 这几个容器,前两个把核心数据记住,推导重建然后在 Web 面板直接导入数据就行。这 Memos 现在没怎么用了,而且据说新版和旧版并不兼容,我想直接放弃得了。

我的 Memos 其实也没多少人看,也没几个留言,我干脆截图、在主站即当前 Kevin's Space 写篇日志得了,就这么放弃了,还免得维护了。得,就这么办喽~

5. 其他应用安装

主要有 Syncthing、FRP 等等。

「WordPress 服务器性能测试优化方案 & 迁移记录」有 9 条评论
  • Goodbye, Memos
    08/28/2025 at 11:21

    […] WordPress 服务器性能测试优化方案 & 迁移记录 08/26/2025 […]

  • 的头像
    ACEVS
    08/27/2025 at 15:21

    搬家确实忙。

    • 的头像
      Kevin
      09/09/2025 at 00:32

      也还好~熟能生巧了属于是
      我现在这个机器是百度36一年的,属于是年抛了
      明年七八月的时候还得换,害

  • Lvtu
    08/27/2025 at 12:03

    迁移最麻烦的事情就是备案问题,其它的由于各种工具越来越简便了。。。

    • 的头像
      Kevin
      09/09/2025 at 00:35

      备案也还好,就是等呗~我感觉以前还快些,,现在要等接近十天的样子;
      为了备案我甚至专门新建了个简单的页面,怕我这种复杂的首页不给过

  • 小彦
    08/26/2025 at 19:21

    opcache,回想起当年做 php 开发时,这个优化方案我还是全公司第一个提出的……

    • 的头像
      Kevin
      09/09/2025 at 00:34

      大佬专业人士 👍👍👍
      那要不你看看正文?看我配置和优化还有哪些空间?先行谢过~

      我现在的主要问题是:
      从纸面数据看,当前服务器性能是要优于阿里云的,但 PHP 的页面生成时间使用要慢一些,大概是 0.1 s

  • 的头像
    obaby
    08/26/2025 at 19:19

    php的优化还是必要的,不然太耗时了。

    • 的头像
      Kevin
      09/09/2025 at 00:34

      嗯;
      我目前能想到的手段只有这些了,不知姐姐有没有啥其他方案~

发表评论

请输入关键词…