---
canonical: https://meta.cyberforums.com/t/wordpress-glotpress-ttfb-45-60/2462
webpage: https://wpcy.com/community/t/2462-wordpress-glotpress-ttfb-45-60
language: zh-Hans
---

# WordPress 多站点 + GlotPress 翻译平台 TTFB 从 45 秒降到 60 毫秒的优化实战

> 文派叶子支持论坛的只读副本，本页不能回复。
> 讨论原文：https://meta.cyberforums.com/t/wordpress-glotpress-ttfb-45-60/2462
> 网页版：https://wpcy.com/community/t/2462-wordpress-glotpress-ttfb-45-60

## 1 · wenpai

- 发布时间：2026年2月24日 23:01

问题
一个运行 67 个子站的 WordPress Multisite 翻译平台（GlotPress 4.0.3 + WP 6.8.3），首页 TTFB 5.7 秒，繁体中文页面（/zh-tw/、/zh-hk/）TTFB 高达 45 秒，服务器 load 长期 30+。
服务器配置不差：80 核 62GB 内存，PHP 8.3，Redis 已有（Object Cache Pro），但 PHP-FPM 22 个 worker 全部 80%+ CPU。
根因分析
排查发现三个叠加因素：
1. wp-chinese-converter 的 OpenCC 字典排序
这是最大的性能杀手。插件使用 OpenCC PHP 库做繁简转换，核心瓶颈在 class-wpcc-opencc-converter.php 的 get_prepared_dictionaries() 方法：
// 53,650 个词条，每次请求都要 uksort
uksort($flat, function ($a, $b) {
    return mb_strlen($b) <=> mb_strlen($a);
});

虽然代码里有 $this->prepared[] 做了单次请求内的缓存，但 PHP-FPM 每个请求是独立进程，字典排序每次都要重新做。53,650 个词条的 uksort + mb_strlen 比较，单次耗时数秒。
排序之后的 strtr($output, $dict) 对 5 万多词条的替换本身也很慢。
2. 无 robots.txt，爬虫疯狂爬翻译页面
没有 robots.txt，MJ12bot 翻到了 /zh-hk/tag/right-sidebar/page/1105（是的，第 1105 页）。GPTBot、OAI-SearchBot、Bytespider、SemrushBot、ClaudeBot 也在同时爬。
每个爬虫请求都是一个完整的 PHP 处理 + OpenCC 字典排序 + 大字典 strtr 替换。最近 10000 个请求中约 10% 是这类爬虫，但它们请求的全是 CPU 密集的翻译页面。
3. Cavalcade cron 任务失控
Cavalcade（WordPress cron 替代方案）有 63 个僵尸 action_scheduler_run_queue 任务从 2025 年 11 月卡到现在，5 个 worker 各吃 95% CPU。加上 WP-Rocket 激活后 67 个子站同时产生 RUCSS 和预加载任务，雪上加霜。
4. wp-chinese-converter 的 Set-Cookie 阻止缓存
插件在每个请求上设置 Set-Cookie: wpcc_variant_xxx，导致 nginx fastcgi_cache 默认不缓存这些响应。即使配了缓存也不生效。
优化方案
第一步：拦截爬虫（立即见效）
创建 robots.txt 拦截无价值爬虫：
User-agent: MJ12bot
Disallow: /

User-agent: Bytespider
Disallow: /

# GPTBot, OAI-SearchBot, SemrushBot, DotBot, AhrefsBot, PetalBot, ClaudeBot 同上

User-agent: *
Disallow: /wp-admin/
Disallow: /glotpress/
Disallow: /translate/
Disallow: /zh-tw/tag/
Disallow: /zh-hk/tag/

同时在 nginx 层直接 403 拦截（robots.txt 只是君子协定）：
# /www/server/panel/vhost/nginx/extension/wpfanyi.com/bot_block.conf
if ($http_user_agent ~* "(MJ12bot|Bytespider|GPTBot|OAI-SearchBot|SemrushBot|DotBot|AhrefsBot|PetalBot|ClaudeBot)") {
    return 403;
}

第二步：nginx fastcgi_cache（根本性解决）
在 nginx http 块定义 cache zone：
# 0.wpfanyi_fcgi_cache.conf (http 块)
fastcgi_cache_path /path/to/nginx-cache levels=1:2
  keys_zone=wpfanyi_cache:100m max_size=2g inactive=60m use_temp_path=off;

在 server 块启用缓存，关键是要忽略 wp-chinese-converter 的 Set-Cookie：
set $skip_cache 0;

if ($request_method = POST) { set $skip_cache 1; }
if ($arg_s) { set $skip_cache 1; }
if ($http_cookie ~* "wordpress_logged_in_") { set $skip_cache 1; }
if ($request_uri ~* "/wp-admin/|/wp-login.php|/wp-json/") { set $skip_cache 1; }

fastcgi_cache wpfanyi_cache;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_valid 200 301 60m;
fastcgi_cache_valid 404 1m;
fastcgi_cache_bypass $skip_cache;
fastcgi_no_cache $skip_cache;
fastcgi_cache_use_stale error timeout updating http_500 http_503;
fastcgi_cache_lock on;

# 关键：忽略 wp-chinese-converter 的 Set-Cookie
fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
fastcgi_hide_header Set-Cookie;

add_header X-FastCGI-Cache $upstream_cache_status;

第三步：OpenCC 字典 OPcache 文件缓存
修改 get_prepared_dictionaries() 方法，排序后写入 PHP 文件，后续请求通过 include + OPcache 加载：
private function get_prepared_dictionaries(string $strategy): array {
    if (isset($this->prepared[$strategy])) {
        return $this->prepared[$strategy];
    }

    // 尝试从 PHP 文件缓存读取（OPcache 加速）
    $cache_file = WP_CONTENT_DIR . "/cache/wpcc-dictionaries/dict_" . md5($strategy) . ".php";
    if (file_exists($cache_file)) {
        $prepared = include $cache_file;
        if (is_array($prepared) && !empty($prepared)) {
            $this->prepared[$strategy] = $prepared;
            return $prepared;
        }
    }

    // 首次：排序并写入文件缓存
    $sets = Dictionary::get($strategy);
    // ... uksort 逻辑不变 ...

    // 写入 PHP 文件，OPcache 自动缓存字节码
    $export = "<?php\nreturn " . var_export($prepared, true) . ";\n";
    $tmp = $cache_file . ".tmp." . getmypid();
    if (@file_put_contents($tmp, $export, LOCK_EX) !== false) {
        @rename($tmp, $cache_file);
        if (function_exists("opcache_compile_file")) {
            @opcache_compile_file($cache_file);
        }
    }
    return $prepared;
}

第四步：限制 Cavalcade CPU
# /etc/systemd/system/cavalcade.service
[Service]
Nice=19
CPUQuota=200%
CPUWeight=50

优化结果




指标
优化前
优化后




服务器 Load
34.87
3.14


首页 TTFB
5.7s
60ms


zh-tw 页面 TTFB
45s
66ms


zh-hk 页面 TTFB
6s
65ms


PHP-FPM workers
22 个 80%+ CPU
10 个 19% CPU



经验总结


wp-chinese-converter / OpenCC 是 CPU 杀手 — 5 万词条的 uksort + mb_strlen 比较 + strtr 大字典替换，每个繁体页面都触发。必须加持久化缓存。


Set-Cookie 会静默破坏 HTTP 缓存 — 插件每次请求都设置 cookie，nginx fastcgi_cache 默认不缓存带 Set-Cookie 的响应。需要显式 fastcgi_ignore_headers Set-Cookie。


没有 robots.txt 的翻译站点是爬虫磁铁 — 翻译站点 URL 结构（/zh-tw/tag/xxx/page/N）会产生海量可爬页面，爬虫会无限翻页。


Cavalcade + action_scheduler 会失控 — 僵尸任务堆积 + WP-Rocket 67 个子站同时产生后台任务 = CPU 爆炸。必须限制 worker 数和 CPU 配额。


nginx fastcgi_cache 是多站点 WordPress 最有效的前端优化 — 一层缓存解决 99% 访客的性能问题，配置简单，效果立竿见影。


Object Cache Pro 的 metrics snapshots 可能膨胀 — wp_sitemeta 中 objectcache_snapshots 可达数百 KB，单次写入耗时数秒，需要定期清理。

## 2 · system

- 发布时间：2026年2月24日 23:01

核心优化策略分析
你的优化方案非常全面，特别是对 wp-chinese-converter 插件性能瓶颈的定位很准确。让我补充几个 WordPress 层面的优化建议：
1. 替代 wp-chinese-converter 的方案
既然这是翻译平台，可以考虑更轻量的繁简转换方案：
// 在主题的 functions.php 中添加
add_filter('locale', function($locale) {
    // 根据 URL 路径判断语言变体
    if (strpos($_SERVER['REQUEST_URI'], '/zh-tw/') !== false) {
        return 'zh_TW';
    }
    if (strpos($_SERVER['REQUEST_URI'], '/zh-hk/') !== false) {
        return 'zh_HK';
    }
    return $locale;
});

// 使用 WordPress 内置的翻译文件，避免实时转换
load_textdomain('default', WP_LANG_DIR . '/zh_TW.mo');

2. 优化 Cavalcade 和 Action Scheduler
对于多站点环境，Action Scheduler 任务需要更精细的控制：
// 在 wp-config.php 中添加
define('ACTION_SCHEDULER_LOCK_TIMEOUT', 60); // 减少锁超时时间
define('ACTION_SCHEDULER_QUEUE_RUNNER_CONCURRENT_BATCHES', 1); // 限制并发批次
define('ACTION_SCHEDULER_GROUP_CONCURRENCY', 1); // 限制组并发

// 清理僵尸任务
add_action('init', function() {
    global $wpdb;
    // 清理超过24小时的失败任务
    $wpdb->query("
        DELETE FROM {$wpdb->prefix}actionscheduler_actions 
        WHERE status = 'failed' 
        AND scheduled_date_gmt < DATE_SUB(NOW(), INTERVAL 24 HOUR)
    ");
});

3. 优化 Object Cache Pro 配置
// wp-config.php 中的 Redis 配置优化
define('WP_REDIS_CONFIG', [
    'token' => 'your_token',
    'host' => '127.0.0.1',
    'port' => 6379,
    'database' => 0,
    'timeout' => 1.0,
    'read_timeout' => 1.0,
    'retry_interval' => 100,
    'compression' => 'zstd', // 使用 zstd 压缩
    'serializer' => 'igbinary', // 更快的序列化
    'async_flush' => true, // 异步刷新
    'split_alloptions' => true, // 分割 alloptions
    'prefetch' => false, // 多站点关闭预取
    'debug' => false,
    'save_commands' => false, // 关闭命令记录
    'prefix' => 'wpfanyi:', // 自定义前缀
]);

4. WordPress 多站点查询优化
// 减少跨站点查询
add_filter('ms_site_check', '__return_false'); // 禁用站点检查
add_filter('site_option__site_transient_timeout_available_translations', '__return_zero'); // 禁用翻译更新检查

// 优化 GlotPress 查询
add_filter('gp_before_get_translation_sets', function($query) {
    $query['no_found_rows'] = true; // 禁用分页计数
    $query['update_post_meta_cache'] = false;
    $query['update_post_term_cache'] = false;
    return $query;
});

5. 数据库索引优化
检查并添加必要的索引：
-- 为 wp_posts 表添加索引
ALTER TABLE wp_posts ADD INDEX idx_post_type_status_date (post_type, post_status, post_date);
ALTER TABLE wp_posts ADD INDEX idx_post_parent (post_parent);

-- 为 wp_term_relationships 表添加索引
ALTER TABLE wp_term_relationships ADD INDEX idx_term_taxonomy_id (term_taxonomy_id);

-- 清理 objectcache_snapshots
DELETE FROM wp_sitemeta WHERE meta_key LIKE 'objectcache_snapshots%';

6. PHP-FPM 配置优化
; /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000 ; 防止内存泄漏
request_terminate_timeout = 30s ; 超时时间

7. 监控和告警
建议添加性能监控：
// 在 mu-plugins 中添加性能监控
add_action('shutdown', function() {
    if (defined('SAVEQUERIES') && SAVEQUERIES) {
        $queries = get_num_queries();
        $time = timer_stop(0, 3);
        if ($queries > 100 || $time > 1.0) {
            error_log(sprintf(
                'Slow request: %s - %d queries in %s seconds',
                $_SERVER['REQUEST_URI'],
                $queries,
                $time
            ));
        }
    }
});

你的优化方案已经覆盖了主要瓶颈，这些补充建议可以帮助进一步提升 WordPress 层面的性能。特别是对于多站点环境，减少跨站点查询和优化数据库索引会有明显效果。
