问题最初看起来很像缓存:Magento 2 首页首字节从不到 300ms 变成 6 秒,执行 cache:flush 后第一次更慢,随后几次又恢复。半小时后问题重新出现。

如果只看“清缓存后好了一会儿”,很容易得出错误结论。我们先保留缓存,分别测了首页、分类页和一个简单 CMS 页面。分类和 CMS 都稳定,只有首页周期性变慢,范围因此缩小到首页布局和 Block。

第一步:确认是不是 Full Page Cache 未命中

响应头显示慢请求确实没有命中 FPC,但这只能解释请求进入了 PHP,不能解释 PHP 为什么需要 6 秒。接下来在测试环境记录首页各 Block 的渲染时间。

一个“猜你喜欢”Block 每次缓存失效后需要 5 秒以上。继续向下看,Block 并没有从本地集合读取商品,而是同步请求一个外部推荐接口。接口正常时 200ms,异常时要等到默认超时结束。

为什么看起来像缓存问题

Full Page Cache 命中时,慢 Block 根本不会执行,所以首页很快;缓存过期或被商品更新清理后,第一个用户请求触发外部接口,页面就变慢。清缓存不是修复,反而主动制造了更多慢请求。

修改方式

我们没有把接口超时从 5 秒改成 30 秒,而是做了三件事:

  • 把推荐结果写入独立缓存,TTL 与整页缓存分开。
  • 把接口连接和读取超时限制在可接受范围。
  • 接口失败时返回本地热销商品,不阻塞首页。
try {
    $items = $this->recommendationClient->fetch($customerContext);
    $this->cache->save($items, $cacheKey, 900);
} catch (\Throwable $e) {
    $this->logger->warning('Recommendation service unavailable', [
        'exception_class' => $e::class
    ]);
    $items = $this->fallbackProducts->getItems(8);
}

日志只记录异常类型和关联信息,没有写入客户画像或接口凭据。

这次排查留下的经验

页面慢和缓存未命中可以同时发生,但未命中只是触发条件。真正要优化的是未缓存请求的执行时间。遇到类似问题,先比较不同页面,再缩小到布局和 Block,最后检查 SQL 与外部依赖。这样比一遍遍清缓存更接近根因。