这篇收四个不成体系但都实际遇到过的问题:两个故障、两个改造。每个都保留当时的现象、定位过程和解法。
插件把 CPU 吃满
某天站点卡到打不开,进服务器看 top,两个核的 CPU 全是满的,占用进程全是 php-fpm。
进不去后台,只能从文件系统下手:到 /www/wwwroot/imsxx.com/wp-content/plugins,把可疑插件的文件夹改名,WordPress 找不到目录就无法加载它,相当于变相停用。
站点恢复之后再看,罪魁是某个带「文章标签内链」功能的插件。它每次渲染文章都要扫描全文做替换,文章一多就把 PHP 进程占满。从后台关掉这个功能后,占用回到正常水平。
这个套路在没有后台权限时很好用:改目录名 = 停用插件,比进数据库改配置快,也比直接删掉安全。确认是哪个插件之后再决定是关功能还是卸载。
发布文章时无限加载
点「发布」之后转圈不停,最后白屏报错,但文章其实已经发出去了。
排查顺序是「先排除插件,再怀疑自己写的代码」:
- 关闭所有插件,确认发布恢复正常
- 逐个启用插件,每启用一个就试一次发布
- 启用 Easy WP SMTP 之后问题复现
但把 Easy WP SMTP 装到一个全新环境里测试,发布完全正常——说明不是插件本身的问题,而是我在它上面加的代码。
翻了很久才想起来,之前给邮件通知做过「美化」,往邮件模板里塞了一段自定义 HTML。这段代码挂在邮件插件里,而邮件插件又会在发布文章时被触发,代码写得不够干净,每次调用都把 post.php 的进程拖死。浏览器那边看到的就是一直转圈。
F12 里 post.php 返回 0,也印证了这一点:请求被异常中断,但文章数据已经写库了。
解法有两个:删掉美化代码,或者优化它。我选了前者——WordPress 自带的邮件通知确实简陋,但为了好看牺牲发布流程不值得。
教训:给插件加自定义代码时,要确认它挂在哪个钩子上。挂在 publish_post 这类高频钩子上的代码,一次性能问题就能拖垮整个后台。
主题的双 H1
WordBook 主题把站点 logo 写成了 <h1>,文章标题也是 <h1>,一页出现两个 H1,对 SEO 不友好。
在「外观 → 主题编辑器」打开 header.php,把 logo 部分的 h1 改成 div:
<div class="logo">
<a href="<?php bloginfo('url'); ?>" title="<?php bloginfo('name'); ?>">
<?php if (get_theme_mod('ds_logo')): ?>
<img src="<?php echo get_theme_mod('ds_logo'); ?>" alt="">
<?php endif; ?>
<?php if (get_theme_mod('ds_logo_dark')): ?>
<img src="<?php echo get_theme_mod('ds_logo_dark'); ?>" alt="">
<?php endif; ?>
<?php if (get_theme_mod('ds_site_name')): ?>
<b><?php echo get_theme_mod('ds_site_name') ?></b>
<?php endif; ?>
</a>
</div>改完样式可能受影响,因为原来的 h1 选择器不再命中。如果 logo 位置或字号变了,去 style.css 里把 .logo h1 换成 .logo 即可。
原则是:一个页面只保留一个 H1,且它应该是文章标题。首页可以是站点名,但文章页必须是文章标题。
在所有文章的第二段后插入广告
WordPress 没有原生的「段落级」钩子,只能用 the_content 过滤器处理字符串。
把下面这段加到主题的 functions.php 末尾:
function insert_after_first_paragraph($content) {
if (!is_single()) return $content;
$parts = explode('</p>', $content);
if (count($parts) > 1) {
$ad = '<div class="inserted-content centered-content">这里换成你的广告代码或链接</div>';
$parts[1] .= $ad;
$content = implode('</p>', $parts);
}
return $content;
}
add_filter('the_content', 'insert_after_first_paragraph');
function add_custom_styles() {
echo '<style>
.centered-content {
text-align: center;
margin: 20px 0;
}
</style>';
}
add_action('wp_head', 'add_custom_styles');几个细节:
- 按
</p>分割比按换行分割稳,因为 WordPress 输出的段落一定以</p>闭合 $parts[1]就是第一段(数组从 0 开始),在它后面追加内容等于插在第二段之前is_single()限制只对文章页生效,首页和页面不受影响- 改了没生效,先清缓存,再确认主题是否另有
functions.php的自定义加载机制
如果站点用了页面缓存,插入的广告在缓存生成时就固定了,换广告代码要顺手清一次缓存。
相关内容
一台 2C4G VPS 上用 1Panel(LEMP + Docker)跑多个 WordPress,优化后后台变慢并出现 EdgeOne 524。本文按时间线复盘:如何从“缓存/超时”误区切换到“容器环回 + Docker 出网被 iptables FORWARD 掐死”的根因定位,最终用 host-gateway + iptables 持久化完成修复,并给出可复制的检查清单。
一台 2 核 4G 的 VPS 承载 4 个 WordPress:从 PHP-FPM 的 ondemand 改造、MySQLTuner 诊断、MariaDB 参数收敛,到缓存分层、端口暴露检查和 swap 兜底。
宝塔面板下 WordPress 的全套优化清单:Nginx、MySQL 性能调整、PHP 参数与扩展、Swap,以及注释掉面板自带 404 页面。